[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.
This commit is contained in:
Thibault Delavallée
2016-08-01 15:05:32 +02:00
parent f3d6a54e36
commit 0f0ca1c133
30 changed files with 70 additions and 93 deletions
+1 -2
View File
@@ -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
+1 -1
View File
@@ -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)
+1 -2
View File
@@ -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
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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:
+1 -1
View File
@@ -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}))
+3 -4
View File
@@ -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'})
+1 -1
View File
@@ -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'])
+4 -6
View File
@@ -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'])
+1 -2
View File
@@ -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:
@@ -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 = {
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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
+4 -15
View File
@@ -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:
+7 -4
View File
@@ -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.")
+6 -7
View File
@@ -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,
+2 -2
View File
@@ -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
@@ -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
+2 -2
View File
@@ -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')
+1 -1
View File
@@ -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
+5 -6
View File
@@ -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
+3 -4
View File
@@ -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):
+4 -4
View File
@@ -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 {
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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')
+6 -8
View File
@@ -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',
+1 -1
View File
@@ -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)
+4 -4
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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: