diff --git a/addons/product/product.py b/addons/product/product.py index 2b70e1a3101..e5afb4ef38d 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -156,13 +156,14 @@ class product_uom(osv.osv): 'rounding': 0.01, 'factor': 1, 'uom_type': 'reference', + 'factor': 1.0, } _sql_constraints = [ ('factor_gt_zero', 'CHECK (factor!=0)', 'The conversion ratio for a unit of measure cannot be 0!') ] - def _compute_qty(self, cr, uid, from_uom_id, qty, to_uom_id=False, round=True): + 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]) @@ -170,9 +171,9 @@ class product_uom(osv.osv): 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) + 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, context=None): + def _compute_qty_obj(self, cr, uid, from_unit, qty, to_unit, round=True, rounding_method='UP', context=None): if context is None: context = {} if from_unit.category_id.id != to_unit.category_id.id: @@ -184,7 +185,7 @@ class product_uom(osv.osv): if to_unit: amount = amount * to_unit.factor if round: - amount = ceiling(amount, to_unit.rounding) + 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): diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 254855bb089..b124d348b87 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1242,7 +1242,7 @@ class stock_picking(osv.osv): need_rereserve = True elif ops.product_id.id: #Check moves with same product - qty_to_assign = uom_obj._compute_qty_obj(cr, uid, ops.product_uom_id, ops.product_qty, ops.product_id.uom_id, round=False, context=context) + qty_to_assign = uom_obj._compute_qty_obj(cr, uid, ops.product_uom_id, ops.product_qty, ops.product_id.uom_id, context=context) for move_dict in prod2move_ids.get(ops.product_id.id, []): move = move_dict['move'] for quant in move.reserved_quant_ids: @@ -1298,7 +1298,8 @@ class stock_picking(osv.osv): if op.product_id and op.product_uom_id and op.product_uom_id.id != product.uom_id.id: 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 - qty = uom_obj._compute_qty_obj(cr, uid, product.uom_id, remaining_qty, op.product_uom_id) + #HALF-UP rounding as only rounding errors will be because of propagation of error from default UoM + qty = uom_obj._compute_qty_obj(cr, uid, product.uom_id, remaining_qty, op.product_uom_id, rounding_method='HALF-UP') picking = op.picking_id res = { 'picking_id': picking.id, @@ -1601,7 +1602,7 @@ class stock_move(osv.osv): for record in move.linked_move_operation_ids: qty -= record.qty # Keeping in product default UoM - res[move.id] = qty + res[move.id] = float_round(qty, precision_rounding=move.product_id.uom_id.rounding) return res def _get_lot_ids(self, cr, uid, ids, field_name, args, context=None): @@ -2461,7 +2462,8 @@ class stock_move(osv.osv): uom_obj = self.pool.get('product.uom') context = context or {} - uom_qty = uom_obj._compute_qty_obj(cr, uid, move.product_id.uom_id, qty, move.product_uom) + #HALF-UP rounding as only rounding errors will be because of propagation of error from default UoM + uom_qty = uom_obj._compute_qty_obj(cr, uid, move.product_id.uom_id, qty, move.product_uom, rounding_method='HALF-UP', context=context) uos_qty = uom_qty * move.product_uos_qty / move.product_uom_qty defaults = { @@ -3838,7 +3840,7 @@ class stock_pack_operation(osv.osv): qty = uom_obj._compute_qty_obj(cr, uid, ops.product_uom_id, ops.product_qty, ops.product_id.uom_id, context=context) for record in ops.linked_move_operation_ids: qty -= record.qty - res[ops.id] = qty + res[ops.id] = float_round(qty, precision_rounding=ops.product_id.uom_id.rounding) return res def product_id_change(self, cr, uid, ids, product_id, product_uom_id, product_qty, context=None):