diff options
| author | Nans Lefebvre <len@odoo.com> | 2019-09-24 17:06:30 +0000 |
|---|---|---|
| committer | fw-bot <otis@odoo.com> | 2019-10-10 11:11:30 +0000 |
| commit | d77a8de5f9a53486337682ce8c7b79317cfe98ab (patch) | |
| tree | 420ffaa21d14218c2f6da4b367dd190a6538cba6 /addons | |
| parent | 398592fb9ded46f28a7b2a6e210b7000d6e30dcd (diff) | |
[FIX] account: round debit and credit of account move lines at creation
This fix is similar to 8020033; both are workarounds for the bug (limitation)
introduced by 9d87d15db6dd40a5a0162fb126c725a2f0a40414.
In this case, the currency_field is a related field, and these fields are only
computed after scalar values are written in database.
As a result, this value is not rounded at creation.
It is a problem since typically accounting reports are written directly in SQL,
and thus reuse the values directly.
Anyway even in the ORM the convert_to_cache optimised this away using the
assumption that 'the value should have been rounded in convert_to_column'.
It follows that in the report, errors can be accumulated
to the point where the report is not balanced.
This needs to be fixed in database by going through every existing line.
Of note: the limitation that was readily acknowledged has not been worked around
anywhere, in fact almost every single currency_field is a related one.
Also of note, commit afef71d6b should "Always round monetary values in database"
while it explicitly checked for the presence of the currency_field in the values
and while not introducing a mechanism to make sure it would always be in the
values.
opw 2066849
closes odoo/odoo#38376
X-original-commit: 937893379ba8c149c681b61a951ca507df798e6b
Signed-off-by: Nans Lefebvre (len) <len@odoo.com>
Diffstat (limited to 'addons')
| -rw-r--r-- | addons/account/models/account_move.py | 1 | ||||
| -rw-r--r-- | addons/account/tests/__init__.py | 1 | ||||
| -rw-r--r-- | addons/account/tests/test_account_move_rounding.py | 77 |
3 files changed, 79 insertions, 0 deletions
diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 5a07c9e271a..4b8058a4b35 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -3049,6 +3049,7 @@ class AccountMoveLine(models.Model): for vals in vals_list: move = self.env['account.move'].browse(vals['move_id']) + vals.setdefault('company_currency_id', move.company_id.currency_id.id) # important to bypass the ORM limitation where monetary fields are not rounded; more info in the commit message if move.is_invoice(include_receipts=True): currency = self.env['res.currency'].browse(vals.get('currency_id')) diff --git a/addons/account/tests/__init__.py b/addons/account/tests/__init__.py index 4ce82138fb8..c55e6b05423 100644 --- a/addons/account/tests/__init__.py +++ b/addons/account/tests/__init__.py @@ -6,6 +6,7 @@ from . import test_account_move_in_invoice from . import test_account_move_in_refund from . import test_account_move_entry from . import test_account_move_partner_count +from . import test_account_move_rounding from . import test_account_invoice_report from . import test_account_journal_dashboard from . import test_bank_statement_reconciliation diff --git a/addons/account/tests/test_account_move_rounding.py b/addons/account/tests/test_account_move_rounding.py new file mode 100644 index 00000000000..63a3bebc2be --- /dev/null +++ b/addons/account/tests/test_account_move_rounding.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +from odoo.addons.account.tests.account_test_classes import AccountingTestCase +from odoo.tests import tagged + + +@tagged('post_install', '-at_install') +class TestAccountMoveRounding(AccountingTestCase): + + def setUp(self): + super(TestAccountMoveRounding, self).setUp() + self.currency = self.env['res.currency'].create({ + 'name': "RAM", + 'symbol': "🐏", + 'rounding': 0.01, + }) + self.company = self.env['res.company'].create({ + 'name': "SHEEP", + 'currency_id': self.currency.id, + }) + self.account_type = self.env['account.account.type'].create( + {'name': 'BAAH', + 'internal_group': 'asset', + 'type': 'receivable' + }) + self.journal = self.env['account.journal'].create({ + 'company_id': self.company.id, + 'name': 'LAMB', + 'code': 'L', + 'type': 'purchase', + }) + self.account = self.env['account.account'].create({ + 'company_id': self.company.id, + 'name': 'EWE', + 'code': 'E', + 'user_type_id': self.account_type.id, + 'reconcile': True, + }) + + + def test_move_line_rounding(self): + """Whatever arguments we give to the creation of an account move, + in every case the amounts should be properly rounded to the currency's precision. + In other words, we don't fall victim of the limitation introduced by 9d87d15db6dd40 + + Here the rounding should be done according to company_currency_id, which is a related + on move_id.company_id.currency_id. + In principle, it should not be necessary to add it to the create values, + since it is supposed to be computed by the ORM... + """ + move1 = self.env['account.move'].create({ + 'journal_id': self.journal.id, + 'line_ids': [ + (0, 0, {'debit': 100.0 / 3, 'account_id': self.account.id}), + (0, 0, {'credit': 100.0 / 3, 'account_id': self.account.id}), + ], + }) + move2 = self.env['account.move'].create({ + 'journal_id': self.journal.id, + 'line_ids': [ + (0, 0, {'debit': 100.0 / 3, 'account_id': self.account.id, + 'company_currency_id': self.company.currency_id.id}), + (0, 0, {'credit': 100.0 / 3, 'account_id': self.account.id, + 'company_currency_id': self.company.currency_id.id}), + ], + }) + + self.assertEqual( + [(33.33, 0.0), (0.0, 33.33)], + move2.line_ids.mapped(lambda x: (x.debit, x.credit)), + "Quantities should have been rounded according to the currency." + ) + self.assertEqual( + move1.line_ids.mapped(lambda x: (x.debit, x.credit)), + move2.line_ids.mapped(lambda x: (x.debit, x.credit)), + "In both cases the rounding should be correctly done." + ) |
