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, }), + ], + })