[FIX] account: nested group of taxes

When a group of tax is nested inside another group of taxes, the tax
amount and base are wrongly calculated. It is also the case when a tax
is applied after a group of taxes.

This is because the recursive call doesn't reuse the previously
calculated tax amounts and base, but always use the same entry amounts.

The fix introduces this behavior, and moreover makes sure to include the
tax group in the base amount only if it should.

Closes #13995
This commit is contained in:
David Arnold
2016-10-27 14:09:18 +02:00
committed by Nicolas Martinelli
parent 147db011c7
commit d3de63ec3f
2 changed files with 45 additions and 3 deletions
+9 -3
View File
@@ -689,7 +689,12 @@ class AccountTax(models.Model):
if not round_tax:
prec += 5
total_excluded = total_included = base = round(price_unit * quantity, prec)
base_values = self.env.context.get('base_values')
if not base_values:
total_excluded = total_included = base = round(price_unit * quantity, prec)
else:
total_excluded, total_included, base = base_values
# Sorting key is mandatory in this case. When no key is provided, sorted() will perform a
# search. However, the search method is overridden in account.tax in order to add a domain
@@ -697,9 +702,10 @@ class AccountTax(models.Model):
# case of group taxes.
for tax in self.sorted(key=lambda r: r.sequence):
if tax.amount_type == 'group':
ret = tax.children_tax_ids.compute_all(price_unit, currency, quantity, product, partner)
children = tax.children_tax_ids.with_context(base_values=(total_excluded, total_included, base))
ret = children.compute_all(price_unit, currency, quantity, product, partner)
total_excluded = ret['total_excluded']
base = ret['base']
base = ret['base'] if tax.include_base_amount else base
total_included = ret['total_included']
tax_amount = total_included - total_excluded
taxes += ret['taxes']
+36
View File
@@ -43,10 +43,46 @@ class TestTax(AccountTestUsers):
(4, self.percent_tax.id, 0)
]
})
self.group_tax_bis = self.tax_model.create({
'name': "Group tax bis",
'amount_type': 'group',
'amount': 0,
'sequence': 6,
'children_tax_ids': [
(4, self.fixed_tax.id, 0),
(4, self.percent_tax.id, 0)
]
})
self.group_of_group_tax = self.tax_model.create({
'name': "Group of group tax",
'amount_type': 'group',
'amount': 0,
'sequence': 7,
'children_tax_ids': [
(4, self.group_tax.id, 0),
(4, self.group_tax_bis.id, 0)
]
})
self.bank_journal = self.env['account.journal'].search([('type', '=', 'bank'), ('company_id', '=', self.account_manager.company_id.id)])[0]
self.bank_account = self.bank_journal.default_debit_account_id
self.expense_account = self.env['account.account'].search([('user_type_id.type', '=', 'payable')], limit=1) #Should be done by onchange later
def test_tax_group_of_group_tax(self):
self.fixed_tax.include_base_amount = True
self.group_tax.include_base_amount = True
self.group_of_group_tax.include_base_amount = True
res = self.group_of_group_tax.compute_all(200.0)
self.assertEquals(res['total_excluded'], 200.0)
# After calculation of first group
# base = 210
# total_included = 231
# Base of the first grouped is passed
# Base after the second group (220) is dropped.
# Base of the group of groups is passed out,
# so we obtain base as after first group
self.assertEquals(res['base'], 210.0)
self.assertEquals(res['total_included'], 263.0)
def test_tax_group(self):
res = self.group_tax.compute_all(200.0)
self.assertEquals(res['total_excluded'], 200.0)