[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:
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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']
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)]}
|
||||
|
||||
Reference in New Issue
Block a user