[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.
This commit is contained in:
Thibault Delavallée
2016-08-01 15:05:32 +02:00
parent 429cd5970e
commit f3d6a54e36
13 changed files with 31 additions and 32 deletions
+1 -2
View File
@@ -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')
+5 -3
View File
@@ -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
+3 -3
View File
@@ -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':
+2 -2
View File
@@ -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
+4 -5
View File
@@ -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
+2 -1
View File
@@ -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,
+3 -4
View File
@@ -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
@@ -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
+1 -1
View File
@@ -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']
+2 -2
View File
@@ -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
@@ -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
+1 -1
View File
@@ -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)
+5 -5
View File
@@ -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)]}