diff --git a/account_payment_mode/models/account_journal.py b/account_payment_mode/models/account_journal.py index 8941a9cd010f..c4f8ba963843 100644 --- a/account_payment_mode/models/account_journal.py +++ b/account_payment_mode/models/account_journal.py @@ -4,6 +4,7 @@ from odoo import _, api, models from odoo.exceptions import ValidationError +from odoo.tools import config class AccountJournal(models.Model): @@ -28,7 +29,38 @@ def _default_inbound_payment_methods(self): ("code", "not in", unique_codes), # filter out unique codes ] ) - return all_in + # 'electronic' are linked to a single journal per company per provider. + if config["test_enable"]: + # This is a hack to be able to test the electronic payment methods, + # as they are defined when you install the account_payment module, + # but the restrictions on electronic codes live in the account module. + electronic_codes = self.env.context.get("electronic_code", False) + else: + electronic_codes = tuple( + code + for code, info in method_info.items() + if info.get("mode") == "electronic" + ) + electronic_methods = self.env["account.payment.method"].search( + [ + ("payment_type", "=", "inbound"), + ("code", "in", electronic_codes), # filter out unique codes + ] + ) + electronic_method_lines_already_assigned = self.env[ + "account.payment.method.line" + ].search( + [ + ("payment_method_id", "in", electronic_methods.ids), + ("journal_id.company_id", "=", self.company_id.id), + ("journal_id", "!=", self.id), + ] + ) + electronic_methods_already_assigned = ( + electronic_method_lines_already_assigned.mapped("payment_method_id") + ) + res = all_in - electronic_methods_already_assigned + return res @api.constrains("company_id") def company_id_account_payment_mode_constrains(self): diff --git a/account_payment_mode/tests/test_account_payment_mode.py b/account_payment_mode/tests/test_account_payment_mode.py index db23e176e6f3..7292408ecffa 100644 --- a/account_payment_mode/tests/test_account_payment_mode.py +++ b/account_payment_mode/tests/test_account_payment_mode.py @@ -131,3 +131,49 @@ def test_payment_mode_company_consistency_create(self): "fixed_journal_id": self.journal_c1.id, } ) + + def test_electronic_payment_methods_proposed_once(self): + """Test that we cannot assign the same payment method when it's electronic + to two journals of the same company.""" + method = ( + self.env["account.payment.method"] + .sudo() + .create( + { + "name": "Electornic method", + "code": "electronic_method", + "payment_type": "inbound", + } + ) + ) + # We call with context variable electronic_code because by default because + # we want to force that this payment method is considered electronic during testing, + # even when it's not. The electronic mode is defaulted in the account_payment + # module, but the restrictions for this mode live in the account module. + journal_model = self.journal_model.with_context( + electronic_code="electronic_method" + ) + journal_c1_1 = journal_model.create( + { + "name": "J1_1", + "code": "J1_1", + "type": "bank", + "company_id": self.company.id, + } + ) + self.assertIn( + method, + journal_c1_1.inbound_payment_method_line_ids.mapped("payment_method_id"), + ) + journal_c1_2 = journal_model.create( + { + "name": "J1_2", + "code": "J1_2", + "type": "bank", + "company_id": self.company.id, + } + ) + self.assertNotIn( + method, + journal_c1_2.inbound_payment_method_line_ids.mapped("payment_method_id"), + )