From 9bd2e29dc81a10ba4227504b243d78c339efdd88 Mon Sep 17 00:00:00 2001 From: "Hamza (hisl)" Date: Thu, 3 Aug 2023 11:42:29 +0000 Subject: [PATCH] [FIX] account : add round to payment term line sum The sum of floating points in not correct when we add a number of lines in payment term. The sum comes up to be 99.999999993 or close to this depending upon the number of lines. 1. Create payment term with 15 lines having percent payment value of 0.166. 2. Keep the last line as calculated by the app. 3. Try to save the payment term. Current Behavior: A validation issue would arise stating the sum should be equal to 100. Expected Behavior: The payment term should be saved. OPW-3450723 closes odoo/odoo#131126 X-original-commit: faebcd0fade95dcdbe1b70449ca46cb7e03f9926 Signed-off-by: Laurent Smet (las) --- addons/account/models/account_payment_term.py | 5 ++- addons/account/tests/test_payment_term.py | 34 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/addons/account/models/account_payment_term.py b/addons/account/models/account_payment_term.py index f870f661720..7b17484e1dc 100644 --- a/addons/account/models/account_payment_term.py +++ b/addons/account/models/account_payment_term.py @@ -3,6 +3,7 @@ from odoo import api, fields, models, _, Command from odoo.exceptions import UserError, ValidationError from odoo.tools import format_date, formatLang, frozendict, date_utils +from odoo.tools.float_utils import float_round from dateutil.relativedelta import relativedelta @@ -137,8 +138,10 @@ class AccountPaymentTerm(models.Model): @api.constrains('line_ids') def _check_lines(self): + round_precision = self.env['decimal.precision'].precision_get('Payment Terms') for terms in self: - if sum(line.value_amount for line in terms.line_ids if line.value == 'percent') != 100: + total_percent = sum(line.value_amount for line in terms.line_ids if line.value == 'percent') + if float_round(total_percent, precision_digits=round_precision) != 100: raise ValidationError(_('The Payment Term must have at least one percent line and the sum of the percent must be 100%.')) if len(terms.line_ids) > 1 and terms.early_discount: raise ValidationError( diff --git a/addons/account/tests/test_payment_term.py b/addons/account/tests/test_payment_term.py index 4589a3d0d47..42033df3678 100644 --- a/addons/account/tests/test_payment_term.py +++ b/addons/account/tests/test_payment_term.py @@ -369,3 +369,37 @@ class TestAccountPaymentTerms(AccountTestInvoicingCommon): [self.env.company.currency_id.round(l['foreign_amount']) for l in computed_term['line_ids']], [700.0, 500.0, 300.0, -500.0], ) + + def test_payment_term_percent_round_calculation(self): + """ + the sum function might not sum the floating numbers properly + if there are a lot of lines with floating numbers + so this test verifies the round function changes + """ + self.env['account.payment.term'].create({ + 'name': "test_payment_term_percent_round_calculation", + 'line_ids': [ + Command.create({'value_amount': 50, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 1.66, 'value': 'percent', 'nb_days': 0, }), + Command.create({'value_amount': 16.8, 'value': 'percent', 'nb_days': 0, }), + ], + })