summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoroco-odoo <oco@odoo.com>2021-05-03 15:15:43 +0000
committeroco-odoo <oco@odoo.com>2021-05-03 15:52:49 +0000
commitb5800c9d2088df2bb9c4fbe0fed91c7ef24299c5 (patch)
treee080c5c96ebe0ff3f7eb68c722384a4aec86ed31
parent2480e9593808126ade2537cc2ae40b85080ba441 (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.py9
-rw-r--r--addons/account/tests/test_reconciliation_matching_rules.py36
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)