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