From d5ecad2a36002558b25ee33633774e85ecaed668 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Wed, 22 Apr 2020 07:53:28 +0000 Subject: [PATCH] [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) --- addons/sale_stock/models/sale_order.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/addons/sale_stock/models/sale_order.py b/addons/sale_stock/models/sale_order.py index 75607d09e0a..be166972818 100644 --- a/addons/sale_stock/models/sale_order.py +++ b/addons/sale_stock/models/sale_order.py @@ -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': {