[FIX] account: Traceback on multiple auto-validation candidates

When an auto-validating reconciliation model is defined for matching
bank statement lines to invoices, it was possible to get a traceback
when the bank statement lines were in a certain order and matched in a
certain way.

In particular, if the first bank statement line is priority 3
(communication_flag True) and the amount is an exact match with the
invoice, it will be instantly reconciled. If there's a second line
that's a priority 5 match, it crashed because _filter_candidates didn't
take into account that candidates_by_priority could be empty if the
candidates were already reconciled.

Instead we just return an empty list of candidates and priorities when
this happens.

closes odoo/odoo#69331

Ticket: 2507189
X-original-commit: e9538d9cee092e034b85187a2eae857349f42ce7
Signed-off-by: William André (wan) <wan@odoo.com>
This commit is contained in:
Raf Geens
2021-04-15 15:07:21 +00:00
parent 65800bcfa5
commit fc41a4a6c9
2 changed files with 48 additions and 0 deletions
@@ -890,6 +890,11 @@ class AccountReconcileModel(models.Model):
the most prioritary are kept.
"""
candidates_by_priority = self._sort_reconciliation_candidates_by_priority(candidates, aml_ids_to_exclude, reconciled_amls_ids)
# This can happen if the candidates were already reconciled at this point
if not candidates_by_priority:
return [], set()
max_priority = min(candidates_by_priority.keys())
filtered_candidates = candidates_by_priority[max_priority]
@@ -477,6 +477,49 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
self.assertEqual(self.invoice_line_1.amount_residual, 60.0, "The invoice should have been partially reconciled")
def test_auto_reconcile_with_duplicate_match(self):
""" If multiple bank statement lines match with the same invoice, ensure the
correct line is auto-validated and no crashing happens.
"""
# Only the invoice defined in this test should have this partner
partner = self.env['res.partner'].create({'name': "The Only One"})
invoice_line = self._create_invoice_line(
2000, partner, 'out_invoice', ref="REF 7788")
# Enable auto-validation and don't restrict the partners that can be matched on
# so our newly created partner can be matched.
self.rule_1.write({
'auto_reconcile': True,
'match_partner_ids': [(5, 0, 0)],
})
self.rule_1.match_partner_ids = []
# This line has a matching payment reference and the exact amount of the
# invoice. As a result it should auto-validate.
self.bank_line_1.amount = 2000
self.bank_line_1.partner_id = partner
self.bank_line_1.payment_ref = "REF 7788"
# This line doesn't have a matching amount or reference, but it does have a
# matching partner.
self.bank_line_2.amount = 1800
self.bank_line_2.partner_id = partner
self.bank_line_2.payment_ref = "something"
# Verify the auto-validation happens with the first line, and no exceptions.
self._check_statement_matching(self.rule_1, {
self.bank_line_1.id: {
'aml_ids': [invoice_line.id],
'model': self.rule_1,
'status': 'reconciled',
'partner': self.bank_line_1.partner_id
},
self.bank_line_2.id: {
'aml_ids': []
},
}, statements=self.bank_st)
def test_auto_reconcile_with_tax(self):
''' Test auto reconciliation with a tax amount included in the bank statement line'''
self.rule_1.write({