From f5b4e6131471dcde49a3eb1cad6e7e0f2e246a1e Mon Sep 17 00:00:00 2001 From: moerradi Date: Mon, 18 Sep 2023 16:10:37 +0100 Subject: [PATCH] [FIX] l10n_latam_check: Prevent Multiple Uses of Same Third-Party Check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit there is a loophole that allows the same third-party check to be used for multiple outbound payments. This issue causes data inconsistencies and disrupts the expected behavior of the financial workflow, thereby undermining the integrity of the accounting processes. In order to address it a constraint was introduced on the l10n_latam_check_id field. This constraint is triggered whenever a payment transaction involves the use of 'out_third_party_checks' as the payment method. The system now conducts a search to identify any pre-existing payments that might be using the same third-party check. If a duplicate use of a check is detected, a ValidationError is promptly raised, effectively blocking the transaction. Task-3503556 closes odoo/odoo#136202 X-original-commit: 462614774e0134b805a87e45c7327f7359736bee Signed-off-by: de Wouters de Bouchout Jean-BenoƮt (jbw) Signed-off-by: Mohamed Erradi (moer) --- addons/l10n_latam_check/models/account_payment.py | 14 ++++++++++++++ .../tests/test_third_party_checks.py | 6 +++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/addons/l10n_latam_check/models/account_payment.py b/addons/l10n_latam_check/models/account_payment.py index a79bbdc4d7c..fe1addfe8c1 100644 --- a/addons/l10n_latam_check/models/account_payment.py +++ b/addons/l10n_latam_check/models/account_payment.py @@ -334,3 +334,17 @@ class AccountPayment(models.Model): default_l10n_latam_check_id=rec.l10n_latam_check_id, ))._create_paired_internal_transfer_payment() super(AccountPayment, self - third_party_checks)._create_paired_internal_transfer_payment() + + @api.constrains('l10n_latam_check_id') + def _check_l10n_latam_check_id(self): + if self.filtered(lambda x: x.payment_method_line_id.code == 'out_third_party_checks'): + payments = self.env['account.payment'].search_count([ + ('l10n_latam_check_id', 'in', self.l10n_latam_check_id.ids), + ('payment_type', '=', 'outbound'), + ('journal_id', 'in', self.journal_id.ids), + ('id', 'not in', self.ids)], + limit=1) + if payments: + raise ValidationError(_( + "The check(s) '%s' is already used on another payment. Please select another check or " + "deselect the check on this payment.", self.l10n_latam_check_id.mapped('display_name'))) diff --git a/addons/l10n_latam_check/tests/test_third_party_checks.py b/addons/l10n_latam_check/tests/test_third_party_checks.py index 4f7c34fd08b..3ca1f41460a 100644 --- a/addons/l10n_latam_check/tests/test_third_party_checks.py +++ b/addons/l10n_latam_check/tests/test_third_party_checks.py @@ -65,7 +65,7 @@ class TestThirdChecks(L10nLatamCheckTest): delivery.action_post() self.assertFalse(check.l10n_latam_check_current_journal_id, 'Current journal was not computed properly on delivery') # check dont delivery twice - with self.assertRaisesRegex(ValidationError, "it seems it has been moved by another payment"), self.cr.savepoint(): + with self.assertRaisesRegex(ValidationError, "is already used on another payment"), self.cr.savepoint(): self.env['account.payment'].create(vals).action_post() # Check Return / Rejection @@ -97,7 +97,7 @@ class TestThirdChecks(L10nLatamCheckTest): customer_return.action_post() self.assertFalse(check.l10n_latam_check_current_journal_id, 'Current journal was not computed properly on customer return') # check dont claim twice - with self.assertRaisesRegex(ValidationError, "it seems it has been moved by another payment"), self.cr.savepoint(): + with self.assertRaisesRegex(ValidationError, "is already used on another payment"), self.cr.savepoint(): self.env['account.payment'].create(vals).action_post() operations = self.env['account.payment'].search([('l10n_latam_check_id', '=', check.id), ('state', '=', 'posted')], order="date desc, id desc") @@ -147,7 +147,7 @@ class TestThirdChecks(L10nLatamCheckTest): customer_return.action_post() self.assertFalse(check.l10n_latam_check_current_journal_id, 'Current journal was not computed properly on customer return') # check dont return twice - with self.assertRaisesRegex(ValidationError, "it seems it has been moved by another payment"), self.cr.savepoint(): + with self.assertRaisesRegex(ValidationError, "is already used on another payment"), self.cr.savepoint(): self.env['account.payment'].create(vals).action_post() operations = self.env['account.payment'].search([('l10n_latam_check_id', '=', check.id), ('state', '=', 'posted')], order="date desc, id desc")