From 9989a9c3294d0ef3bd6a659bd8a5d7cce9cd49dc Mon Sep 17 00:00:00 2001 From: Laurent Smet Date: Tue, 21 May 2019 15:15:57 +0000 Subject: [PATCH] [FIX] account: Fix reconciliation foreign currency on account Suppose you make a reconciliation on an account having a foreign currency being the same as the company one. Suppose also you are making a reconciliation of three lines without currency_id set on this account: - A with debit = 11 - B with credit = 10 - C with credit = 1 Before this commit, the reconciliation was wrong because all computation are made using the foreign currency due to the account's configuration. As A, B & C have their amount_currency set to 0, an account.full.reconcile is well created but only one account.partial.reconcile is created instead of 2 leading to an inconsistent state. opw:1984684 closes odoo/odoo#33445 Signed-off-by: Simon Goffin (sig) Co-authored-by: Goffin Simon --- addons/account/models/account_move.py | 5 +- addons/account/tests/test_reconciliation.py | 70 +++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 825cbb37025..41d2e75e912 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -918,7 +918,10 @@ class AccountMoveLine(models.Model): debit_moves = debit_moves.sorted(key=lambda a: (a.date_maturity or a.date, a.currency_id)) credit_moves = credit_moves.sorted(key=lambda a: (a.date_maturity or a.date, a.currency_id)) # Compute on which field reconciliation should be based upon: - field = self[0].account_id.currency_id and 'amount_residual_currency' or 'amount_residual' + if self[0].account_id.currency_id and self[0].account_id.currency_id != self[0].account_id.company_id.currency_id: + field = 'amount_residual_currency' + else: + field = 'amount_residual' #if all lines share the same currency, use amount_residual_currency to avoid currency rounding error if self[0].currency_id and all([x.amount_currency and x.currency_id == self[0].currency_id for x in self]): field = 'amount_residual_currency' diff --git a/addons/account/tests/test_reconciliation.py b/addons/account/tests/test_reconciliation.py index 0226a0f1e94..83f3c0c6d72 100644 --- a/addons/account/tests/test_reconciliation.py +++ b/addons/account/tests/test_reconciliation.py @@ -90,6 +90,11 @@ class TestReconciliation(AccountingTestCase): 'code': 'CABA', 'type': 'general', }) + self.general_journal = self.env['account.journal'].create({ + 'name': 'general', + 'code': 'GENE', + 'type': 'general', + }) # Tax Cash Basis self.tax_cash_basis = self.env['account.tax'].create({ @@ -1999,3 +2004,68 @@ class TestReconciliationExec(TestReconciliation): pay_receivable_line1 = payment1.move_line_ids.filtered(lambda l: l.account_id == self.account_rcv) self.assertTrue(pay_receivable_line1.reconciled) self.assertEqual(pay_receivable_line1.matched_debit_ids, move_caba1.tax_cash_basis_rec_id) + + def test_reconciliation_with_currency(self): + #reconciliation on an account having a foreign currency being + #the same as the company one + account_rcv = self.account_rcv + account_rcv.currency_id = self.currency_euro_id + aml_obj = self.env['account.move.line'].with_context( + check_move_validity=False) + general_move1 = self.env['account.move'].create({ + 'name': 'general1', + 'journal_id': self.general_journal.id, + }) + aml_obj.create({ + 'name': 'debit1', + 'account_id': account_rcv.id, + 'debit': 11, + 'move_id': general_move1.id, + }) + aml_obj.create({ + 'name': 'credit1', + 'account_id': self.account_rsa.id, + 'credit': 11, + 'move_id': general_move1.id, + }) + general_move1.post() + general_move2 = self.env['account.move'].create({ + 'name': 'general2', + 'journal_id': self.general_journal.id, + }) + aml_obj.create({ + 'name': 'credit2', + 'account_id': account_rcv.id, + 'credit': 10, + 'move_id': general_move2.id, + }) + aml_obj.create({ + 'name': 'debit2', + 'account_id': self.account_rsa.id, + 'debit': 10, + 'move_id': general_move2.id, + }) + general_move2.post() + general_move3 = self.env['account.move'].create({ + 'name': 'general3', + 'journal_id': self.general_journal.id, + }) + aml_obj.create({ + 'name': 'credit3', + 'account_id': account_rcv.id, + 'credit': 1, + 'move_id': general_move3.id, + }) + aml_obj.create({ + 'name': 'debit3', + 'account_id': self.account_rsa.id, + 'debit': 1, + 'move_id': general_move3.id, + }) + general_move3.post() + to_reconcile = ((general_move1 + general_move2 + general_move3) + .mapped('line_ids') + .filtered(lambda l: l.account_id.id == account_rcv.id)) + to_reconcile.reconcile() + for aml in to_reconcile: + self.assertEqual(aml.amount_residual, 0.0)