Merge lp:~lin-yu/purchase-wkfl/add_purchase_price_list into lp:~purchase-core-editors/purchase-wkfl/7.0
- add_purchase_price_list
- Merge into 7.0
Status: | Work in progress |
---|---|
Proposed branch: | lp:~lin-yu/purchase-wkfl/add_purchase_price_list |
Merge into: | lp:~purchase-core-editors/purchase-wkfl/7.0 |
Diff against target: |
518 lines (+488/-0) 5 files modified
purchase_price_list_item/__init__.py (+23/-0) purchase_price_list_item/__openerp__.py (+52/-0) purchase_price_list_item/i18n/purchase_price_list_item.po (+33/-0) purchase_price_list_item/purchase.py (+332/-0) purchase_price_list_item/purchase_view.xml (+48/-0) |
To merge this branch: | bzr merge lp:~lin-yu/purchase-wkfl/add_purchase_price_list |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Pedro Manuel Baeza | Needs Resubmitting | ||
Joël Grand-Guillaume @ camptocamp | code review, no tests | Disapprove | |
Maxime Chambreuil (http://www.savoirfairelinux.com) | code review | Needs Fixing | |
Review via email: mp+180796@code.launchpad.net |
Commit message
Description of the change
[ADD] purchase_
Improve purchase price managment
=======
* In Purchase List Item, the price is fixed based on price_surchage if base is 'fixed on UOP'
* If 'fixed on UOP', if product UOP change, the price list price will be change automtically.
* Add field 'Qty on Hand', and 'Stock Values' for product
* Add field 'Qty on Hand', 'Stock Values', UOP in product list view
Maxime Chambreuil (http://www.savoirfairelinux.com) (max3903) wrote : | # |
Joël Grand-Guillaume @ camptocamp (jgrandguillaume-c2c) wrote : | # |
Hi Lin,
Thanks for this contribs ! Do you really need to override the whole function "price_get_multi" without calling super() ?
This can lead in very unexpected result so for now I marks it as Disapprove for that reason. Other module that may override this method can face trouble due to that...
Thanks for your understanding or explanation if I do missed something !
Regards,
Pedro Manuel Baeza (pedro.baeza) wrote : | # |
This project is now hosted on https:/
Preview Diff
1 | === added directory 'purchase_price_list_item' | |||
2 | === added file 'purchase_price_list_item/__init__.py' | |||
3 | --- purchase_price_list_item/__init__.py 1970-01-01 00:00:00 +0000 | |||
4 | +++ purchase_price_list_item/__init__.py 2013-08-19 07:32:33 +0000 | |||
5 | @@ -0,0 +1,23 @@ | |||
6 | 1 | # -*- coding: utf-8 -*- | ||
7 | 2 | ############################################################################## | ||
8 | 3 | # | ||
9 | 4 | # OpenERP, Open Source Management Solution | ||
10 | 5 | # Copyright (c) 2010-2013 Elico Corp. All Rights Reserved. | ||
11 | 6 | # Author: Jean LELIEVRE <jean.lelievre@elico-corp.com> | ||
12 | 7 | # | ||
13 | 8 | # This program is free software: you can redistribute it and/or modify | ||
14 | 9 | # it under the terms of the GNU Affero General Public License as | ||
15 | 10 | # published by the Free Software Foundation, either version 3 of the | ||
16 | 11 | # License, or (at your option) any later version. | ||
17 | 12 | # | ||
18 | 13 | # This program is distributed in the hope that it will be useful, | ||
19 | 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | 16 | # GNU Affero General Public License for more details. | ||
22 | 17 | # | ||
23 | 18 | # You should have received a copy of the GNU Affero General Public License | ||
24 | 19 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
25 | 20 | # | ||
26 | 21 | ############################################################################## | ||
27 | 22 | |||
28 | 23 | import purchase | ||
29 | 0 | \ No newline at end of file | 24 | \ No newline at end of file |
30 | 1 | 25 | ||
31 | === added file 'purchase_price_list_item/__openerp__.py' | |||
32 | --- purchase_price_list_item/__openerp__.py 1970-01-01 00:00:00 +0000 | |||
33 | +++ purchase_price_list_item/__openerp__.py 2013-08-19 07:32:33 +0000 | |||
34 | @@ -0,0 +1,52 @@ | |||
35 | 1 | # -*- coding: utf-8 -*- | ||
36 | 2 | ############################################################################## | ||
37 | 3 | # | ||
38 | 4 | # OpenERP, Open Source Management Solution | ||
39 | 5 | # Copyright (c) 2010-2013 Elico Corp. All Rights Reserved. | ||
40 | 6 | # Author: Jean LELIEVRE <jean.lelievre@elico-corp.com> | ||
41 | 7 | # Andy LU<andy.lu@elico-corp.com> | ||
42 | 8 | # | ||
43 | 9 | # This program is free software: you can redistribute it and/or modify | ||
44 | 10 | # it under the terms of the GNU Affero General Public License as | ||
45 | 11 | # published by the Free Software Foundation, either version 3 of the | ||
46 | 12 | # License, or (at your option) any later version. | ||
47 | 13 | # | ||
48 | 14 | # This program is distributed in the hope that it will be useful, | ||
49 | 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
50 | 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
51 | 17 | # GNU Affero General Public License for more details. | ||
52 | 18 | # | ||
53 | 19 | # You should have received a copy of the GNU Affero General Public License | ||
54 | 20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
55 | 21 | # | ||
56 | 22 | ############################################################################## | ||
57 | 23 | |||
58 | 24 | { | ||
59 | 25 | 'name': 'Purchase Price List Item', | ||
60 | 26 | 'version': '1.0', | ||
61 | 27 | 'category': 'Purchase', | ||
62 | 28 | 'sequence': 19, | ||
63 | 29 | 'summary': 'Purchase Price List Item', | ||
64 | 30 | 'description': """ | ||
65 | 31 | Improve purchase price managment | ||
66 | 32 | ================================ | ||
67 | 33 | |||
68 | 34 | * In Purchase List Item, the price is fixed based on price_surchage if base is 'fixed on UOP' | ||
69 | 35 | * If 'fixed on UOP', if product UOP change, the price list price will be change automtically. | ||
70 | 36 | * Add field 'Qty on Hand', and 'Stock Values' for product | ||
71 | 37 | * Add field 'Qty on Hand', 'Stock Values', UOP in product list view | ||
72 | 38 | |||
73 | 39 | """, | ||
74 | 40 | 'author': 'Elico Corp', | ||
75 | 41 | 'website': 'http://www.elico-corp.com', | ||
76 | 42 | 'images' : [], | ||
77 | 43 | 'depends': ['purchase'], | ||
78 | 44 | 'data': [ | ||
79 | 45 | 'purchase_view.xml', | ||
80 | 46 | ], | ||
81 | 47 | 'test': [], | ||
82 | 48 | 'demo': [], | ||
83 | 49 | 'installable': True, | ||
84 | 50 | 'auto_install': False, | ||
85 | 51 | 'application': False, | ||
86 | 52 | } | ||
87 | 0 | \ No newline at end of file | 53 | \ No newline at end of file |
88 | 1 | 54 | ||
89 | === added directory 'purchase_price_list_item/i18n' | |||
90 | === added file 'purchase_price_list_item/i18n/purchase_price_list_item.po' | |||
91 | --- purchase_price_list_item/i18n/purchase_price_list_item.po 1970-01-01 00:00:00 +0000 | |||
92 | +++ purchase_price_list_item/i18n/purchase_price_list_item.po 2013-08-19 07:32:33 +0000 | |||
93 | @@ -0,0 +1,33 @@ | |||
94 | 1 | # Translation of OpenERP Server. | ||
95 | 2 | # This file contains the translation of the following modules: | ||
96 | 3 | # * purchase_price_list_item | ||
97 | 4 | # | ||
98 | 5 | msgid "" | ||
99 | 6 | msgstr "" | ||
100 | 7 | "Project-Id-Version: OpenERP Server 7.0\n" | ||
101 | 8 | "Report-Msgid-Bugs-To: \n" | ||
102 | 9 | "POT-Creation-Date: 2013-08-14 09:03+0000\n" | ||
103 | 10 | "PO-Revision-Date: 2013-08-14 09:03+0000\n" | ||
104 | 11 | "Last-Translator: <>\n" | ||
105 | 12 | "Language-Team: \n" | ||
106 | 13 | "MIME-Version: 1.0\n" | ||
107 | 14 | "Content-Type: text/plain; charset=UTF-8\n" | ||
108 | 15 | "Content-Transfer-Encoding: \n" | ||
109 | 16 | "Plural-Forms: \n" | ||
110 | 17 | |||
111 | 18 | #. module: purchase_price_list_item | ||
112 | 19 | #: code:addons/purchase_price_list_item/purchase.py:34 | ||
113 | 20 | #, python-format | ||
114 | 21 | msgid "Fix Price based on UoP" | ||
115 | 22 | msgstr "" | ||
116 | 23 | |||
117 | 24 | #. module: purchase_price_list_item | ||
118 | 25 | #: model:ir.model,name:purchase_price_list_item.model_product_pricelist_item | ||
119 | 26 | msgid "Pricelist item" | ||
120 | 27 | msgstr "" | ||
121 | 28 | |||
122 | 29 | #. module: purchase_price_list_item | ||
123 | 30 | #: field:product.pricelist.item,uom_id:0 | ||
124 | 31 | msgid "UoM for Fix Price" | ||
125 | 32 | msgstr "" | ||
126 | 33 | |||
127 | 0 | 34 | ||
128 | === added file 'purchase_price_list_item/purchase.py' | |||
129 | --- purchase_price_list_item/purchase.py 1970-01-01 00:00:00 +0000 | |||
130 | +++ purchase_price_list_item/purchase.py 2013-08-19 07:32:33 +0000 | |||
131 | @@ -0,0 +1,332 @@ | |||
132 | 1 | # -*- coding: utf-8 -*- | ||
133 | 2 | ############################################################################## | ||
134 | 3 | # | ||
135 | 4 | # OpenERP, Open Source Management Solution | ||
136 | 5 | # Copyright (c) 2010-2013 Elico Corp. All Rights Reserved. | ||
137 | 6 | # Author: Jean LELIEVRE <jean.lelievre@elico-corp.com> | ||
138 | 7 | # | ||
139 | 8 | # This program is free software: you can redistribute it and/or modify | ||
140 | 9 | # it under the terms of the GNU Affero General Public License as | ||
141 | 10 | # published by the Free Software Foundation, either version 3 of the | ||
142 | 11 | # License, or (at your option) any later version. | ||
143 | 12 | # | ||
144 | 13 | # This program is distributed in the hope that it will be useful, | ||
145 | 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
146 | 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
147 | 16 | # GNU Affero General Public License for more details. | ||
148 | 17 | # | ||
149 | 18 | # You should have received a copy of the GNU Affero General Public License | ||
150 | 19 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
151 | 20 | # | ||
152 | 21 | ############################################################################## | ||
153 | 22 | |||
154 | 23 | from osv import osv, fields | ||
155 | 24 | from tools.translate import _ | ||
156 | 25 | |||
157 | 26 | import openerp.addons.decimal_precision as dp | ||
158 | 27 | |||
159 | 28 | import time | ||
160 | 29 | from product._common import rounding | ||
161 | 30 | |||
162 | 31 | |||
163 | 32 | class product_pricelist_item(osv.osv): | ||
164 | 33 | _inherit = "product.pricelist.item" | ||
165 | 34 | |||
166 | 35 | def _price_field_get(self, cr, uid, context=None): | ||
167 | 36 | result = super(product_pricelist_item, self)._price_field_get(cr, uid, context=context) | ||
168 | 37 | |||
169 | 38 | result.append((-3, _('Fix Price based on UoP'))) | ||
170 | 39 | return result | ||
171 | 40 | |||
172 | 41 | _columns = { | ||
173 | 42 | 'base': fields.selection(_price_field_get, 'Based on',required=True, size=-1, help="Base price for computation."), | ||
174 | 43 | 'uom_id': fields.many2one('product.uom','UoM for Fix Price',store=True), | ||
175 | 44 | } | ||
176 | 45 | _defaults = { | ||
177 | 46 | 'price_discount': lambda *a: -1, | ||
178 | 47 | 'base': lambda *a: -3, | ||
179 | 48 | } | ||
180 | 49 | |||
181 | 50 | def product_id_change(self,cr,uid,ids,product_id,context=None): | ||
182 | 51 | if not product_id: | ||
183 | 52 | return{} | ||
184 | 53 | prod = self.pool.get('product.product').browse(cr,uid,product_id,context=context) | ||
185 | 54 | |||
186 | 55 | if prod.default_code: | ||
187 | 56 | return {'value': {'name': prod.default_code,'uom_id': prod.uom_po_id.id}} | ||
188 | 57 | return{} | ||
189 | 58 | |||
190 | 59 | def create(self,cr,uid,vals,context=None): | ||
191 | 60 | if not vals.get('uom_id',False) and vals.get('product_id', False) and vals.get('base',False) == -3: | ||
192 | 61 | prod = self.pool.get('product.product').browse(cr,uid,vals.get('product_id',False),context=context) | ||
193 | 62 | vals['uom_id'] = prod.uom_po_id.id | ||
194 | 63 | |||
195 | 64 | return super(product_pricelist_item,self).create(cr,uid,vals,context=context) | ||
196 | 65 | |||
197 | 66 | def write(self, cr, uid, ids, vals, context=None): | ||
198 | 67 | if type(ids) != type([]): | ||
199 | 68 | ids = [ids] | ||
200 | 69 | if not vals.get('uom_id', False) and ids: | ||
201 | 70 | pl_item_obj = self.pool.get('product.pricelist.item') | ||
202 | 71 | for id in ids: | ||
203 | 72 | item = pl_item_obj.browse(cr, uid, id, context=context) | ||
204 | 73 | if item.base == -3 and item.product_id: | ||
205 | 74 | vals['uom_id'] = item.product_id.uom_po_id.id | ||
206 | 75 | return super(product_pricelist_item, self).write(cr, uid, ids, vals, context=context) | ||
207 | 76 | |||
208 | 77 | product_pricelist_item() | ||
209 | 78 | |||
210 | 79 | |||
211 | 80 | class product_pricelist(osv.osv): | ||
212 | 81 | _inherit = "product.pricelist" | ||
213 | 82 | |||
214 | 83 | #def price_get_multi(self, cr, uid, product_ids, context=None): | ||
215 | 84 | def price_get_multi(self, cr, uid, pricelist_ids, products_by_qty_by_partner, context=None): | ||
216 | 85 | """multi products 'price_get'. | ||
217 | 86 | @param pricelist_ids: | ||
218 | 87 | @param products_by_qty: | ||
219 | 88 | @param partner: | ||
220 | 89 | @param context: { | ||
221 | 90 | 'date': Date of the pricelist (%Y-%m-%d),} | ||
222 | 91 | @return: a dict of dict with product_id as key and a dict 'price by pricelist' as value | ||
223 | 92 | """ | ||
224 | 93 | |||
225 | 94 | def _create_parent_category_list(id, lst): | ||
226 | 95 | if not id: | ||
227 | 96 | return [] | ||
228 | 97 | parent = product_category_tree.get(id) | ||
229 | 98 | if parent: | ||
230 | 99 | lst.append(parent) | ||
231 | 100 | return _create_parent_category_list(parent, lst) | ||
232 | 101 | else: | ||
233 | 102 | return lst | ||
234 | 103 | # _create_parent_category_list | ||
235 | 104 | |||
236 | 105 | if context is None: | ||
237 | 106 | context = {} | ||
238 | 107 | |||
239 | 108 | date = time.strftime('%Y-%m-%d') | ||
240 | 109 | if 'date' in context: | ||
241 | 110 | date = context['date'] | ||
242 | 111 | |||
243 | 112 | currency_obj = self.pool.get('res.currency') | ||
244 | 113 | product_obj = self.pool.get('product.product') | ||
245 | 114 | product_category_obj = self.pool.get('product.category') | ||
246 | 115 | product_uom_obj = self.pool.get('product.uom') | ||
247 | 116 | supplierinfo_obj = self.pool.get('product.supplierinfo') | ||
248 | 117 | price_type_obj = self.pool.get('product.price.type') | ||
249 | 118 | |||
250 | 119 | # product.pricelist.version: | ||
251 | 120 | if not pricelist_ids: | ||
252 | 121 | pricelist_ids = self.pool.get('product.pricelist').search(cr, uid, [], context=context) | ||
253 | 122 | |||
254 | 123 | pricelist_version_ids = self.pool.get('product.pricelist.version').search(cr, uid, [ | ||
255 | 124 | ('pricelist_id', 'in', pricelist_ids), | ||
256 | 125 | '|', | ||
257 | 126 | ('date_start', '=', False), | ||
258 | 127 | ('date_start', '<=', date), | ||
259 | 128 | '|', | ||
260 | 129 | ('date_end', '=', False), | ||
261 | 130 | ('date_end', '>=', date), | ||
262 | 131 | ]) | ||
263 | 132 | if len(pricelist_ids) != len(pricelist_version_ids): | ||
264 | 133 | raise osv.except_osv(_('Warning!'), _("At least one pricelist has no active version !\nPlease create or activate one.")) | ||
265 | 134 | |||
266 | 135 | # product.product: | ||
267 | 136 | product_ids = [i[0] for i in products_by_qty_by_partner] | ||
268 | 137 | #products = dict([(item['id'], item) for item in product_obj.read(cr, uid, product_ids, ['categ_id', 'product_tmpl_id', 'uos_id', 'uom_id'])]) | ||
269 | 138 | products = product_obj.browse(cr, uid, product_ids, context=context) | ||
270 | 139 | products_dict = dict([(item.id, item) for item in products]) | ||
271 | 140 | |||
272 | 141 | # product.category: | ||
273 | 142 | product_category_ids = product_category_obj.search(cr, uid, []) | ||
274 | 143 | product_categories = product_category_obj.read(cr, uid, product_category_ids, ['parent_id']) | ||
275 | 144 | product_category_tree = dict([(item['id'], item['parent_id'][0]) for item in product_categories if item['parent_id']]) | ||
276 | 145 | |||
277 | 146 | results = {} | ||
278 | 147 | for product_id, qty, partner in products_by_qty_by_partner: | ||
279 | 148 | for pricelist_id in pricelist_ids: | ||
280 | 149 | price = False | ||
281 | 150 | |||
282 | 151 | tmpl_id = products_dict[product_id].product_tmpl_id and products_dict[product_id].product_tmpl_id.id or False | ||
283 | 152 | |||
284 | 153 | categ_id = products_dict[product_id].categ_id and products_dict[product_id].categ_id.id or False | ||
285 | 154 | categ_ids = _create_parent_category_list(categ_id, [categ_id]) | ||
286 | 155 | if categ_ids: | ||
287 | 156 | categ_where = '(categ_id IN (' + ','.join(map(str, categ_ids)) + '))' | ||
288 | 157 | else: | ||
289 | 158 | categ_where = '(categ_id IS NULL)' | ||
290 | 159 | |||
291 | 160 | if partner: | ||
292 | 161 | partner_where = 'base <> -2 OR %s IN (SELECT name FROM product_supplierinfo WHERE product_id = %s) ' | ||
293 | 162 | partner_args = (partner, tmpl_id) | ||
294 | 163 | else: | ||
295 | 164 | partner_where = 'base <> -2 ' | ||
296 | 165 | partner_args = () | ||
297 | 166 | |||
298 | 167 | #And | ||
299 | 168 | pl = self.pool.get('product.pricelist').browse(cr, uid, pricelist_id, context=context) | ||
300 | 169 | if pl.type == "purchase": | ||
301 | 170 | product = products_dict[product_id] | ||
302 | 171 | if 'uom' in context: | ||
303 | 172 | uom = product.uom_po_id | ||
304 | 173 | if uom.id != context['uom']: | ||
305 | 174 | qty = qty * product.uom_po_id.factor / product.uom_id.factor | ||
306 | 175 | |||
307 | 176 | cr.execute( | ||
308 | 177 | 'SELECT i.*, pl.currency_id ' | ||
309 | 178 | 'FROM product_pricelist_item AS i, ' | ||
310 | 179 | 'product_pricelist_version AS v, product_pricelist AS pl ' | ||
311 | 180 | 'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) ' | ||
312 | 181 | 'AND (product_id IS NULL OR product_id = %s) ' | ||
313 | 182 | 'AND (' + categ_where + ' OR (categ_id IS NULL)) ' | ||
314 | 183 | 'AND (' + partner_where + ') ' | ||
315 | 184 | 'AND price_version_id = %s ' | ||
316 | 185 | 'AND (min_quantity IS NULL OR min_quantity <= %s) ' | ||
317 | 186 | 'AND i.price_version_id = v.id AND v.pricelist_id = pl.id ' | ||
318 | 187 | 'ORDER BY sequence', | ||
319 | 188 | (tmpl_id, product_id) + partner_args + (pricelist_version_ids[0], qty)) | ||
320 | 189 | res1 = cr.dictfetchall() | ||
321 | 190 | uom_price_already_computed = False | ||
322 | 191 | for res in res1: | ||
323 | 192 | if res: | ||
324 | 193 | if res['base'] == -1: | ||
325 | 194 | if not res['base_pricelist_id']: | ||
326 | 195 | price = 0.0 | ||
327 | 196 | else: | ||
328 | 197 | price_tmp = self.price_get(cr, uid, | ||
329 | 198 | [res['base_pricelist_id']], product_id, | ||
330 | 199 | qty, context=context)[res['base_pricelist_id']] | ||
331 | 200 | ptype_src = self.browse(cr, uid, res['base_pricelist_id']).currency_id.id | ||
332 | 201 | uom_price_already_computed = True | ||
333 | 202 | price = currency_obj.compute(cr, uid, ptype_src, res['currency_id'], price_tmp, round=False) | ||
334 | 203 | elif res['base'] == -2: | ||
335 | 204 | # this section could be improved by moving the queries outside the loop: | ||
336 | 205 | where = [] | ||
337 | 206 | if partner: | ||
338 | 207 | where = [('name', '=', partner) ] | ||
339 | 208 | sinfo = supplierinfo_obj.search(cr, uid, | ||
340 | 209 | [('product_id', '=', tmpl_id)] + where) | ||
341 | 210 | price = 0.0 | ||
342 | 211 | if sinfo: | ||
343 | 212 | qty_in_product_uom = qty | ||
344 | 213 | product_default_uom = product_obj.read(cr, uid, [product_id], ['uom_id'])[0]['uom_id'][0] | ||
345 | 214 | supplier = supplierinfo_obj.browse(cr, uid, sinfo, context=context)[0] | ||
346 | 215 | seller_uom = supplier.product_uom and supplier.product_uom.id or False | ||
347 | 216 | if seller_uom and product_default_uom and product_default_uom != seller_uom: | ||
348 | 217 | uom_price_already_computed = True | ||
349 | 218 | qty_in_product_uom = product_uom_obj._compute_qty(cr, uid, product_default_uom, qty, to_uom_id=seller_uom) | ||
350 | 219 | cr.execute('SELECT * ' \ | ||
351 | 220 | 'FROM pricelist_partnerinfo ' \ | ||
352 | 221 | 'WHERE suppinfo_id IN %s' \ | ||
353 | 222 | 'AND min_quantity <= %s ' \ | ||
354 | 223 | 'ORDER BY min_quantity DESC LIMIT 1', (tuple(sinfo), qty_in_product_uom,)) | ||
355 | 224 | res2 = cr.dictfetchone() | ||
356 | 225 | if res2: | ||
357 | 226 | price = res2['price'] | ||
358 | 227 | #Add by Andy | ||
359 | 228 | elif res['base'] == -3: | ||
360 | 229 | price = False | ||
361 | 230 | else: | ||
362 | 231 | price_type = price_type_obj.browse(cr, uid, int(res['base'])) | ||
363 | 232 | uom_price_already_computed = True | ||
364 | 233 | price = currency_obj.compute(cr, uid, | ||
365 | 234 | price_type.currency_id.id, res['currency_id'], | ||
366 | 235 | product_obj.price_get(cr, uid, [product_id], | ||
367 | 236 | price_type.field, context=context)[product_id], round=False, context=context) | ||
368 | 237 | |||
369 | 238 | if price is not False: | ||
370 | 239 | price_limit = price | ||
371 | 240 | price = price * (1.0 + (res['price_discount'] or 0.0)) | ||
372 | 241 | price = rounding(price, res['price_round']) #TOFIX: rounding with tools.float_rouding | ||
373 | 242 | price += (res['price_surcharge'] or 0.0) | ||
374 | 243 | if res['price_min_margin']: | ||
375 | 244 | price = max(price, price_limit + res['price_min_margin']) | ||
376 | 245 | if res['price_max_margin']: | ||
377 | 246 | price = min(price, price_limit + res['price_max_margin']) | ||
378 | 247 | break | ||
379 | 248 | #Add by Andy | ||
380 | 249 | else: | ||
381 | 250 | if res['base'] == -3: | ||
382 | 251 | price = res['price_surcharge'] or 0.0 | ||
383 | 252 | product = products_dict[product_id] | ||
384 | 253 | if 'uom' in context: | ||
385 | 254 | uom = product.uom_po_id | ||
386 | 255 | if uom.id != context['uom']: | ||
387 | 256 | price = product_uom_obj._compute_price(cr, uid, uom.id, price, context['uom']) | ||
388 | 257 | uom_price_already_computed = True | ||
389 | 258 | #Todo: # Use company currency? | ||
390 | 259 | if 'currency_id' in context: | ||
391 | 260 | price = currency_obj.compute(cr, uid, 1, | ||
392 | 261 | context['currency_id'], price, context=context) | ||
393 | 262 | if price: | ||
394 | 263 | break | ||
395 | 264 | else: | ||
396 | 265 | # False means no valid line found ! But we may not raise an | ||
397 | 266 | # exception here because it breaks the search | ||
398 | 267 | price = False | ||
399 | 268 | |||
400 | 269 | if price: | ||
401 | 270 | results['item_id'] = res['id'] | ||
402 | 271 | if 'uom' in context and not uom_price_already_computed: | ||
403 | 272 | product = products_dict[product_id] | ||
404 | 273 | uom = product.uos_id or product.uom_id | ||
405 | 274 | price = product_uom_obj._compute_price(cr, uid, uom.id, price, context['uom']) | ||
406 | 275 | |||
407 | 276 | if results.get(product_id): | ||
408 | 277 | results[product_id][pricelist_id] = price | ||
409 | 278 | else: | ||
410 | 279 | results[product_id] = {pricelist_id: price} | ||
411 | 280 | |||
412 | 281 | return results | ||
413 | 282 | |||
414 | 283 | product_pricelist() | ||
415 | 284 | |||
416 | 285 | |||
417 | 286 | |||
418 | 287 | class product_product(osv.osv): | ||
419 | 288 | _name = "product.product" | ||
420 | 289 | _inherit = "product.product" | ||
421 | 290 | |||
422 | 291 | def _qty_uop(self, cr, uid, ids, name, arg, context=None): | ||
423 | 292 | res = {} | ||
424 | 293 | |||
425 | 294 | uom_obj = self.pool.get('product.uom') | ||
426 | 295 | for id in ids: | ||
427 | 296 | res.setdefault(id, 0.0) | ||
428 | 297 | for product in self.browse(cr, uid, ids): | ||
429 | 298 | res[product.id] = uom_obj._compute_qty(cr, uid, product.uom_id.id, product.qty_available, product.uom_po_id.id) | ||
430 | 299 | return res | ||
431 | 300 | |||
432 | 301 | def _amount_uom(self, cr, uid, ids, name, arg, context=None): | ||
433 | 302 | res = {} | ||
434 | 303 | |||
435 | 304 | for id in ids: | ||
436 | 305 | res.setdefault(id, 0.0) | ||
437 | 306 | for product in self.browse(cr, uid, ids): | ||
438 | 307 | res[product.id] = product.qty_available * product.standard_price | ||
439 | 308 | return res | ||
440 | 309 | |||
441 | 310 | _columns = { | ||
442 | 311 | #'price_uop': fields.float('Purchase Price(UoP)', digits_compute=dp.get_precision('Product Price')), | ||
443 | 312 | 'qty_uop': fields.function(_qty_uop, type='float', string='Qty on Hand (UoP)', digits_compute=dp.get_precision('Product Unit of Measure')), | ||
444 | 313 | 'amount_uom': fields.function(_amount_uom, type='float', string='Stock Values', digits_compute=dp.get_precision('Account')), | ||
445 | 314 | } | ||
446 | 315 | |||
447 | 316 | def write(self, cr, uid, ids, vals, context=None): | ||
448 | 317 | if type(ids) != type([]): | ||
449 | 318 | ids = [ids] | ||
450 | 319 | if vals.get('uom_po_id', False) and ids: | ||
451 | 320 | uom_obj = self.pool.get('product.uom') | ||
452 | 321 | uop = uom_obj.browse(cr, uid, vals.get('uom_po_id', False), context=context) | ||
453 | 322 | pl_item_obj = self.pool.get('product.pricelist.item') | ||
454 | 323 | pl_ids = pl_item_obj.search(cr, uid, [('product_id', '=', ids[0]), ('base', '=', -3)], context=context) | ||
455 | 324 | for item in pl_item_obj.browse(cr, uid, pl_ids, context=context): | ||
456 | 325 | if item.uom_id and uop.id == item.uom_id.id: | ||
457 | 326 | continue | ||
458 | 327 | new_price = item.price_surcharge / uop.factor * item.uom_id.factor | ||
459 | 328 | pl_item_obj.write(cr, uid, [item.id], {'uom_id': vals.get('uom_po_id', False), 'price_surcharge': new_price}) | ||
460 | 329 | |||
461 | 330 | return super(product_product, self).write(cr, uid, ids, vals, context=context) | ||
462 | 331 | |||
463 | 332 | product_product() | ||
464 | 0 | \ No newline at end of file | 333 | \ No newline at end of file |
465 | 1 | 334 | ||
466 | === added file 'purchase_price_list_item/purchase_view.xml' | |||
467 | --- purchase_price_list_item/purchase_view.xml 1970-01-01 00:00:00 +0000 | |||
468 | +++ purchase_price_list_item/purchase_view.xml 2013-08-19 07:32:33 +0000 | |||
469 | @@ -0,0 +1,48 @@ | |||
470 | 1 | <?xml version="1.0" encoding="UTF-8" ?> | ||
471 | 2 | <openerp> | ||
472 | 3 | <data> | ||
473 | 4 | |||
474 | 5 | <record id="product_pricelist_item_list_view_FC" model="ir.ui.view"> | ||
475 | 6 | <field name="name">product.pricelist.item.list.FC</field> | ||
476 | 7 | <field name="model">product.pricelist.item</field> | ||
477 | 8 | <field name="inherit_id" ref="product.product_pricelist_item_tree_view" /> | ||
478 | 9 | <field name="arch" type="xml"> | ||
479 | 10 | <xpath expr="//field[@name='categ_id']" position="before"> | ||
480 | 11 | <field name="price_surcharge" attrs="{'invisible':[('base', '!=', -3)]}"/> | ||
481 | 12 | <field name="uom_id" attrs="{'invisible':[('base', '!=', -3)],'readonly':1}"/> | ||
482 | 13 | </xpath> | ||
483 | 14 | </field> | ||
484 | 15 | </record> | ||
485 | 16 | |||
486 | 17 | <record id="product_pricelist_item_form_view_FC" model="ir.ui.view"> | ||
487 | 18 | <field name="name">product.pricelist.item.form.FC</field> | ||
488 | 19 | <field name="model">product.pricelist.item</field> | ||
489 | 20 | <field name="type">form</field> | ||
490 | 21 | <field name="inherit_id" ref="product.product_pricelist_item_form_view" /> | ||
491 | 22 | <field name="arch" type="xml"> | ||
492 | 23 | <xpath expr="//field[@name='product_id']" position="replace"> | ||
493 | 24 | <field name="product_id" on_change="product_id_change(product_id)" attrs="{'required': [('base','=', -3)]}"/> | ||
494 | 25 | <field name="uom_id" attrs="{'invisible':[('base', '!=', -3)],'readonly':1}"/> | ||
495 | 26 | </xpath> | ||
496 | 27 | </field> | ||
497 | 28 | </record> | ||
498 | 29 | |||
499 | 30 | <record id="product_product_tree_view_uop" model="ir.ui.view"> | ||
500 | 31 | <field name="name">product.product.tree.uop</field> | ||
501 | 32 | <field name="model">product.product</field> | ||
502 | 33 | <field name="type">form</field> | ||
503 | 34 | <field name="inherit_id" ref="product.product_product_tree_view" /> | ||
504 | 35 | <field name="arch" type="xml"> | ||
505 | 36 | <xpath expr="//field[@name='state']" position="before"> | ||
506 | 37 | <field name="qty_uop"/> | ||
507 | 38 | <field name="uom_po_id"/> | ||
508 | 39 | </xpath> | ||
509 | 40 | <xpath expr="//field[@name='standard_price']" position="replace"> | ||
510 | 41 | <field name="standard_price"/> | ||
511 | 42 | <field name="amount_uom"/> | ||
512 | 43 | </xpath> | ||
513 | 44 | </field> | ||
514 | 45 | </record> | ||
515 | 46 | |||
516 | 47 | </data> | ||
517 | 48 | </openerp> | ||
518 | 0 | \ No newline at end of file | 49 | \ No newline at end of file |
Thanks for your contribution Yu.
l163: please use orm.Model instead of osv.osv. Update the import accordingly.
l208, 463: no need to instantiate
l417: 2 lines are enough to comply with PEP8. Run flake8 to check for PEP8 issues