From 6d7daac2a898df1c92f04130a15d4ecb7c500bce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Fri, 30 May 2025 18:10:27 +0200 Subject: [PATCH] Round only the tax amount of the line when rounding per line If we round the tax amount already added to the other line, the result may vary depending on the order of the lines. This is because round half even is used so the result may depend on the already summed tax amounts. Closes #14047 (grafted from e1e376f91bc1e111cdef39ddcbbfd92d201ea6c9) --HG-- branch : 7.0 --- modules/account/tax.py | 16 +++++++++----- modules/account/tests/test_module.py | 32 ++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/modules/account/tax.py b/modules/account/tax.py index 5dd420f98f..15a162c2a2 100644 --- a/modules/account/tax.py +++ b/modules/account/tax.py @@ -1307,14 +1307,20 @@ class TaxableMixin(object): if self.currency: taxline['base'] = self.currency.round( taxline['base']) - if taxline not in taxes: - taxes[taxline] = taxline + if taxline not in current_taxes: + current_taxes[taxline] = taxline else: - taxes[taxline]['base'] += taxline['base'] - taxes[taxline]['amount'] += taxline['amount'] - current_taxes[taxline] = taxes[taxline] + current_taxes[taxline]['base'] += taxline['base'] + current_taxes[taxline]['amount'] += ( + taxline['amount']) if tax_rounding == 'line': self._round_taxes(current_taxes) + for key, taxline in current_taxes.items(): + if key not in taxes: + taxes[key] = taxline + else: + taxes[key]['base'] += taxline['base'] + taxes[key]['amount'] += taxline['amount'] if tax_rounding == 'document': self._round_taxes(taxes) for key, taxline in taxes.items(): diff --git a/modules/account/tests/test_module.py b/modules/account/tests/test_module.py index e7cef7d2df..f5f0dea74a 100644 --- a/modules/account/tests/test_module.py +++ b/modules/account/tests/test_module.py @@ -1143,6 +1143,38 @@ class AccountTestCase( self.assertEqual(tax['base'], Decimal('100.00')) self.assertEqual(tax['amount'], Decimal('20.00')) + @with_transaction() + def test_taxable_mixin_line2(self): + "Test TaxableMixin with rounding on line" + pool = Pool() + Tax = pool.get('account.tax') + Configuration = pool.get('account.configuration') + currency = create_currency('cur') + + company = create_company() + with set_company(company): + create_chart(company, tax=True) + tax, = Tax.search([]) + tax.rate = 1 + tax.save() + config = Configuration(1) + config.tax_rounding = 'line' + config.save() + + taxable = self.Taxable( + currency=currency, + taxable_lines=[ + ([tax], Decimal('1.070'), 1, None), + ([tax], Decimal('1.005'), 1, None), + ], + company=company) + + taxes = taxable._get_taxes() + + tax, = taxes + self.assertEqual(tax['base'], Decimal('2.07')) + self.assertEqual(tax['amount'], Decimal('2.07')) + @with_transaction() def test_taxable_mixin_document(self): "Test TaxableMixin with rounding on document"