diff options
| author | oco-odoo <oco@odoo.com> | 2021-05-03 15:15:43 +0000 |
|---|---|---|
| committer | oco-odoo <oco@odoo.com> | 2021-05-03 15:52:49 +0000 |
| commit | b5800c9d2088df2bb9c4fbe0fed91c7ef24299c5 (patch) | |
| tree | e080c5c96ebe0ff3f7eb68c722384a4aec86ed31 | |
| parent | 2480e9593808126ade2537cc2ae40b85080ba441 (diff) | |
[FIX] account: reconciliation models: fix priorities when matching amls from payments
Since the payment refactoring, the structured reference of a payment is stored in its ref field, not payment_reference like for invoices. This caused payments never to be matched with highest priorities, as payment_reference_flag was always false, and only communication_flag could match.
To reproduce:
- Have a reconcile model with match_total_amount=False.
- Create a statement line with communication a1b2c3 for 1000
- Create 3 payments:
> 500, with memo a1b2c3
> 500, with memo a1b2c3 (so, the same one)
> 500, with memo d1e2f3
- Open the reconciliation widget for your statement line
===> The 3 payments are matched, while only the two first ones should have been, as they were exact matches for the communication, and should hence have received higher priority.
closes odoo/odoo#70277
Signed-off-by: Laurent Smet <smetl@users.noreply.github.com>
| -rw-r--r-- | addons/account/models/account_reconcile_model.py | 9 | ||||
| -rw-r--r-- | addons/account/tests/test_reconciliation_matching_rules.py | 36 |
2 files changed, 42 insertions, 3 deletions
diff --git a/addons/account/models/account_reconcile_model.py b/addons/account/models/account_reconcile_model.py index 2da8dd89fb2..4b866bcbbb6 100644 --- a/addons/account/models/account_reconcile_model.py +++ b/addons/account/models/account_reconcile_model.py @@ -30,7 +30,7 @@ class AccountReconcileModelPartnerMapping(models.Model): re.compile(record.payment_ref_regex) if record.narration_regex: current_regex = record.narration_regex - re.compile(record.narration_regex) + re.compile(record.narration_regex) except re.error: raise ValidationError(_("The following regular expression is invalid to create a partner mapping: %s") % current_regex) @@ -612,6 +612,7 @@ class AccountReconcileModel(models.Model): LEFT JOIN account_move move ON move.id = aml.move_id AND move.state = 'posted' LEFT JOIN account_account account ON account.id = aml.account_id LEFT JOIN res_partner aml_partner ON aml.partner_id = aml_partner.id + LEFT JOIN account_payment payment ON payment.move_id = move.id WHERE aml.company_id = st_line_move.company_id AND move.state = 'posted' @@ -725,9 +726,11 @@ class AccountReconcileModel(models.Model): st_ref_list += ['st_line_move.ref'] if not st_ref_list: return "FALSE" - return r'''(move.payment_reference IS NOT NULL AND ({}))'''.format( + + # payment_reference is not used on account.move for payments; ref is used instead + return r'''((move.payment_reference IS NOT NULL OR (payment.id IS NOT NULL AND move.ref IS NOT NULL)) AND ({}))'''.format( ' OR '.join( - rf"regexp_replace(move.payment_reference, '\s+', '', 'g') = regexp_replace({st_ref}, '\s+', '', 'g')" + rf"regexp_replace(CASE WHEN payment.id IS NULL THEN move.payment_reference ELSE move.ref END, '\s+', '', 'g') = regexp_replace({st_ref}, '\s+', '', 'g')" for st_ref in st_ref_list ) ) diff --git a/addons/account/tests/test_reconciliation_matching_rules.py b/addons/account/tests/test_reconciliation_matching_rules.py index b7718ff0f7b..c00fe13cbbd 100644 --- a/addons/account/tests/test_reconciliation_matching_rules.py +++ b/addons/account/tests/test_reconciliation_matching_rules.py @@ -919,3 +919,39 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon): self.bank_line_1.id: {'aml_ids': [self.invoice_line_1.id], 'model': self.rule_1, 'status': 'write_off', 'partner': self.bank_line_1.partner_id}, self.bank_line_2.id: {'aml_ids': [self.invoice_line_2.id], 'model': second_inv_matching_rule, 'partner': self.bank_line_2.partner_id} }, statements=self.bank_st) + + def test_payment_similar_communications(self): + def create_payment_line(amount, memo, partner): + payment = self.env['account.payment'].create({ + 'amount': amount, + 'payment_type': 'inbound', + 'partner_type': 'customer', + 'partner_id': partner.id, + 'ref': memo, + 'destination_account_id': self.company_data['default_account_receivable'].id, + }) + payment.action_post() + + return payment.line_ids.filtered(lambda x: x.account_id.user_type_id.type not in {'receivable', 'payable'}) + + payment_partner = self.env['res.partner'].create({ + 'name': "Bernard Gagnant", + }) + + self.rule_1.match_partner_ids = [(6, 0, payment_partner.ids)] + + pmt_line_1 = create_payment_line(500, 'a1b2c3', payment_partner) + pmt_line_2 = create_payment_line(500, 'a1b2c3', payment_partner) + pmt_line_3 = create_payment_line(500, 'd1e2f3', payment_partner) + + self.bank_line_1.write({ + 'amount': 1000, + 'payment_ref': 'a1b2c3', + 'partner_id': payment_partner.id, + }) + self.bank_line_2.unlink() + self.rule_1.match_total_amount = False + + self._check_statement_matching(self.rule_1, { + self.bank_line_1.id: {'aml_ids': (pmt_line_1 + pmt_line_2).ids, 'model': self.rule_1, 'partner': payment_partner}, + }, statements=self.bank_line_1.statement_id) |
