[FIX] sale_stock: package with decimal values

Follow-up of f1e79c74a5c07d6be3154629f6f381ebaf907fb1

The issue still arises with:
8 % 1.6 = 1.5999999999999996

The modulo operator on float doesn't seem reliable for our use case,
therefore we use a combination of `float_round` and `float_compare` to
verify the quantity sold is a multiple of the quantity per package.

The rounding threshold is 0.01, meaning that the warning might not be
raised for some specific configurations. For example, 8.005 units with
a package of 1.6 won't return a warning. Since this is a non-blocking
warning, this should be enough for most cases.

opw-2241985

closes odoo/odoo#49983

X-original-commit: 3d48e2b49023eaf1b1dd0c8cb2b7723e41924a38
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
This commit is contained in:
Nicolas Martinelli
2020-04-22 13:00:06 +00:00
parent 51d36ca373
commit d5ecad2a36
+13 -2
View File
@@ -7,7 +7,7 @@ from datetime import datetime, timedelta
from collections import defaultdict
from odoo import api, fields, models, _
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, float_compare
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, float_compare, float_round
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
@@ -570,7 +570,18 @@ class SaleOrderLine(models.Model):
pack = self.product_packaging
qty = self.product_uom_qty
q = default_uom._compute_quantity(pack.qty, self.product_uom)
if qty and q and round(qty % q, 2):
# We do not use the modulo operator to check if qty is a mltiple of q. Indeed the quantity
# per package might be a float, leading to incorrect results. For example:
# 8 % 1.6 = 1.5999999999999996
# 5.4 % 1.8 = 2.220446049250313e-16
if (
qty
and q
and float_compare(
qty / q, float_round(qty / q, precision_rounding=1.0), precision_rounding=0.001
)
!= 0
):
newqty = qty - (qty % q) + q
return {
'warning': {