[FIX] account: Fix tax details with negative invoice lines
Before this commit: Suppose invl1 of 1000.0 with 10.0% and invl2 of -100.0 with the same tax. A tax line of 90.0 is created. If invl1 is created before invl2, the tax details is computing the tax amounts as: invl1 tax amount = 1000/900 * 90 = 100 (OK) invl2 tax amount = 90 - 100 = -10 (OK) total tax amount = 100 - 10 = 90 (OK) If invl2 is created before invl2: invl1 tax amount = 100/900 * 90 = 10 (NOT OK) invl2 tax amount = 90 - 10 = 80 (NOT OK) total tax amount = 10 + 80 = 90 (OK) closes odoo/odoo#85406 X-original-commit: bada85c7621b45970c88548c4d09b88b77c08e8e Signed-off-by: Olivier Colson <oco@odoo.com> Signed-off-by: Laurent Smet <las@odoo.com>
This commit is contained in:
@@ -319,11 +319,11 @@ class AccountMoveLine(models.Model):
|
||||
sub.src_line_id,
|
||||
|
||||
ROUND(
|
||||
COALESCE(sub.total_tax_amount * ABS(sub.cumulated_base_amount) / ABS(NULLIF(sub.total_base_amount, 0.0)), 0.0),
|
||||
COALESCE(SIGN(sub.cumulated_base_amount) * sub.total_tax_amount * ABS(sub.cumulated_base_amount) / NULLIF(sub.total_base_amount, 0.0), 0.0),
|
||||
sub.comp_curr_prec
|
||||
)
|
||||
- LAG(ROUND(
|
||||
COALESCE(sub.total_tax_amount * ABS(sub.cumulated_base_amount) / ABS(NULLIF(sub.total_base_amount, 0.0)), 0.0),
|
||||
COALESCE(SIGN(sub.cumulated_base_amount) * sub.total_tax_amount * ABS(sub.cumulated_base_amount) / NULLIF(sub.total_base_amount, 0.0), 0.0),
|
||||
sub.comp_curr_prec
|
||||
), 1, 0.0)
|
||||
OVER (
|
||||
@@ -331,11 +331,11 @@ class AccountMoveLine(models.Model):
|
||||
) AS base_amount,
|
||||
|
||||
ROUND(
|
||||
COALESCE(sub.total_tax_amount_currency * ABS(sub.cumulated_base_amount_currency) / ABS(NULLIF(sub.total_base_amount_currency, 0.0)), 0.0),
|
||||
COALESCE(SIGN(sub.cumulated_base_amount_currency) * sub.total_tax_amount_currency * ABS(sub.cumulated_base_amount_currency) / NULLIF(sub.total_base_amount_currency, 0.0), 0.0),
|
||||
sub.curr_prec
|
||||
)
|
||||
- LAG(ROUND(
|
||||
COALESCE(sub.total_tax_amount_currency * ABS(sub.cumulated_base_amount_currency) / ABS(NULLIF(sub.total_base_amount_currency, 0.0)), 0.0),
|
||||
COALESCE(SIGN(sub.cumulated_base_amount_currency) * sub.total_tax_amount_currency * ABS(sub.cumulated_base_amount_currency) / NULLIF(sub.total_base_amount_currency, 0.0), 0.0),
|
||||
sub.curr_prec
|
||||
), 1, 0.0)
|
||||
OVER (
|
||||
@@ -459,11 +459,11 @@ class AccountMoveLine(models.Model):
|
||||
|
||||
sub.base_amount,
|
||||
ROUND(
|
||||
COALESCE(sub.total_tax_amount * ABS(sub.cumulated_base_amount) / ABS(NULLIF(sub.total_base_amount, 0.0)), 0.0),
|
||||
COALESCE(SIGN(sub.cumulated_base_amount) * sub.total_tax_amount * ABS(sub.cumulated_base_amount) / NULLIF(sub.total_base_amount, 0.0), 0.0),
|
||||
sub.comp_curr_prec
|
||||
)
|
||||
- LAG(ROUND(
|
||||
COALESCE(sub.total_tax_amount * ABS(sub.cumulated_base_amount) / ABS(NULLIF(sub.total_base_amount, 0.0)), 0.0),
|
||||
COALESCE(SIGN(sub.cumulated_base_amount) * sub.total_tax_amount * ABS(sub.cumulated_base_amount) / NULLIF(sub.total_base_amount, 0.0), 0.0),
|
||||
sub.comp_curr_prec
|
||||
), 1, 0.0)
|
||||
OVER (
|
||||
@@ -472,11 +472,11 @@ class AccountMoveLine(models.Model):
|
||||
|
||||
sub.base_amount_currency,
|
||||
ROUND(
|
||||
COALESCE(sub.total_tax_amount_currency * ABS(sub.cumulated_base_amount_currency) / ABS(NULLIF(sub.total_base_amount_currency, 0.0)), 0.0),
|
||||
COALESCE(SIGN(sub.cumulated_base_amount_currency) * sub.total_tax_amount_currency * ABS(sub.cumulated_base_amount_currency) / NULLIF(sub.total_base_amount_currency, 0.0), 0.0),
|
||||
sub.curr_prec
|
||||
)
|
||||
- LAG(ROUND(
|
||||
COALESCE(sub.total_tax_amount_currency * ABS(sub.cumulated_base_amount_currency) / ABS(NULLIF(sub.total_base_amount_currency, 0.0)), 0.0),
|
||||
COALESCE(SIGN(sub.cumulated_base_amount_currency) * sub.total_tax_amount_currency * ABS(sub.cumulated_base_amount_currency) / NULLIF(sub.total_base_amount_currency, 0.0), 0.0),
|
||||
sub.curr_prec
|
||||
), 1, 0.0)
|
||||
OVER (
|
||||
|
||||
@@ -17,8 +17,8 @@ class TestAccountTaxDetailsReport(AccountTestInvoicingCommon):
|
||||
.sorted(lambda x: (x.move_id, x.tax_line_id, x.tax_ids, x.tax_repartition_line_id))
|
||||
return base_lines, tax_lines
|
||||
|
||||
def _get_tax_details(self, fallback=False):
|
||||
domain = [('company_id', '=', self.env.company.id)]
|
||||
def _get_tax_details(self, fallback=False, extra_domain=None):
|
||||
domain = [('company_id', '=', self.env.company.id)] + (extra_domain or [])
|
||||
tax_details_query, tax_details_params = self.env['account.move.line']._get_query_tax_details_from_domain(domain, fallback=fallback)
|
||||
self.cr.execute(tax_details_query, tax_details_params)
|
||||
tax_details_res = self.cr.dictfetchall()
|
||||
@@ -1252,3 +1252,47 @@ class TestAccountTaxDetailsReport(AccountTestInvoicingCommon):
|
||||
],
|
||||
)
|
||||
self.assertTotalAmounts(invoice, tax_details)
|
||||
|
||||
def test_amounts_sign(self):
|
||||
for tax_sign in (1, -1):
|
||||
tax = self.env['account.tax'].create({
|
||||
'name': "tax",
|
||||
'amount_type': 'percent',
|
||||
'amount': tax_sign * 10.0,
|
||||
})
|
||||
|
||||
amounts_list = [
|
||||
(-1000.0, 7000.0, -2000.0),
|
||||
(1000.0, -7000.0, 2000.0),
|
||||
(-1000.0, -7000.0, 2000.0),
|
||||
(1000.0, 7000.0, -2000.0),
|
||||
]
|
||||
for amounts in amounts_list:
|
||||
with self.subTest(tax_sign=tax_sign, amounts=amounts):
|
||||
invoice = self.env['account.move'].create({
|
||||
'move_type': 'in_invoice',
|
||||
'partner_id': self.partner_a.id,
|
||||
'invoice_date': '2019-01-01',
|
||||
'invoice_line_ids': [
|
||||
Command.create({
|
||||
'name': 'line2',
|
||||
'account_id': self.company_data['default_account_revenue'].id,
|
||||
'price_unit': amount,
|
||||
'tax_ids': [Command.set(tax.ids)],
|
||||
})
|
||||
for amount in amounts],
|
||||
})
|
||||
_base_lines, tax_lines = self._dispatch_move_lines(invoice)
|
||||
|
||||
tax_details = self._get_tax_details(extra_domain=[('move_id', '=', invoice.id)])
|
||||
self.assertTaxDetailsValues(
|
||||
tax_details,
|
||||
[
|
||||
{
|
||||
'tax_line_id': tax_lines[0].id,
|
||||
'base_amount': amount,
|
||||
'tax_amount': tax_sign * amount * 0.1,
|
||||
}
|
||||
for amount in amounts],
|
||||
)
|
||||
self.assertTotalAmounts(invoice, tax_details)
|
||||
|
||||
Reference in New Issue
Block a user