From 0f0ca1c1337ae03b28150d3ff3e411e9be685854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 14 Jul 2016 17:36:00 +0200 Subject: [PATCH] [REF] product_uom, *: clean quantity computation methods product_uom._compute_quantity is an ensure one multi method taking a browse record as second paramter. It replaces _compute_qty and _compute_qty_obj to have a single and standard computation method. --- addons/delivery/models/delivery_carrier.py | 3 +-- addons/delivery/models/sale_order.py | 2 +- addons/delivery/models/stock_picking.py | 3 +-- addons/hr_holidays/models/hr_holidays.py | 2 +- addons/l10n_be_intrastat/wizard/xml_decl.py | 2 +- addons/mrp/models/mrp_bom.py | 2 +- addons/mrp/models/mrp_production.py | 7 +++---- addons/mrp/models/mrp_unbuild.py | 2 +- addons/mrp/models/stock_move.py | 10 ++++------ addons/mrp/wizard/stock_move_consume.py | 3 +-- addons/mrp_byproduct/models/mrp_production.py | 3 +-- addons/product/models/product.py | 2 +- addons/product/models/product_pricelist.py | 4 ++-- addons/product/models/product_uom.py | 19 ++++--------------- addons/product/tests/test_uom.py | 11 +++++++---- addons/purchase/purchase.py | 13 ++++++------- addons/purchase_mrp/models/purchase_mrp.py | 4 ++-- .../models/purchase_requisition.py | 7 ++----- addons/sale/sale.py | 4 ++-- addons/sale/sale_analytic.py | 2 +- addons/sale_mrp/sale_mrp.py | 11 +++++------ addons/sale_stock/models/account_invoice.py | 7 +++---- addons/sale_stock/models/sale_order.py | 8 ++++---- addons/sale_timesheet/models/sale_service.py | 2 +- addons/stock/models/stock_inventory.py | 2 +- addons/stock/models/stock_move.py | 14 ++++++-------- addons/stock/models/stock_pack_operation.py | 2 +- addons/stock/models/stock_picking.py | 8 ++++---- addons/stock/models/stock_warehouse.py | 2 +- addons/stock/wizard/stock_picking_return.py | 2 +- 30 files changed, 70 insertions(+), 93 deletions(-) diff --git a/addons/delivery/models/delivery_carrier.py b/addons/delivery/models/delivery_carrier.py index 9ea3f393c82..eb0fdf7a507 100644 --- a/addons/delivery/models/delivery_carrier.py +++ b/addons/delivery/models/delivery_carrier.py @@ -264,7 +264,6 @@ class DeliveryCarrier(models.Model): self.ensure_one() total = weight = volume = quantity = 0 total_delivery = 0.0 - ProductUom = self.env['product.uom'] for line in order.order_line: if line.state == 'cancel': continue @@ -272,7 +271,7 @@ class DeliveryCarrier(models.Model): total_delivery += line.price_total if not line.product_id or line.is_delivery: continue - qty = ProductUom._compute_qty(line.product_uom.id, line.product_uom_qty, line.product_id.uom_id.id) + qty = line.product_uom._compute_quantity(line.product_uom_qty, line.product_id.uom_id) weight += (line.product_id.weight or 0.0) * qty volume += (line.product_id.volume or 0.0) * qty quantity += qty diff --git a/addons/delivery/models/sale_order.py b/addons/delivery/models/sale_order.py index 0e57f0d933e..e9478696592 100644 --- a/addons/delivery/models/sale_order.py +++ b/addons/delivery/models/sale_order.py @@ -110,4 +110,4 @@ class SaleOrderLine(models.Model): for line in self: if not line.product_id or not line.product_uom or not line.product_uom_qty: return 0.0 - line.product_qty = self.env['product.uom']._compute_qty_obj(line.product_uom, line.product_uom_qty, line.product_id.uom_id) + line.product_qty = line.product_uom._compute_quantity(line.product_uom_qty, line.product_id.uom_id) diff --git a/addons/delivery/models/stock_picking.py b/addons/delivery/models/stock_picking.py index 84b819faa25..5f10135fd83 100644 --- a/addons/delivery/models/stock_picking.py +++ b/addons/delivery/models/stock_picking.py @@ -68,10 +68,9 @@ class StockPicking(models.Model): @api.depends('pack_operation_ids') def _compute_bulk_weight(self): weight = 0.0 - uom_obj = self.env['product.uom'] for packop in self.pack_operation_ids: if packop.product_id and not packop.result_package_id: - weight += uom_obj._compute_qty_obj(packop.product_uom_id , packop.product_qty, packop.product_id.uom_id) * packop.product_id.weight + weight += packop.product_uom_id._compute_quantity(packop.product_qty, packop.product_id.uom_id) * packop.product_id.weight self.weight_bulk = weight @api.one diff --git a/addons/hr_holidays/models/hr_holidays.py b/addons/hr_holidays/models/hr_holidays.py index c44fd367e1f..ea207c3cc8b 100644 --- a/addons/hr_holidays/models/hr_holidays.py +++ b/addons/hr_holidays/models/hr_holidays.py @@ -284,7 +284,7 @@ class Holidays(models.Model): uom_hour = resource.calendar_id.uom_id uom_day = self.env.ref('product.product_uom_day') if uom_hour and uom_day: - return self.env['product.uom']._compute_qty_obj(uom_hour, hours, uom_day) + return uom_hour._compute_quantity(hours, uom_day) time_delta = to_dt - from_dt return math.ceil(time_delta.days + float(time_delta.seconds) / 86400) diff --git a/addons/l10n_be_intrastat/wizard/xml_decl.py b/addons/l10n_be_intrastat/wizard/xml_decl.py index ae8bff402e1..50b457361eb 100644 --- a/addons/l10n_be_intrastat/wizard/xml_decl.py +++ b/addons/l10n_be_intrastat/wizard/xml_decl.py @@ -248,7 +248,7 @@ class XmlDeclaration(models.TransientModel): else: amount = 0 weight = (inv_line.product_id.weight or 0.0) * \ - self.env['product.uom']._compute_qty(inv_line.uom_id.id, inv_line.quantity, inv_line.product_id.uom_id.id) + inv_line.uom_id._compute_quantity(inv_line.quantity, inv_line.product_id.uom_id) if not inv_line.product_id.uom_id.category_id: supply_units = inv_line.quantity else: diff --git a/addons/mrp/models/mrp_bom.py b/addons/mrp/models/mrp_bom.py index b99707f844b..4b8b80608e5 100644 --- a/addons/mrp/models/mrp_bom.py +++ b/addons/mrp/models/mrp_bom.py @@ -123,7 +123,7 @@ class MrpBom(models.Model): bom = self._bom_find(product=current_line.product_id, picking_type=picking_type or self.picking_type_id, company_id=self.company_id.id) if bom.type == 'phantom': - converted_line_quantity = self.env['product.uom']._compute_qty_obj(current_line.product_uom_id, line_quantity, bom.product_uom_id) + converted_line_quantity = current_line.product_uom_id._compute_quantity(line_quantity, bom.product_uom_id) bom_lines = [(line, current_line.product_id, line_quantity) for line in bom.bom_line_ids] + bom_lines templates_done |= current_line.product_id.product_tmpl_id boms_done.append((bom, {'qty': converted_line_quantity, 'product': current_product, 'original_qty': quantity})) diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index ed2611c2871..7b074b6641b 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -262,7 +262,7 @@ class MrpProduction(models.Model): def _generate_moves(self): for production in self: production._generate_finished_moves() - factor = self.env['product.uom']._compute_qty(production.product_uom_id.id, production.product_qty, production.bom_id.product_uom_id.id) + factor = production.product_uom_id._compute_quantity(production.product_qty, production.bom_id.product_uom_id) boms, lines = production.bom_id.explode(production.product_id, factor, picking_type=production.bom_id.picking_type_id) production._generate_raw_moves(lines) # Check for all draft moves whether they are mto or not @@ -306,7 +306,7 @@ class MrpProduction(models.Model): source_location = self.bom_id.routing_id.location_id else: source_location = self.location_src_id - original_quantity = self.env['product.uom']._compute_qty(self.product_uom_id.id, self.product_qty, self.bom_id.product_uom_id.id) + original_quantity = self.product_uom_id._compute_quantity(self.product_qty, self.bom_id.product_uom_id) data = { 'name': self.name, @@ -369,9 +369,8 @@ class MrpProduction(models.Model): def button_plan(self): """ Create work orders. And probably do stuff, like things. """ orders_to_plan = self.filtered(lambda order: order.routing_id and order.state == 'confirmed') - UoM = self.env['product.uom'] for order in orders_to_plan: - quantity = UoM._compute_qty_obj(order.product_uom_id, order.product_qty, order.bom_id.product_uom_id) + quantity = order.product_uom_id._compute_quantity(order.product_qty, order.bom_id.product_uom_id) boms, lines = order.bom_id.explode(order.product_id, quantity, picking_type=order.bom_id.picking_type_id) order._generate_workorders(boms) orders_to_plan.write({'state': 'planned'}) diff --git a/addons/mrp/models/mrp_unbuild.py b/addons/mrp/models/mrp_unbuild.py index 97081786ba1..b5d1c44495a 100644 --- a/addons/mrp/models/mrp_unbuild.py +++ b/addons/mrp/models/mrp_unbuild.py @@ -153,7 +153,7 @@ class MrpUnbuild(models.Model): def _generate_produce_moves(self): moves = self.env['stock.move'] for unbuild in self: - factor = self.env['product.uom']._compute_qty(unbuild.product_uom_id.id, unbuild.product_qty, unbuild.bom_id.product_uom_id.id) + factor = unbuild.product_uom_id._compute_quantity(unbuild.product_qty, unbuild.bom_id.product_uom_id) boms, lines = unbuild.bom_id.explode(unbuild.product_id, factor / unbuild.bom_id.product_qty, picking_type=unbuild.bom_id.picking_type_id) for line, line_data in lines: moves += unbuild._generate_move_from_bom_line(line, line_data['qty']) diff --git a/addons/mrp/models/stock_move.py b/addons/mrp/models/stock_move.py index a6f0b08f091..e4509368a27 100644 --- a/addons/mrp/models/stock_move.py +++ b/addons/mrp/models/stock_move.py @@ -129,7 +129,6 @@ class StockMove(models.Model): @api.multi def create_lots(self): lots = self.env['stock.move.lots'] - uom_obj = self.env['product.uom'] for move in self: unlink_move_lots = move.move_lot_ids.filtered(lambda x : (x.quantity_done == 0) and not x.workorder_id) unlink_move_lots.unlink() @@ -140,7 +139,7 @@ class StockMove(models.Model): old_move_lot.setdefault(key, []).append(movelot) for quant in move.reserved_quant_ids: key = (quant.lot_id.id or False) - quantity = uom_obj._compute_qty(move.product_id.uom_id.id, quant.qty, move.product_uom.id) + quantity = move.product_id.uom_id._compute_quantity(quant.qty, move.product_uom) if group_new_quant.get(key): group_new_quant[key] += quantity else: @@ -170,7 +169,6 @@ class StockMove(models.Model): moves = self._filter_closed_moves() quant_obj = self.env['stock.quant'] moves_todo = self.env['stock.move'] - uom_obj = self.env['product.uom'] for move in moves: rounding = move.product_uom.rounding if float_compare(move.quantity_done, 0.0, precision_rounding=rounding) <= 0: @@ -186,7 +184,7 @@ class StockMove(models.Model): for move in moves_todo: if float_compare(move.quantity_done, move.product_uom_qty, precision_rounding=rounding): # Need to do some kind of conversion here - qty_split = uom_obj._compute_qty(move.product_uom.id, move.product_uom_qty - move.quantity_done, move.product_id.uom_id.id) + qty_split = move.product_uom._compute_quantity(move.product_uom_qty - move.quantity_done, move.product_id.uom_id) new_move = move.split(qty_split) self.browse(new_move).quantity_done = 0.0 main_domain = [('qty', '>', 0)] @@ -200,7 +198,7 @@ class StockMove(models.Model): else: for movelot in move.move_lot_ids: if float_compare(movelot.quantity_done, 0, precision_rounding=rounding) > 0: - qty = uom_obj._compute_qty(move.product_uom.id, movelot.quantity_done, move.product_id.uom_id.id) + qty = move.product_uom._compute_quantity(movelot.quantity_done, move.product_id.uom_id) quants = quant_obj.quants_get_preferred_domain(qty, move, lot_id=movelot.lot_id.id, domain=main_domain, preferred_domain_list=preferred_domain_list) self.env['stock.quant'].quants_move(quants, move, move.location_dest_id, lot_id = movelot.lot_id.id) move.quants_unreserve() @@ -273,7 +271,7 @@ class StockMove(models.Model): return self phantom_moves = self.env['stock.move'] processed_moves = self.env['stock.move'] - factor = self.env['product.uom']._compute_qty(self.product_uom.id, self.product_uom_qty, bom.product_uom_id.id) / bom.product_qty + factor = self.product_uom._compute_quantity(self.product_uom_qty, bom.product_uom_id) / bom.product_qty boms, lines = bom.sudo().explode(self.product_id, factor, picking_type=bom.picking_type_id) for bom_line, line_data in lines: phantom_moves += self._generate_move_phantom(bom_line, line_data['qty']) diff --git a/addons/mrp/wizard/stock_move_consume.py b/addons/mrp/wizard/stock_move_consume.py index e69b74ece45..26e3471c735 100644 --- a/addons/mrp/wizard/stock_move_consume.py +++ b/addons/mrp/wizard/stock_move_consume.py @@ -42,13 +42,12 @@ class StockMoveConsume(models.TransientModel): @api.multi def do_move_consume(self): - UoM = self.env['product.uom'] Production = self.env['mrp.production'] move = self.env['stock.move'].browse(self._context['active_id']) precision = self.env['decimal.precision'].precision_get('Product Unit of Measure') for wizard in self: - qty = UoM._compute_qty(wizard.product_uom.id, wizard.product_qty, wizard.product_id.uom_id.id) + qty = wizard.product_uom._compute_quantity(wizard.product_qty, wizard.product_id.uom_id) remaining_qty = move.product_qty - qty # check for product quantity is less than previously planned if float_compare(remaining_qty, 0, precision_digits=precision) >= 0: diff --git a/addons/mrp_byproduct/models/mrp_production.py b/addons/mrp_byproduct/models/mrp_production.py index 2355b67a60f..142775818af 100644 --- a/addons/mrp_byproduct/models/mrp_production.py +++ b/addons/mrp_byproduct/models/mrp_production.py @@ -17,11 +17,10 @@ class Production(models.Model): # TDE FIXME: was action_confirm ?? -> refactored Move = self.env['stock.move'] res = super(Production, self)._generate_moves() - UoM = self.env['product.uom'] for production in self.filtered(lambda production: production.bom_id): source = production.product_id.property_stock_production.id for sub_product in production.bom_id.sub_products: - product_uom_factor = UoM._compute_qty_obj(production.product_uom_id, production.product_qty, production.bom_id.product_uom_id) + product_uom_factor = production.product_uom_id._compute_quantity(production.product_qty, production.bom_id.product_uom_id) qty1 = sub_product.product_qty qty1 *= product_uom_factor / production.bom_id.product_qty data = { diff --git a/addons/product/models/product.py b/addons/product/models/product.py index 5f24309edb2..61299c41873 100644 --- a/addons/product/models/product.py +++ b/addons/product/models/product.py @@ -280,7 +280,7 @@ class product_product(osv.osv): # Set quantity in UoM of seller quantity_uom_seller = quantity if quantity_uom_seller and uom_id and uom_id != seller.product_uom: - quantity_uom_seller = uom_id._compute_qty_obj(uom_id, quantity_uom_seller, seller.product_uom) + quantity_uom_seller = uom_id._compute_quantity(quantity_uom_seller, seller.product_uom) if seller.date_start and seller.date_start > date: continue diff --git a/addons/product/models/product_pricelist.py b/addons/product/models/product_pricelist.py index a055f953c17..43cc0bebc92 100644 --- a/addons/product/models/product_pricelist.py +++ b/addons/product/models/product_pricelist.py @@ -177,8 +177,8 @@ class product_pricelist(osv.osv): qty_in_product_uom = qty if qty_uom_id != product.uom_id.id: try: - qty_in_product_uom = product_uom_obj._compute_qty( - cr, uid, context['uom'], qty, product.uom_id.id) + qty_in_product_uom = product_uom_obj._compute_quantity( + cr, uid, [context['uom']], qty, product.uom_id) except UserError: # Ignored - incompatible UoM in context, use default product UoM pass diff --git a/addons/product/models/product_uom.py b/addons/product/models/product_uom.py index 1a59f18d2de..60649337288 100644 --- a/addons/product/models/product_uom.py +++ b/addons/product/models/product_uom.py @@ -101,26 +101,15 @@ class product_uom(osv.osv): ('factor_gt_zero', 'CHECK (factor!=0)', 'The conversion ratio for a unit of measure cannot be 0!') ] - @api.cr_uid - def _compute_qty(self, cr, uid, from_uom_id, qty, to_uom_id=False, round=True, rounding_method='UP'): - if not from_uom_id or not qty or not to_uom_id: - return qty - uoms = self.browse(cr, uid, [from_uom_id, to_uom_id]) - if uoms[0].id == from_uom_id: - from_unit, to_unit = uoms[0], uoms[-1] - else: - from_unit, to_unit = uoms[-1], uoms[0] - return self._compute_qty_obj(cr, uid, from_unit, qty, to_unit, round=round, rounding_method=rounding_method) - - def _compute_qty_obj(self, cr, uid, from_unit, qty, to_unit, round=True, rounding_method='UP', context=None): - if context is None: - context = {} + def _compute_quantity(self, cr, uid, ids, qty, to_unit, round=True, rounding_method='UP', context=None): + context = context if context is not None else {} + from_unit = self.browse(cr, uid, ids[0], context=context) if from_unit.category_id.id != to_unit.category_id.id: if context.get('raise-exception', True): raise UserError(_('Conversion from Product UoM %s to Default UoM %s is not possible as they both belong to different Category!.') % (from_unit.name,to_unit.name)) else: return qty - amount = qty/from_unit.factor + amount = qty / from_unit.factor if to_unit: amount = amount * to_unit.factor if round: diff --git a/addons/product/tests/test_uom.py b/addons/product/tests/test_uom.py index d6618a7eb7b..b58b4cc0f3f 100644 --- a/addons/product/tests/test_uom.py +++ b/addons/product/tests/test_uom.py @@ -13,12 +13,14 @@ class TestUom(TransactionCase): cr, uid = self.cr, self.uid 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] + kg = self.registry['product.uom'].browse(cr, uid, [kg_id]) 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] + unit = self.registry['product.uom'].browse(cr, uid, [unit_id]) 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) + qty = self.uom._compute_quantity(cr, uid, [gram_id], 1020000, tonne) self.assertEquals(qty, 1.02, "Converted quantity does not correspond.") price = self.uom._compute_price(cr, uid, [gram_id], 2, tonne) @@ -29,13 +31,13 @@ class TestUom(TransactionCase): # and the Unit rounding will round that up to 13. # This is a partial regression test for rev. 311c77bb, which is further improved # by rev. fa2f7b86. - qty = self.uom._compute_qty(cr, uid, dozen_id, 1, unit_id) + qty = self.uom._compute_quantity(cr, uid, [dozen_id], 1, unit) self.assertEquals(qty, 12.0, "Converted quantity does not correspond.") # Regression test for side-effect of commit 311c77bb - converting 1234 Grams # into Kilograms should work even if grams are rounded to 1. self.uom.write(cr, uid, gram_id, {'rounding': 1}) - qty = self.uom._compute_qty(cr, uid, gram_id, 1234, kg_id) + qty = self.uom._compute_quantity(cr, uid, [gram_id], 1234, kg) self.assertEquals(qty, 1.234, "Converted quantity does not correspond.") def test_20_rounding(self): @@ -50,6 +52,7 @@ class TestUom(TransactionCase): 'rounding': 1.0, 'category_id': categ_unit_id }) + score = self.uom.browse(cr, uid, score_id) - qty = self.uom._compute_qty(cr, uid, unit_id, 2, score_id) + qty = self.uom._compute_quantity(cr, uid, [unit_id], 2, score) self.assertEquals(qty, 1, "Converted quantity should be rounded up.") diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index d8bc846170e..05db716bf5f 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -502,12 +502,11 @@ class PurchaseOrderLine(models.Model): qty = 0.0 for inv_line in line.invoice_lines: if inv_line.invoice_id.state not in ['cancel']: - qty += inv_line.uom_id._compute_qty_obj(inv_line.uom_id, inv_line.quantity, line.product_uom) + qty += inv_line.uom_id._compute_quantity(inv_line.quantity, line.product_uom) line.qty_invoiced = qty @api.depends('order_id.state', 'move_ids.state') def _compute_qty_received(self): - productuom = self.env['product.uom'] for line in self: if line.order_id.state not in ['purchase', 'done']: line.qty_received = 0.0 @@ -519,7 +518,7 @@ class PurchaseOrderLine(models.Model): for move in line.move_ids: if move.state == 'done': if move.product_uom != line.product_uom: - total += productuom._compute_qty_obj(move.product_uom, move.product_uom_qty, line.product_uom) + total += move.product_uom._compute_quantity(move.product_uom_qty, line.product_uom) else: total += move.product_uom_qty line.qty_received = total @@ -601,7 +600,7 @@ class PurchaseOrderLine(models.Model): # Fullfill all related procurements with this po line diff_quantity = line.product_qty for procurement in line.procurement_ids: - procurement_qty = procurement.product_uom._compute_qty_obj(procurement.product_uom, procurement.product_qty, line.product_uom) + procurement_qty = procurement.product_uom._compute_quantity(procurement.product_qty, line.product_uom) tmp = template.copy() tmp.update({ 'product_uom_qty': min(procurement_qty, diff_quantity), @@ -767,7 +766,7 @@ class ProcurementOrder(models.Model): others_procs = procurement.purchase_line_id.procurement_ids.filtered(lambda r: r != procurement) for other_proc in others_procs: if other_proc.state not in ['cancel', 'draft']: - product_qty += other_proc.product_uom._compute_qty_obj(other_proc.product_uom, other_proc.product_qty, procurement.purchase_line_id.product_uom) + product_qty += other_proc.product_uom._compute_quantity(other_proc.product_qty, procurement.purchase_line_id.product_uom) precision = self.env['decimal.precision'].precision_get('Product Unit of Measure') if not float_is_zero(product_qty, precision_digits=precision): @@ -823,7 +822,7 @@ class ProcurementOrder(models.Model): def _prepare_purchase_order_line(self, po, supplier): self.ensure_one() - procurement_uom_po_qty = self.env['product.uom']._compute_qty_obj(self.product_uom, self.product_qty, self.product_id.uom_po_id) + procurement_uom_po_qty = self.product_uom._compute_quantity(self.product_qty, self.product_id.uom_po_id) seller = self.product_id._select_seller( partner_id=supplier.name, quantity=procurement_uom_po_qty, @@ -943,7 +942,7 @@ class ProcurementOrder(models.Model): po_line = False for line in po.order_line: if line.product_id == procurement.product_id and line.product_uom == procurement.product_id.uom_po_id: - procurement_uom_po_qty = self.env['product.uom']._compute_qty_obj(procurement.product_uom, procurement.product_qty, procurement.product_id.uom_po_id) + procurement_uom_po_qty = procurement.product_uom._compute_quantity(procurement.product_qty, procurement.product_id.uom_po_id) seller = procurement.product_id._select_seller( partner_id=partner, quantity=line.product_qty + procurement_uom_po_qty, diff --git a/addons/purchase_mrp/models/purchase_mrp.py b/addons/purchase_mrp/models/purchase_mrp.py index 99ff9aaa3eb..2bdf19c2006 100644 --- a/addons/purchase_mrp/models/purchase_mrp.py +++ b/addons/purchase_mrp/models/purchase_mrp.py @@ -27,12 +27,12 @@ class PurchaseOrderLine(models.Model): bom_delivered = {} if bom: bom_delivered[bom.id] = False - product_uom_qty_bom = self.env['product.uom']._compute_qty_obj(self.product_uom, self.product_qty, bom.product_uom_id) + product_uom_qty_bom = self.product_uom._compute_quantity(self.product_qty, bom.product_uom_id) boms, lines = bom.explode(self.product_id, product_uom_qty_bom) for bom_line, data in lines: qty = 0.0 for move in self.move_ids.filtered(lambda x: x.state == 'done' and x.product_id == bom_line.product_id): - qty += self.env['product.uom']._compute_qty(move.product_uom.id, move.product_uom_qty, bom_line.product_uom_id.id) + qty += move.product_uom._compute_quantity(move.product_uom_qty, bom_line.product_uom_id) if float_compare(qty, data['qty'], precision_digits=precision) < 0: bom_delivered[bom.id] = False break diff --git a/addons/purchase_requisition/models/purchase_requisition.py b/addons/purchase_requisition/models/purchase_requisition.py index 7b56f9e7893..0560a4ef3b7 100644 --- a/addons/purchase_requisition/models/purchase_requisition.py +++ b/addons/purchase_requisition/models/purchase_requisition.py @@ -118,13 +118,12 @@ class PurchaseRequisitionLine(models.Model): @api.multi @api.depends('requisition_id.purchase_ids.state') def _compute_ordered_qty(self): - ProductUOM = self.env['product.uom'] for line in self: total = 0.0 for po in line.requisition_id.purchase_ids.filtered(lambda purchase_order: purchase_order.state in ['purchase', 'done']): for po_line in po.order_line.filtered(lambda order_line: order_line.product_id == line.product_id): if po_line.product_uom != line.product_uom_id: - total += ProductUOM._compute_qty_obj(po_line.product_uom, po_line.product_qty, line.product_uom_id) + total += po_line.product_uom._compute_quantity(po_line.product_qty, line.product_uom_id) else: total += po_line.product_qty line.qty_ordered = total @@ -199,9 +198,7 @@ class PurchaseOrder(models.Model): product_qty = 0 price_unit = line.price_unit elif line.product_uom_id != line.product_id.uom_po_id: - ProductUOM = self.env['product.uom'] - product_qty = ProductUOM._compute_qty_obj( - line.product_uom_id, line.product_qty, line.product_id.uom_po_id) + product_qty = line.product_uom_id._compute_quantity(line.product_qty, line.product_id.uom_po_id) price_unit = line.product_uom_id._compute_price(line.price_unit, line.product_id.uom_po_id) else: product_qty = line.product_qty diff --git a/addons/sale/sale.py b/addons/sale/sale.py index d1947fd95b7..dd7637db549 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -615,9 +615,9 @@ class SaleOrderLine(models.Model): for invoice_line in line.invoice_lines: if invoice_line.invoice_id.state != 'cancel': if invoice_line.invoice_id.type == 'out_invoice': - qty_invoiced += self.env['product.uom']._compute_qty_obj(invoice_line.uom_id, invoice_line.quantity, line.product_uom) + qty_invoiced += invoice_line.uom_id._compute_quantity(invoice_line.quantity, line.product_uom) elif invoice_line.invoice_id.type == 'out_refund': - qty_invoiced -= self.env['product.uom']._compute_qty_obj(invoice_line.uom_id, invoice_line.quantity, line.product_uom) + qty_invoiced -= invoice_line.uom_id._compute_quantity(invoice_line.quantity, line.product_uom) line.qty_invoiced = qty_invoiced @api.depends('price_unit', 'discount') diff --git a/addons/sale/sale_analytic.py b/addons/sale/sale_analytic.py index 9efa41efb18..64e62a6a87a 100644 --- a/addons/sale/sale_analytic.py +++ b/addons/sale/sale_analytic.py @@ -25,7 +25,7 @@ class SaleOrderLine(models.Model): lines.setdefault(line, 0.0) uom = self.env['product.uom'].browse(d['product_uom_id'][0]) if line.product_uom.category_id == uom.category_id: - qty = self.env['product.uom']._compute_qty_obj(uom, d['unit_amount'], line.product_uom) + qty = uom._compute_quantity(d['unit_amount'], line.product_uom) else: qty = d['unit_amount'] lines[line] += qty diff --git a/addons/sale_mrp/sale_mrp.py b/addons/sale_mrp/sale_mrp.py index 527ef81fa0f..1b734ed35d2 100644 --- a/addons/sale_mrp/sale_mrp.py +++ b/addons/sale_mrp/sale_mrp.py @@ -38,13 +38,13 @@ class SaleOrderLine(models.Model): bom = self.env['mrp.bom']._bom_find(product=self.product_id) if bom and bom.type == 'phantom': bom_delivered[bom.id] = False - product_uom_qty_bom = self.env['product.uom']._compute_qty_obj(self.product_uom, self.product_uom_qty, bom.product_uom_id) + product_uom_qty_bom = self.product_uom._compute_quantity(self.product_uom_qty, bom.product_uom_id) boms, lines = bom.explode(self.product_id, product_uom_qty_bom) for bom_line, data in lines: qty = 0.0 for move in self.procurement_ids.mapped('move_ids'): if move.state == 'done' and move.product_id.id == bom_line.product_id.id: - qty += self.env['product.uom']._compute_qty(move.product_uom.id, move.product_uom_qty, bom_line.product_uom_id.id) + qty += move.product_uom._compute_quantity(move.product_uom_qty, bom_line.product_uom_id) if float_compare(qty, data['qty'], precision_digits=precision) < 0: bom_delivered[bom.id] = False break @@ -65,12 +65,11 @@ class AccountInvoiceLine(models.Model): price_unit = super(AccountInvoiceLine, self)._get_anglo_saxon_price_unit() # in case of anglo saxon with a product configured as invoiced based on delivery, with perpetual # valuation and real price costing method, we must find the real price for the cost of good sold - uom_obj = self.env['product.uom'] if self.product_id.invoice_policy == "delivery": for s_line in self.sale_line_ids: # qtys already invoiced - qty_done = sum([uom_obj._compute_qty_obj(x.uom_id, x.quantity, x.product_id.uom_id) for x in s_line.invoice_lines if x.invoice_id.state in ('open', 'paid')]) - quantity = uom_obj._compute_qty_obj(self.uom_id, self.quantity, self.product_id.uom_id) + qty_done = sum([x.uom_id._compute_quantity(x.quantity, x.product_id.uom_id) for x in s_line.invoice_lines if x.invoice_id.state in ('open', 'paid')]) + quantity = self.uom_id._compute_quantity(self.quantity, self.product_id.uom_id) # Put moves in fixed order by date executed moves = self.env['stock.move'] for procurement in s_line.procurement_ids: @@ -90,5 +89,5 @@ class AccountInvoiceLine(models.Model): prod_quantity = factor * quantity average_price_unit += self._compute_average_price(prod_qty_done, prod_quantity, prod_moves) price_unit = average_price_unit or price_unit - price_unit = uom_obj._compute_qty_obj(self.uom_id, price_unit, self.product_id.uom_id, round=False) + price_unit = self.uom_id._compute_quantity(price_unit, self.product_id.uom_id, round=False) return price_unit diff --git a/addons/sale_stock/models/account_invoice.py b/addons/sale_stock/models/account_invoice.py index 4bd9efe8021..19991767a1f 100644 --- a/addons/sale_stock/models/account_invoice.py +++ b/addons/sale_stock/models/account_invoice.py @@ -19,12 +19,11 @@ class AccountInvoiceLine(models.Model): price_unit = super(AccountInvoiceLine,self)._get_anglo_saxon_price_unit() # in case of anglo saxon with a product configured as invoiced based on delivery, with perpetual # valuation and real price costing method, we must find the real price for the cost of good sold - uom_obj = self.env['product.uom'] if self.product_id.invoice_policy == "delivery": for s_line in self.sale_line_ids: # qtys already invoiced - qty_done = sum([uom_obj._compute_qty_obj(x.uom_id, x.quantity, x.product_id.uom_id) for x in s_line.invoice_lines if x.invoice_id.state in ('open', 'paid')]) - quantity = uom_obj._compute_qty_obj(self.uom_id, self.quantity, self.product_id.uom_id) + qty_done = sum([x.uom_id._compute_quantity(x.quantity, x.product_id.uom_id) for x in s_line.invoice_lines if x.invoice_id.state in ('open', 'paid')]) + quantity = self.uom_id._compute_quantity(self.quantity, self.product_id.uom_id) # Put moves in fixed order by date executed moves = self.env['stock.move'] for procurement in s_line.procurement_ids: @@ -35,7 +34,7 @@ class AccountInvoiceLine(models.Model): # on the moves we encounter. average_price_unit = self._compute_average_price(qty_done, quantity, moves) price_unit = average_price_unit or price_unit - price_unit = uom_obj._compute_qty_obj(self.uom_id, price_unit, self.product_id.uom_id, round=False) + price_unit = self.uom_id._compute_quantity(price_unit, self.product_id.uom_id, round=False) return price_unit def _compute_average_price(self, qty_done, quantity, moves): diff --git a/addons/sale_stock/models/sale_order.py b/addons/sale_stock/models/sale_order.py index 2ae16e8809f..f4c59a48f10 100644 --- a/addons/sale_stock/models/sale_order.py +++ b/addons/sale_stock/models/sale_order.py @@ -137,7 +137,7 @@ class SaleOrderLine(models.Model): return {} if self.product_id.type == 'product': precision = self.env['decimal.precision'].precision_get('Product Unit of Measure') - product_qty = self.env['product.uom']._compute_qty_obj(self.product_uom, self.product_uom_qty, self.product_id.uom_id) + product_qty = self.product_uom._compute_quantity(self.product_uom_qty, self.product_id.uom_id) if float_compare(self.product_id.virtual_available, product_qty, precision_digits=precision) == -1: is_available = self._check_routing() if not is_available: @@ -183,9 +183,9 @@ class SaleOrderLine(models.Model): qty = 0.0 for move in self.procurement_ids.mapped('move_ids').filtered(lambda r: r.state == 'done' and not r.scrapped): if move.location_dest_id.usage == "customer": - qty += self.env['product.uom']._compute_qty_obj(move.product_uom, move.product_uom_qty, self.product_uom) + qty += move.product_uom._compute_quantity(move.product_uom_qty, self.product_uom) elif move.location_dest_id.usage == "internal" and move.to_refund_so: - qty -= self.env['product.uom']._compute_qty_obj(move.product_uom, move.product_uom_qty, self.product_uom) + qty -= move.product_uom._compute_quantity(move.product_uom_qty, self.product_uom) return qty @api.multi @@ -193,7 +193,7 @@ class SaleOrderLine(models.Model): default_uom = self.product_id.uom_id pack = self.product_packaging qty = self.product_uom_qty - q = self.env['product.uom']._compute_qty_obj(default_uom, pack.qty, self.product_uom) + q = default_uom._compute_quantity(pack.qty, self.product_uom) if qty and q and (qty % q): newqty = qty - (qty % q) + q return { diff --git a/addons/sale_timesheet/models/sale_service.py b/addons/sale_timesheet/models/sale_service.py index a60ed3a8167..0bd0b1b00c2 100644 --- a/addons/sale_timesheet/models/sale_service.py +++ b/addons/sale_timesheet/models/sale_service.py @@ -37,7 +37,7 @@ class procurement_order(osv.osv): product_uom = self.pool.get('product.uom') company_time_uom_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.project_time_mode_id if procurement.product_uom.id != company_time_uom_id.id and procurement.product_uom.category_id.id == company_time_uom_id.category_id.id: - planned_hours = product_uom._compute_qty(cr, uid, procurement.product_uom.id, procurement.product_qty, company_time_uom_id.id) + planned_hours = product_uom._compute_quantity(cr, uid, [procurement.product_uom.id], procurement.product_qty, company_time_uom_id) else: planned_hours = procurement.product_qty return planned_hours diff --git a/addons/stock/models/stock_inventory.py b/addons/stock/models/stock_inventory.py index 422a8838ef1..5105a0ce55f 100644 --- a/addons/stock/models/stock_inventory.py +++ b/addons/stock/models/stock_inventory.py @@ -318,7 +318,7 @@ class InventoryLine(models.Model): return theoretical_qty = sum([x.qty for x in self._get_quants()]) if theoretical_qty and self.product_uom_id and self.product_id.uom_id != self.product_uom_id: - theoretical_qty = self.env["product.uom"]._compute_qty_obj(self.product_id.uom_id, theoretical_qty, self.product_uom_id) + theoretical_qty = self.product_id.uom_id._compute_quantity(theoretical_qty, self.product_uom_id) self.theoretical_qty = theoretical_qty @api.onchange('product_id', 'product_uom_id') diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py index 0265a333d18..9722e98635d 100644 --- a/addons/stock/models/stock_move.py +++ b/addons/stock/models/stock_move.py @@ -156,7 +156,7 @@ class StockMove(models.Model): @api.depends('product_id', 'product_uom', 'product_uom_qty') def _compute_product_qty(self): if self.product_uom: - self.product_qty = self.env['product.uom']._compute_qty_obj(self.product_uom, self.product_uom_qty, self.product_id.uom_id) + self.product_qty = self.product_uom._compute_quantity(self.product_uom_qty, self.product_id.uom_id) def _set_product_qty(self): """ The meaning of product_qty field changed lately and is now a functional field computing the quantity @@ -195,7 +195,6 @@ class StockMove(models.Model): @api.multi def _compute_string_qty_information(self): StockConfig = self.env['stock.config.settings'] - UOM = self.env['product.uom'] precision = self.env['decimal.precision'].precision_get('Product Unit of Measure') void_moves = self.filtered(lambda move: move.state in ('draft', 'done', 'cancel') or move.location_id.usage != 'internal') other_moves = self - void_moves @@ -203,7 +202,7 @@ class StockMove(models.Model): move.string_availability_info = '' # 'not applicable' or 'n/a' could work too for move in other_moves: total_available = min(move.product_qty, move.reserved_availability + move.availability) - total_available = UOM._compute_qty_obj(move.product_id.uom_id, total_available, move.product_uom, round=False) + total_available = move.product_id.uom_id._compute_quantity(total_available, move.product_uom, round=False) total_available = float_round(total_available, precision_digits=precision) info = str(total_available) # look in the settings if we need to display the UoM name or not @@ -213,7 +212,7 @@ class StockMove(models.Model): if move.reserved_availability: if move.reserved_availability != total_available: # some of the available quantity is assigned and some are available but not reserved - reserved_available = UOM._compute_qty_obj(move.product_id.uom_id, move.reserved_availability, move.product_uom, round=False) + reserved_available = move.product_id.uom_id._compute_quantity(move.reserved_availability, move.product_uom, round=False) reserved_available = float_round(reserved_available, precision_digits=precision) info += _(' (%s reserved)') % str(reserved_available) else: @@ -615,7 +614,7 @@ class StockMove(models.Model): lot_qty = {} rounding = ops.product_id.uom_id.rounding for pack_lot in ops.pack_lot_ids: - lot_qty[pack_lot.lot_id.id] = Uom._compute_qty_obj(ops.product_uom_id, pack_lot.qty, ops.product_id.uom_id) + lot_qty[pack_lot.lot_id.id] = ops.product_uom_id._compute_quantity(pack_lot.qty, ops.product_id.uom_id) for record in ops.linked_move_operation_ids: move_qty = record.qty move = record.move_id @@ -791,8 +790,7 @@ class StockMove(models.Model): entire_pack = not operation.product_id and True or False # compute quantities for each lot + check quantities match - lot_quantities = dict((pack_lot.lot_id.id, Uom._compute_qty_obj( - operation.product_uom_id, pack_lot.qty, operation.product_id.uom_id) + lot_quantities = dict((pack_lot.lot_id.id, operation.product_uom_id._compute_quantity(pack_lot.qty, operation.product_id.uom_id) ) for pack_lot in operation.pack_lot_ids) if operation.pack_lot_ids and float_compare(sum(lot_quantities.values()), operation.product_qty, precision_rounding=operation.product_uom_id.rounding) != 0.0: raise UserError(_('You have a difference between the quantity on the operation and the quantities specified for the lots. ')) @@ -918,7 +916,7 @@ class StockMove(models.Model): return self.id # HALF-UP rounding as only rounding errors will be because of propagation of error from default UoM - uom_qty = self.env['product.uom']._compute_qty_obj(self.product_id.uom_id, qty, self.product_uom, rounding_method='HALF-UP') + uom_qty = self.product_id.uom_id._compute_quantity(qty, self.product_uom, rounding_method='HALF-UP') defaults = { 'product_uom_qty': uom_qty, 'procure_method': 'make_to_stock', diff --git a/addons/stock/models/stock_pack_operation.py b/addons/stock/models/stock_pack_operation.py index 94d54c07a2f..7921a5f02eb 100644 --- a/addons/stock/models/stock_pack_operation.py +++ b/addons/stock/models/stock_pack_operation.py @@ -107,7 +107,7 @@ class PackOperation(models.Model): else: qty = self.product_qty if self.product_uom_id: - qty = self.env['product.uom']._compute_qty_obj(self.product_uom_id, self.product_qty, self.product_id.uom_id) + qty = self.product_uom_id._compute_quantity(self.product_qty, self.product_id.uom_id) for record in self.linked_move_operation_ids: qty -= record.qty self.remaining_qty = float_round(qty, precision_rounding=self.product_id.uom_id.rounding) diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py index 10f23a28b79..46e6fa2d231 100644 --- a/addons/stock/models/stock_picking.py +++ b/addons/stock/models/stock_picking.py @@ -557,7 +557,7 @@ class Picking(models.Model): uom = product_to_uom[mapping.product.id] val_dict = { 'picking_id': self.id, - 'product_qty': Uom._compute_qty_obj(mapping.product.uom_id, qty, uom), + 'product_qty': mapping.product.uom_id._compute_quantity(qty, uom), 'product_id': mapping.product.id, 'package_id': mapping.package.id, 'owner_id': mapping.owner.id, @@ -686,7 +686,7 @@ class Picking(models.Model): for ops in operations: lot_qty = {} for packlot in ops.pack_lot_ids: - lot_qty[packlot.lot_id.id] = Uom._compute_qty_obj(ops.product_uom_id, packlot.qty, ops.product_id.uom_id) + lot_qty[packlot.lot_id.id] = ops.product_uom_id._compute_quantity(packlot.qty, ops.product_id.uom_id) # for each operation, create the links with the stock move by seeking on the matching reserved quants, # and deffer the operation if there is some ambiguity on the move to select if ops.package_id and not ops.product_id and (not done_qtys or ops.qty_done): @@ -704,7 +704,7 @@ class Picking(models.Model): elif ops.product_id.id: # Check moves with same product product_qty = ops.qty_done if done_qtys else ops.product_qty - qty_to_assign = Uom._compute_qty_obj(ops.product_uom_id, product_qty, ops.product_id.uom_id) + qty_to_assign = ops.product_uom_id._compute_quantity(product_qty, ops.product_id.uom_id) precision_rounding = ops.product_id.uom_id.rounding for move_dict in prod2move_ids.get(ops.product_id.id, []): move = move_dict['move'] @@ -927,7 +927,7 @@ class Picking(models.Model): if op.product_uom_id.factor > product.uom_id.factor: # If the pack operation's is a smaller unit uom_id = op.product_uom_id.id # HALF-UP rounding as only rounding errors will be because of propagation of error from default UoM - qty = Uom._compute_qty_obj(product.uom_id, remaining_qty, op.product_uom_id, rounding_method='HALF-UP') + qty = product.uom_id._compute_quantity(remaining_qty, op.product_uom_id, rounding_method='HALF-UP') picking = op.picking_id ref = product.default_code name = '[' + ref + ']' + ' ' + product.name if ref else product.name diff --git a/addons/stock/models/stock_warehouse.py b/addons/stock/models/stock_warehouse.py index 51efa09c9ea..99e66c75762 100644 --- a/addons/stock/models/stock_warehouse.py +++ b/addons/stock/models/stock_warehouse.py @@ -801,7 +801,7 @@ class Orderpoint(models.Model): for orderpoint_id, procurement_id, product_uom_id, procurement_qty, template_uom_id, move_qty in self._cr.fetchall(): if procurement_id not in procurements_done: # count procurement once, if multiple move in this orderpoint/procurement combo procurements_done.add(procurement_id) - res[orderpoint_id] += UoM._compute_qty(product_uom_id, procurement_qty, template_uom_id, round=False) + res[orderpoint_id] += UoM.browse(product_uom_id)._compute_quantity(procurement_qty, UoM.browse(template_uom_id), round=False) if move_qty: res[orderpoint_id] -= move_qty return res diff --git a/addons/stock/wizard/stock_picking_return.py b/addons/stock/wizard/stock_picking_return.py index 370006aedc0..4cbfd88a41a 100644 --- a/addons/stock/wizard/stock_picking_return.py +++ b/addons/stock/wizard/stock_picking_return.py @@ -53,7 +53,7 @@ class ReturnPicking(models.TransientModel): ]).filtered( lambda quant: not quant.reservation_id or quant.reservation_id.origin_returned_move_id != move) ) - quantity = self.env['product.uom']._compute_qty_obj(move.product_id.uom_id, quantity, move.product_uom) + quantity = move.product_id.uom_id._compute_quantity(quantity, move.product_uom) product_return_moves.append((0, 0, {'product_id': move.product_id.id, 'quantity': quantity, 'move_id': move.id})) if not product_return_moves: