Skip to content
Snippets Groups Projects
Commit 91bd2b8c authored by Nicolas Galler's avatar Nicolas Galler
Browse files

[FIX] account: avoid multiplying rounding error on unit price.

Do not round the unit price when calculating the company currency price
used to calculate the tax.  This avoids rounding errors when the company
currency amount has been calculated based on a converted (and rounded) unit
price.

Corrects a regression bug introduced in 13.0.  The behavior has been
corrected in 14.0 by a more extensive rework of the accounting module
(commit id 419d4bbe among others).
This fix seeks to correct the bug with minimal impact.

In version 12.0, the tax amount was calculated strictly based on the
total amount, which avoided compounding the rounding issue but had some
other problems (see https://github.com/odoo/odoo/issues/35358

).

In version 14.0, the problem does not exist.  This commit only includes
the unit test.

Current behavior before PR:

For example: 20000 @ 2.82 with a rate of 1.1726 gives a
tax amount in foreign currency of 11844, which is 10100 in company
currency.  But if the company currency amount is calculated
based on a unit price of 2.4 (rounded converted amount of 2.82), the
calculated tax amount will only be 10080 in company currency.

Desired behavior after PR is merged:

Tax amount is calculated based on the total amount in the foreign
currency, not the amount based on the rounded unit price.

opw-2340933

closes odoo/odoo#59365

X-original-commit: 14c86a02
Signed-off-by: default avatarNicolas Martinelli (nim) <nim@odoo.com>
Signed-off-by: default avatarNicolas Galler <nicocrm@users.noreply.github.com>
parent 73be30d3
Branches
Tags
No related merge requests found
......@@ -432,3 +432,48 @@ class TestInvoiceTaxes(AccountTestInvoicingCommon):
{'balance': -100.0, 'tax_ids': [], 'tax_tag_ids': self.tax_tag_pos.ids},
{'balance': 1100.0, 'tax_ids': [], 'tax_tag_ids': []},
])
def test_tax_calculation_foreign_currency_large_quantity(self):
''' Test:
Foreign currency with rate of 1.1726 and tax of 21%
price_unit | Quantity | Taxes
------------------
2.82 | 20000 | 21% not incl
'''
self.env['res.currency.rate'].search([]).unlink()
self.currency_usd_id = self.env.ref("base.USD")
self.currency_chf_id = self.env.ref("base.CHF")
# make sure that we have USD as base...
self.cr.execute("UPDATE res_company SET currency_id = %s WHERE id = %s",
[self.currency_usd_id.id, self.env.company.id])
self.env['res.currency.rate'].create({
'currency_id': self.currency_chf_id.id,
'rate': 1.1726,
'name': '2001-01-01'})
invoice = self.env['account.move'].create({
'move_type': 'out_invoice',
'partner_id': self.partner_a.id,
'currency_id': self.currency_chf_id.id,
'invoice_line_ids': [(0, 0, {
'name': 'xxxx',
'quantity': 20000,
'price_unit': 2.82,
'tax_ids': [(6, 0, self.percent_tax_1.ids)],
})]
})
# don't post! Post will write() which will cause the amount to recalculate.
# but we want to make sure that the calculation is correct when it is made on
# the fly, from a user editing it in the web UI
# invoice.post()
# make sure the tax is calculated in the foreign currency correctly
self.assertRecordValues(invoice.line_ids.filtered('tax_line_id'), [
{
'name': self.percent_tax_1.name,
# 20000 * 2.82 / 1.1726
'tax_base_amount': 48098.24,
'price_unit': 11844,
# tax_base_amount * 21%
'credit': 10100.63,
'tax_ids': []
},
])
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment