[FIX] account: reconciliation on reversed move

With this commit, we make sure that all lines are fully reconciled when
reversing a move.

Steps to reproduce:

- Create a Journal Entry, with eg a line with 300$ debit/credit and two others
lines to make the journal entry fully balanced
- Then reverse the move
-> Only one line is marked as fully reconciled, the other one is marked
as partially reconciled.

This is because each line was passed in the reconcile method with
all the counterpart lines, even those which didn't belong to it.
Therefore, all the firsts lines was marked as partially reconciled
until the last one, which passed with the only counterpart line
left.

With this commit, we group the lines and counterpart lines by account,
and reconcile them.

opw-2810392

closes odoo/odoo#90928

X-original-commit: 0a03d029f93f6c0f31f6617c00943aa2dfcd937b
Signed-off-by: William André (wan) <wan@odoo.com>
Signed-off-by: Guillaume Vanleynseele <guva@odoo.com>
This commit is contained in:
Guillaume (guva)
2022-05-09 19:56:50 +02:00
committed by william
parent 7a146e6f0b
commit d00fdb9310
2 changed files with 63 additions and 11 deletions
+6 -11
View File
@@ -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
@@ -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({