[FIX] account: 0% tax not in tax report due

Steps to reproduce:

Have a 0% Tax
Make an invoice with it
Open tax report

The 0% tax is not present in the report because there is no tax lines generated for them because the resulting balance is zero.
Since the tax details is making a mapping between tax lines and base lines and the tax report is using them to compute the report, the tax report is not able to compute the tax base amount for such taxes.

Explanation:

Until now, the tax line with a zero amount wasn't generated because considered as noisy journal items.
Now we must be able to groupby on the base tax account on the tax report, we are forced to use the tax details.
Injecting dynamically the 0% tax on the tax details sub-queries is really complicated and leads to a huge performance drop.
For that reason, we start to generate the tax lines for 0% tax even the balance is zero.
However, since there is nothing creating the missing lines in the past, it should be fixed case by case if needed.

opw-2711432

closes odoo/odoo#82971

X-original-commit: 65b5ec4ad65f798b1d647978b5b42a49e760139a
Signed-off-by: Olivier Colson <oco@odoo.com>
Signed-off-by: Laurent Smet <las@odoo.com>
This commit is contained in:
Laurent Smet
2022-01-18 13:40:43 +00:00
parent 6b0ab28791
commit 022ecb50fe
4 changed files with 87 additions and 8 deletions
-6
View File
@@ -787,12 +787,6 @@ class AccountMove(models.Model):
currency = self.env['res.currency'].browse(taxes_map_entry['grouping_dict']['currency_id'])
# Don't create tax lines with zero balance.
if currency.is_zero(taxes_map_entry['amount']):
if taxes_map_entry['tax_line'] and not recompute_tax_base_amount:
self.line_ids -= taxes_map_entry['tax_line']
continue
# tax_base_amount field is expressed using the company currency.
tax_base_amount = currency._convert(taxes_map_entry['tax_base_amount'], self.company_currency_id, self.company_id, self.date or fields.Date.context_today(self))
@@ -1167,3 +1167,88 @@ class TestAccountTaxDetailsReport(AccountTestInvoicingCommon):
],
)
self.assertTotalAmounts(invoice, tax_details)
def test_zero_amount_tax(self):
""" Ensure the tax details is generated for 0% tax. """
zero_tax = self.env['account.tax'].create({
'name': "zero_tax",
'amount_type': 'percent',
'amount': 0.0,
})
invoice = self.env['account.move'].create({
'move_type': 'out_invoice',
'partner_id': self.partner_a.id,
'invoice_date': '2019-01-01',
'invoice_line_ids': [
Command.create({
'name': 'line1',
'account_id': self.company_data['default_account_revenue'].id,
'price_unit': 1000.0,
'tax_ids': [Command.set(zero_tax.ids)],
}),
Command.create({
'name': 'line2',
'account_id': self.company_data['default_account_revenue'].id,
'price_unit': 1000.0,
'tax_ids': [Command.set(zero_tax.ids)],
}),
]
})
base_lines, tax_lines = self._dispatch_move_lines(invoice)
tax_details = self._get_tax_details()
self.assertTaxDetailsValues(
tax_details,
[
{
'base_line_id': base_lines[0].id,
'tax_line_id': tax_lines[0].id,
'base_amount': -1000.0,
'tax_amount': 0.0,
},
{
'base_line_id': base_lines[1].id,
'tax_line_id': tax_lines[0].id,
'base_amount': -1000.0,
'tax_amount': 0.0,
},
],
)
self.assertTotalAmounts(invoice, tax_details)
# Same with a group of taxes
tax_group = self.env['account.tax'].create({
'name': "tax_group",
'amount_type': 'group',
'children_tax_ids': [Command.set(zero_tax.ids)],
})
invoice.write({
'invoice_line_ids': [
Command.update(base_lines[0].id, {'tax_ids': [Command.set(tax_group.ids)]}),
Command.update(base_lines[1].id, {'tax_ids': [Command.set(tax_group.ids)]}),
],
})
base_lines, tax_lines = self._dispatch_move_lines(invoice)
tax_details = self._get_tax_details()
self.assertTaxDetailsValues(
tax_details,
[
{
'base_line_id': base_lines[0].id,
'tax_line_id': tax_lines[0].id,
'base_amount': -1000.0,
'tax_amount': 0.0,
},
{
'base_line_id': base_lines[1].id,
'tax_line_id': tax_lines[0].id,
'base_amount': -1000.0,
'tax_amount': 0.0,
},
],
)
self.assertTotalAmounts(invoice, tax_details)
@@ -2802,7 +2802,7 @@ class TestAccountMoveOutInvoiceOnchanges(AccountTestInvoicingCommon):
})
self.assertEqual(len(invoice.invoice_line_ids), 1)
self.assertEqual(len(invoice.line_ids), 2)
self.assertEqual(len(invoice.line_ids), 3)
def test_out_invoice_recomputation_receivable_lines(self):
''' Test a tricky specific case caused by some framework limitations. Indeed, when
@@ -80,7 +80,7 @@ class ValuationReconciliationTestCommon(AccountTestInvoicingCommon):
def check_reconciliation(self, invoice, picking, full_reconcile=True, operation='purchase'):
interim_account_id = self.company_data['default_account_stock_in'].id if operation == 'purchase' else self.company_data['default_account_stock_out'].id
invoice_line = invoice.line_ids.filtered(lambda line: line.account_id.id == interim_account_id)
invoice_line = invoice.line_ids.filtered(lambda line: line.account_id.id == interim_account_id and not line.tax_line_id)
stock_moves = picking.move_ids