From 311c77bb885d815aeb64ac5e89d3665f4c2dd172 Mon Sep 17 00:00:00 2001 From: Cedric Snauwaert Date: Wed, 24 Sep 2014 16:09:28 +0200 Subject: [PATCH] [FIX] product: _compute_qty: first round before ceiling, to avoid pathological cases Fixes problem when we try to sell 12 units of a product and change it to 1 dozen, the algorithm was then trying to recompute the original amount and was getting 12,0000048 as a result which was then passed to the ceiling method, getting 13.0! See also previous commit and issue #1125, PR #1126 --- addons/product/product.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/addons/product/product.py b/addons/product/product.py index 83ab8183f7a..da0ce6f9040 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -29,6 +29,7 @@ from openerp.osv import osv, fields from openerp.tools.translate import _ import openerp.addons.decimal_precision as dp +from openerp.tools.float_utils import float_round def ean_checksum(eancode): """returns the checksum of an ean string of length 13, returns -1 if the string has the wrong length""" @@ -176,7 +177,10 @@ class product_uom(osv.osv): raise osv.except_osv(_('Error!'), _('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 + # First round to the precision of the original unit, so that + # float representation errors do not bias the following ceil() + # e.g. with 1 / (1/12) we could get 12.0000048, ceiling to 13! + amount = float_round(qty/from_unit.factor, precision_rounding=from_unit.rounding) if to_unit: amount = ceiling(amount * to_unit.factor, to_unit.rounding) return amount