From f3d6a54e36ae1c8ab110b0da519ed9b521589baa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 14 Jul 2016 16:52:50 +0200 Subject: [PATCH] [REF] product_uom, *: clean price computation method product_uom._compute_price() is now an ensure_one multi methods, taking a browse record as second unit. This helps simplifying and unifying the various calls and price computation methods. --- addons/account/models/account_invoice.py | 3 +-- addons/product/models/product.py | 8 +++++--- addons/product/models/product_pricelist.py | 6 +++--- addons/product/models/product_template.py | 4 ++-- addons/product/models/product_uom.py | 9 ++++----- addons/product/tests/test_uom.py | 3 ++- addons/product_extended/models/product.py | 7 +++---- addons/product_visible_discount/models/sale_order.py | 2 +- addons/purchase/invoice.py | 2 +- addons/purchase/purchase.py | 4 ++-- .../models/purchase_requisition.py | 3 +-- addons/sale_margin/models/sale_order.py | 2 +- addons/website_quote/models/order.py | 10 +++++----- 13 files changed, 31 insertions(+), 32 deletions(-) diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py index 28e5a9d520a..6fe9a217aa6 100644 --- a/addons/account/models/account_invoice.py +++ b/addons/account/models/account_invoice.py @@ -1249,8 +1249,7 @@ class AccountInvoiceLine(models.Model): self.price_unit = self.price_unit * currency.with_context(dict(self._context or {}, date=self.invoice_id.date_invoice)).rate if self.uom_id and self.uom_id.id != product.uom_id.id: - self.price_unit = self.env['product.uom']._compute_price( - product.uom_id.id, self.price_unit, self.uom_id.id) + self.price_unit = product.uom_id._compute_price(self.price_unit, self.uom_id) return {'domain': domain} @api.onchange('account_id') diff --git a/addons/product/models/product.py b/addons/product/models/product.py index fa4556e336b..5f24309edb2 100644 --- a/addons/product/models/product.py +++ b/addons/product/models/product.py @@ -181,13 +181,15 @@ class product_product(osv.osv): def _product_lst_price(self, cr, uid, ids, name, arg, context=None): product_uom_obj = self.pool.get('product.uom') + if 'uom' in context: + to_uom = self.pool['product.uom'].browse(cr, uid, context['uom'], context=context) res = dict.fromkeys(ids, 0.0) for product in self.browse(cr, uid, ids, context=context): if 'uom' in context: uom = product.uom_id res[product.id] = product_uom_obj._compute_price(cr, uid, - uom.id, product.list_price, context['uom']) + [uom.id], product.list_price, to_uom) else: res[product.id] = product.list_price res[product.id] = res[product.id] + product.price_extra @@ -201,7 +203,7 @@ class product_product(osv.osv): if 'uom' in context: uom = product.uom_id value = product_uom_obj._compute_price(cr, uid, - context['uom'], value, uom.id) + [context['uom']], value, uom) value = value - product.price_extra return product.write({'list_price': value}) @@ -518,7 +520,7 @@ class product_product(osv.osv): prices[product.id] += product.price_extra if uom: - prices[product.id] = product.uom_id._compute_price(product.uom_id.id, prices[product.id], uom.id) + prices[product.id] = product.uom_id._compute_price(prices[product.id], uom) # Convert from current user company currency to asked one # This is right cause a field cannot be in more than one currency diff --git a/addons/product/models/product_pricelist.py b/addons/product/models/product_pricelist.py index cf2439f3ed2..a055f953c17 100644 --- a/addons/product/models/product_pricelist.py +++ b/addons/product/models/product_pricelist.py @@ -187,7 +187,7 @@ class product_pricelist(osv.osv): # TDE SURPRISE: product can actually be a template price = product.price_compute('list_price')[product.id] - price_uom_id = qty_uom_id + price_uom = self.pool['product.uom'].browse(cr, uid, [qty_uom_id], context=context) for rule in items: if rule.min_quantity and qty_in_product_uom < rule.min_quantity: continue @@ -222,8 +222,8 @@ class product_pricelist(osv.osv): price = product.price_compute(rule.base)[product.id] convert_to_price_uom = (lambda price: product_uom_obj._compute_price( - cr, uid, product.uom_id.id, - price, price_uom_id)) + cr, uid, [product.uom_id.id], + price, price_uom)) if price is not False: if rule.compute_price == 'fixed': diff --git a/addons/product/models/product_template.py b/addons/product/models/product_template.py index 4bf45d0bbd1..57003af1c93 100644 --- a/addons/product/models/product_template.py +++ b/addons/product/models/product_template.py @@ -60,7 +60,7 @@ class product_template(osv.osv): if 'uom' in context: uom = product.uom_id value = product_uom_obj._compute_price(cr, uid, - context['uom'], value, uom.id) + [context['uom']], value, uom, context=context) return product.write({'list_price': value}) @@ -212,7 +212,7 @@ class product_template(osv.osv): prices[template.id] = template[price_type] or 0.0 if uom: - prices[template.id] = template.uom_id._compute_price(template.uom_id.id, prices[template.id], uom.id) + prices[template.id] = template.uom_id._compute_price(prices[template.id], uom) # Convert from current user company currency to asked one # This is right cause a field cannot be in more than one currency diff --git a/addons/product/models/product_uom.py b/addons/product/models/product_uom.py index d7c07e92510..1a59f18d2de 100644 --- a/addons/product/models/product_uom.py +++ b/addons/product/models/product_uom.py @@ -127,15 +127,14 @@ class product_uom(osv.osv): amount = float_round(amount, precision_rounding=to_unit.rounding, rounding_method=rounding_method) return amount - def _compute_price(self, cr, uid, from_uom_id, price, to_uom_id=False): - if (not from_uom_id or not price or not to_uom_id - or (to_uom_id == from_uom_id)): + def _compute_price(self, cr, uid, ids, price, to_unit, context=None): + from_unit = self.browse(cr, uid, ids[0], context=context) + if not from_unit or not price or not to_unit or from_unit == to_unit: return price - from_unit, to_unit = self.browse(cr, uid, [from_uom_id, to_uom_id]) if from_unit.category_id.id != to_unit.category_id.id: return price amount = price * from_unit.factor - if to_uom_id: + if to_unit: amount = amount / to_unit.factor return amount diff --git a/addons/product/tests/test_uom.py b/addons/product/tests/test_uom.py index e6ac6055137..d6618a7eb7b 100644 --- a/addons/product/tests/test_uom.py +++ b/addons/product/tests/test_uom.py @@ -14,13 +14,14 @@ class TestUom(TransactionCase): gram_id = self.imd.get_object_reference(cr, uid, 'product', 'product_uom_gram')[1] kg_id = self.imd.get_object_reference(cr, uid, 'product', 'product_uom_kgm')[1] tonne_id = self.imd.get_object_reference(cr, uid, 'product', 'product_uom_ton')[1] + tonne = self.registry['product.uom'].browse(cr, uid, [tonne_id]) unit_id = self.imd.get_object_reference(cr, uid, 'product','product_uom_unit')[1] dozen_id = self.imd.get_object_reference(cr, uid, 'product','product_uom_dozen')[1] qty = self.uom._compute_qty(cr, uid, gram_id, 1020000, tonne_id) self.assertEquals(qty, 1.02, "Converted quantity does not correspond.") - price = self.uom._compute_price(cr, uid, gram_id, 2, tonne_id) + price = self.uom._compute_price(cr, uid, [gram_id], 2, tonne) self.assertEquals(price, 2000000.0, "Converted price does not correspond.") # If the conversion factor for Dozens (1/12) is not stored with sufficient precision, diff --git a/addons/product_extended/models/product.py b/addons/product_extended/models/product.py index 0eb830abf87..8156b943350 100644 --- a/addons/product_extended/models/product.py +++ b/addons/product_extended/models/product.py @@ -36,19 +36,18 @@ class ProductProduct(models.Model): def _calc_price(self, bom): price = 0.0 workcenter_cost = 0.0 - uom_obj = self.env['product.uom'] for sbom in bom.bom_line_ids: my_qty = sbom.product_qty if not sbom.attribute_value_ids: # No attribute_value_ids means the bom line is not variant specific - price += uom_obj._compute_price(sbom.product_id.uom_id.id, sbom.product_id.standard_price, sbom.product_uom_id.id) * my_qty + price += sbom.product_id.uom_id._compute_price(sbom.product_id.standard_price, sbom.product_uom_id) * my_qty if bom.routing_id: total_cost = 0.0 for order in bom.routing_id.operation_ids: total_cost += (order.time_cycle_manual/60) * order.workcenter_id.costs_hour workcenter_cost = total_cost / len(bom.routing_id.operation_ids) - price += uom_obj._compute_price(bom.product_uom_id.id, workcenter_cost, bom.product_id.uom_id.id) + price += bom.product_uom_id._compute_price(workcenter_cost, bom.product_id.uom_id) # Convert on product UoM quantities if price > 0: - price = uom_obj._compute_price(bom.product_uom_id.id, price / bom.product_qty, bom.product_id.uom_id.id) + price = bom.product_uom_id._compute_price(price / bom.product_qty, bom.product_id.uom_id) return price diff --git a/addons/product_visible_discount/models/sale_order.py b/addons/product_visible_discount/models/sale_order.py index 3c5e95b0e0d..7b6a0b52c7e 100644 --- a/addons/product_visible_discount/models/sale_order.py +++ b/addons/product_visible_discount/models/sale_order.py @@ -37,7 +37,7 @@ class SaleOrderLine(models.Model): product_uom = self.env.context.get('uom') or product.uom_id.id if uom and uom.id != product_uom: # the unit price is in a different uom - uom_factor = uom._compute_price(uom.id, 1.0, product.uom_id.id) + uom_factor = uom._compute_price(1.0, product.uom_id) else: uom_factor = 1.0 diff --git a/addons/purchase/invoice.py b/addons/purchase/invoice.py index d454625f1ee..6173924f9ba 100644 --- a/addons/purchase/invoice.py +++ b/addons/purchase/invoice.py @@ -123,7 +123,7 @@ class AccountInvoice(models.Model): # calculate and write down the possible price difference between invoice price and product price for line in res: if line.get('invl_id', 0) == i_line.id and reference_account_id == line['account_id']: - valuation_price_unit = self.env['product.uom']._compute_price(i_line.product_id.uom_id.id, i_line.product_id.standard_price, i_line.uom_id.id) + valuation_price_unit = i_line.product_id.uom_id._compute_price(i_line.product_id.standard_price, i_line.uom_id) if i_line.product_id.cost_method != 'standard' and i_line.purchase_line_id: #for average/fifo/lifo costing method, fetch real cost price from incomming moves stock_move_obj = self.env['stock.move'] diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 6261e67ccae..d8bc846170e 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -719,7 +719,7 @@ class PurchaseOrderLine(models.Model): price_unit = seller.currency_id.compute(price_unit, self.order_id.currency_id) if seller and self.product_uom and seller.product_uom != self.product_uom: - price_unit = self.env['product.uom']._compute_price(seller.product_uom.id, price_unit, to_uom_id=self.product_uom.id) + price_unit = seller.product_uom._compute_price(price_unit, self.product_uom) self.price_unit = price_unit @@ -782,7 +782,7 @@ class ProcurementOrder(models.Model): price_unit = seller.currency_id.compute(price_unit, procurement.purchase_line_id.order_id.currency_id) if seller and seller.product_uom != procurement.purchase_line_id.product_uom: - price_unit = self.env['product.uom']._compute_price(seller.product_uom.id, price_unit, to_uom_id=procurement.purchase_line_id.product_uom.id) + price_unit = seller.product_uom._compute_price(price_unit, procurement.purchase_line_id.product_uom) procurement.purchase_line_id.product_qty = product_qty procurement.purchase_line_id.price_unit = price_unit diff --git a/addons/purchase_requisition/models/purchase_requisition.py b/addons/purchase_requisition/models/purchase_requisition.py index fa218f7826e..7b56f9e7893 100644 --- a/addons/purchase_requisition/models/purchase_requisition.py +++ b/addons/purchase_requisition/models/purchase_requisition.py @@ -202,8 +202,7 @@ class PurchaseOrder(models.Model): ProductUOM = self.env['product.uom'] product_qty = ProductUOM._compute_qty_obj( line.product_uom_id, line.product_qty, line.product_id.uom_po_id) - price_unit = ProductUOM._compute_price( - line.product_uom_id.id, line.price_unit, to_uom_id=line.product_id.uom_po_id.id) + price_unit = line.product_uom_id._compute_price(line.price_unit, line.product_id.uom_po_id) else: product_qty = line.product_qty price_unit = line.price_unit diff --git a/addons/sale_margin/models/sale_order.py b/addons/sale_margin/models/sale_order.py index a8e1ed6ef8b..9ec43d4fa0b 100644 --- a/addons/sale_margin/models/sale_order.py +++ b/addons/sale_margin/models/sale_order.py @@ -16,7 +16,7 @@ class SaleOrderLine(models.Model): to_cur = order_id.pricelist_id.currency_id purchase_price = product_id.standard_price if product_uom_id != product_id.uom_id: - purchase_price = self.env['product.uom']._compute_price(product_id.uom_id.id, purchase_price, to_uom_id=product_uom_id.id) + purchase_price = product_id.uom_id._compute_price(purchase_price, product_uom_id) ctx = self.env.context.copy() ctx['date'] = order_id.date_order price = frm_cur.with_context(ctx).compute(purchase_price, to_cur, round=False) diff --git a/addons/website_quote/models/order.py b/addons/website_quote/models/order.py index 3a9d2199666..11d37f2e302 100644 --- a/addons/website_quote/models/order.py +++ b/addons/website_quote/models/order.py @@ -75,7 +75,7 @@ class sale_quote_line(osv.osv): uom_obj = self.pool.get('product.uom') if vals['product_uom_id'] != product_obj.uom_id.id: selected_uom = uom_obj.browse(cr, uid, vals['product_uom_id'], context=context) - new_price = uom_obj._compute_price(cr, uid, product_obj.uom_id.id, vals['price_unit'], vals['product_uom_id']) + new_price = uom_obj._compute_price(cr, uid, [product_obj.uom_id.id], vals['price_unit'], selected_uom) vals['price_unit'] = new_price if not uom_id: domain = {'product_uom_id': [('category_id', '=', product_obj.uom_id.category_id.id)]} @@ -362,7 +362,7 @@ class sale_quote_option(osv.osv): self.price_unit = 0.0 return if self.uom_id.id != self.product_id.uom_id.id: - new_price = self.product_id.uom_id._compute_price(self.product_id.uom_id.id, self.price_unit, self.uom_id.id) + new_price = self.product_id.uom_id._compute_price(self.price_unit, self.uom_id) self.price_unit = new_price def on_change_product_id(self, cr, uid, ids, product, uom_id=None, context=None): @@ -380,8 +380,8 @@ class sale_quote_option(osv.osv): uom_obj = self.pool.get('product.uom') if vals['uom_id'] != product_obj.uom_id.id: selected_uom = uom_obj.browse(cr, uid, vals['uom_id'], context=context) - new_price = uom_obj._compute_price(cr, uid, product_obj.uom_id.id, - vals['price_unit'], vals['uom_id']) + new_price = uom_obj._compute_price(cr, uid, [product_obj.uom_id.id], + vals['price_unit'], selected_uom) vals['price_unit'] = new_price if not uom_id: domain = {'uom_id': [('category_id', '=', product_obj.uom_id.category_id.id)]} @@ -434,7 +434,7 @@ class sale_order_option(osv.osv): uom_obj = self.pool.get('product.uom') if vals['uom_id'] != product_obj.uom_id.id: selected_uom = uom_obj.browse(cr, uid, vals['uom_id'], context=context) - new_price = uom_obj._compute_price(cr, uid, product_obj.uom_id.id, vals['price_unit'], vals['uom_id']) + new_price = uom_obj._compute_price(cr, uid, [product_obj.uom_id.id], vals['price_unit'], selected_uom) vals['price_unit'] = new_price if not uom_id: domain = {'uom_id': [('category_id', '=', product_obj.uom_id.category_id.id)]}