diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 56ac0b9af69..ec00bb99a97 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -2643,17 +2643,12 @@ class AccountMove(models.Model): if cancel: reverse_moves.with_context(move_reverse_cancel=cancel)._post(soft=False) for move, reverse_move in zip(self, reverse_moves): - lines = move.line_ids.filtered( - lambda x: (x.account_id.reconcile or x.account_id.internal_type == 'liquidity') - and not x.reconciled - ) - for line in lines: - counterpart_lines = reverse_move.line_ids.filtered( - lambda x: x.account_id == line.account_id - and x.currency_id == line.currency_id - and not x.reconciled - ) - (line + counterpart_lines).with_context(move_reverse_cancel=cancel).reconcile() + group = defaultdict(list) + for line in move.line_ids + reverse_move.line_ids: + group[(line.account_id, line.currency_id)].append(line.id) + for (account, dummy), line_ids in group.items(): + if account.reconcile or account.internal_type == 'liquidity': + self.env['account.move.line'].browse(line_ids).reconcile() return reverse_moves diff --git a/addons/account/tests/test_account_move_reconcile.py b/addons/account/tests/test_account_move_reconcile.py index a459ffcaaa1..a5053d6657a 100644 --- a/addons/account/tests/test_account_move_reconcile.py +++ b/addons/account/tests/test_account_move_reconcile.py @@ -1631,6 +1631,63 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon): {'amount_residual': 0.0, 'amount_residual_currency': 0.0, 'reconciled': True}, ]) + def test_reverse_with_multiple_lines(self): + """ + Test if all lines from a reversed entry are fully reconciled + """ + move = self.env['account.move'].create({ + 'move_type': 'entry', + 'line_ids': [ + (0, 0, { + 'debit': 1200.0, + 'credit': 0.0, + 'amount_currency': 3600.0, + 'account_id': self.company_data['default_account_receivable'].id, + }), + (0, 0, { + 'debit': 0.0, + 'credit': 200.0, + 'account_id': self.company_data['default_account_payable'].id, + }), + (0, 0, { + 'debit': 0.0, + 'credit': 400.0, + 'account_id': self.company_data['default_account_payable'].id, + }), + (0, 0, { + 'debit': 0.0, + 'credit': 600.0, + 'account_id': self.company_data['default_account_payable'].id, + }), + ], + }) + + move.action_post() + + lines_to_reconcile = move.line_ids.filtered(lambda x: (x.account_id.reconcile or x.account_id.internal_type == 'liquidity') and not x.reconciled) + + self.assertRecordValues(lines_to_reconcile, [ + {'debit': 1200.0, 'credit': 0.0, 'reconciled': False}, + {'debit': 0.0, 'credit': 200.0, 'reconciled': False}, + {'debit': 0.0, 'credit': 400.0, 'reconciled': False}, + {'debit': 0.0, 'credit': 600.0, 'reconciled': False}, + ]) + + reversed_move = move._reverse_moves(cancel=True) + + reversed_lines = reversed_move.line_ids.filtered(lambda x: ( + x.account_id.reconcile or x.account_id.internal_type == 'liquidity' + )) + + self.assertRecordValues(reversed_lines, [ + {'debit': 0.0, 'credit': 1200.0, 'reconciled': True}, + {'debit': 200.0, 'credit': 0.0, 'reconciled': True}, + {'debit': 400.0, 'credit': 0.0, 'reconciled': True}, + {'debit': 600.0, 'credit': 0.0, 'reconciled': True}, + ]) + + self.assertTrue(all([line.full_reconcile_id for line in reversed_lines])) + def test_reconcile_special_mexican_workflow_1(self): comp_curr = self.company_data['currency'] foreign_curr = self.env['res.currency'].create({