[FIX] account: tax rounding error

- Create Tax 0:
  Percentage
  Amount: 0
  Tax Included
  Tax Group 0
- Create Tax 8:
  Percentage
  Amount: 8
  Tax Included
  Tax Group 8
- Create a customer invoice with one line
  Quantity: 8.0
  Price Unit: 15.55
  Taxes: Tax 8, Tax 0 (order is important)

The tax amounts are:
  Tax 8: 9.22
  Tax 0: -0.01

If the taxes are inverted, the tax amounts
  Tax 8: 9.21
  Tax 0: 0.00

The difference is due to the rounding of the 8% tax done differently. In
the second case, the computation of the 8% tax goes through:

https://github.com/odoo/odoo/blob/8c5cd335a57c20ed5faa6b7c7630c296c1f2a5cf/addons/account/models/account.py#L1480

In the first case, the amount is recomputed in:

https://github.com/odoo/odoo/blob/8c5cd335a57c20ed5faa6b7c7630c296c1f2a5cf/addons/account/models/account.py#L1483

The rounding is different in both cases, leading to an inconsistency.

When the tax amount is zero, there is no need to save the amount in
`total_included_checkpoints`.

opw-2306676

closes odoo/odoo#55812

X-original-commit: e2776e188070221ef465a864bd2cb8dcfc971e14
Signed-off-by: Jorge Pinna Puissant (jpp) <jpp@odoo.com>
This commit is contained in:
Nicolas Martinelli
2020-08-12 13:42:20 +00:00
committed by Jorge Pinna Puissant
parent 9039183fbb
commit ebac669b2e
2 changed files with 56 additions and 1 deletions
+6 -1
View File
@@ -492,7 +492,12 @@ class AccountTax(models.Model):
incl_fixed_amount += tax_amount
# Avoid unecessary re-computation
cached_tax_amounts[i] = tax_amount
if store_included_tax_total:
# In case of a zero tax, do not store the base amount since the tax amount will
# be zero anyway. Group and Python taxes have an amount of zero, so do not take
# them into account.
if store_included_tax_total and (
tax.amount or tax.amount_type not in ("percent", "division", "fixed")
):
total_included_checkpoints[i] = base
store_included_tax_total = False
i -= 1
+50
View File
@@ -124,6 +124,17 @@ class TestTaxCommon(AccountTestInvoicingCommon):
],
})
cls.tax_0_percent = cls.env['account.tax'].with_company(cls.company_data['company']).create({
'name': "test_0_percent",
'amount_type': 'percent',
'amount': 0,
})
cls.tax_8_percent = cls.env['account.tax'].with_company(cls.company_data['company']).create({
'name': "test_8_percent",
'amount_type': 'percent',
'amount': 8,
})
cls.tax_12_percent = cls.env['account.tax'].with_company(cls.company_data['company']).create({
'name': "test_12_percent",
'amount_type': 'percent',
@@ -828,6 +839,45 @@ class TestTax(TestTaxCommon):
res1
)
def test_rounding_tax_included_round_per_line_03(self):
''' Test the rounding of a 8% and 0% price included tax in an invoice having 8 * 15.55 as line.
The decimal precision is set to 2.
'''
self.tax_0_percent.company_id.currency_id.rounding = 0.01
self.tax_0_percent.price_include = True
self.tax_8_percent.price_include = True
self.group_tax.children_tax_ids = [(6, 0, self.tax_0_percent.ids)]
self.group_tax_bis.children_tax_ids = [(6, 0, self.tax_8_percent.ids)]
res1 = (self.tax_8_percent | self.tax_0_percent).compute_all(15.55, quantity=8.0)
self._check_compute_all_results(
124.40, # 'total_included'
115.19, # 'total_excluded'
[
# base , amount
# -------------
(115.19, 9.21),
(115.19, 0.00),
# -------------
],
res1
)
res2 = (self.tax_0_percent | self.tax_8_percent).compute_all(15.55, quantity=8.0)
self._check_compute_all_results(
124.40, # 'total_included'
115.19, # 'total_excluded'
[
# base , amount
# -------------
(115.19, 0.00),
(115.19, 9.21),
# -------------
],
res2
)
def test_rounding_tax_included_round_globally_01(self):
''' Test the rounding of a 19% price included tax in an invoice having 27000 and 10920 as lines.
The decimal precision is set to zero.