From d96260f590ceef1eacc408b1a7491f91aee5bb2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sun, 14 Sep 2025 12:23:08 +0200 Subject: [PATCH] Add party's address to the SEPA mandate Use explicit address selection to display on the SEPA mandate instead of the default first address. Closes #14229 --- doc/migration.rst | 20 +++++++++++++ modules/account_payment_sepa/CHANGELOG | 1 + modules/account_payment_sepa/mandate.fodt | 18 ++++++------ modules/account_payment_sepa/payment.py | 28 ++++++++++++++++--- .../tests/scenario_account_payment_sepa.rst | 6 ++++ .../account_payment_sepa/tests/test_module.py | 1 + .../view/mandate_form.xml | 5 ++++ .../view/mandate_list.xml | 1 + 8 files changed, 67 insertions(+), 13 deletions(-) diff --git a/doc/migration.rst b/doc/migration.rst index f3d736f872..32eec2719f 100644 --- a/doc/migration.rst +++ b/doc/migration.rst @@ -14,6 +14,26 @@ a database from another series. .. warning:: You cannot skip more than 2 series ending with ``.0``. +7.8 +--- + +After +~~~~~ + +* If ``account_payment_sepa`` module is activated, fill the address of + validated mandates with default value with the ``trytond-console``: + + .. code-block:: python + + Mandate = pool.get('account.payment.sepa.mandate') + mandates = Mandate.search([ + ('state', '=', 'validated'), + ('address', '=', None), + ]) + for mandate in mandates: + mandate.address = mandate.on_change_party() + Mandate.save(mandates) + 7.6 --- diff --git a/modules/account_payment_sepa/CHANGELOG b/modules/account_payment_sepa/CHANGELOG index f35b458774..6a88e64a96 100644 --- a/modules/account_payment_sepa/CHANGELOG +++ b/modules/account_payment_sepa/CHANGELOG @@ -1,3 +1,4 @@ +* Add party's address to the mandate Version 7.6.0 - 2025-04-28 -------------------------- diff --git a/modules/account_payment_sepa/mandate.fodt b/modules/account_payment_sepa/mandate.fodt index 8e567ff9e8..2b81f9db5a 100644 --- a/modules/account_payment_sepa/mandate.fodt +++ b/modules/account_payment_sepa/mandate.fodt @@ -753,7 +753,7 @@ Your address - <mandate.party.addresses[0].street if mandate.party.addresses else ''> + <mandate.address.street if mandate.address else ''> @@ -771,10 +771,10 @@ - <mandate.party.addresses[0].postal_code if mandate.party.addresses else ''> + <mandate.address.postal_code if mandate.address else ''> - <mandate.party.addresses[0].city if mandate.party.addresses else ''> + <mandate.address.city if mandate.address else ''> @@ -793,7 +793,7 @@ - <mandate.party.addresses[0].country.rec_name if mandate.party.addresses and mandate.party.addresses[0].country else ''> + <mandate.address.country.rec_name if mandate.address and mandate.address.country else ''> @@ -883,7 +883,7 @@ - <mandate.company.party.addresses[0].street if mandate.company.party.addresses else ''> + <mandate.company_address.street if mandate.company_address else ''> @@ -901,10 +901,10 @@ - <mandate.company.party.addresses[0].postal_code if mandate.company.party.addresses else ''> + <mandate.company_address.postal_code if mandate.company_address else ''> - <mandate.company.party.addresses[0].city if mandate.company.party.addresses else ''> + <mandate.company_address.city if mandate.company_address else ''> @@ -923,7 +923,7 @@ - <mandate.company.party.addresses[0].country.rec_name if mandate.company.party.addresses and mandate.company.party.addresses[0].country else ''> + <mandate.company_address.country.rec_name if mandate.company_address and mandate.company_address.country else ''> @@ -1018,4 +1018,4 @@ </for> - \ No newline at end of file + diff --git a/modules/account_payment_sepa/payment.py b/modules/account_payment_sepa/payment.py index 5e9902ef57..81ebcef03f 100644 --- a/modules/account_payment_sepa/payment.py +++ b/modules/account_payment_sepa/payment.py @@ -26,7 +26,8 @@ from trytond.pool import Pool, PoolMeta from trytond.pyson import Eval, If from trytond.report import Report from trytond.tools import ( - grouped_slice, is_full_text, lstrip_wildcard, reduce_ids, sortable_values) + cached_property, grouped_slice, is_full_text, lstrip_wildcard, reduce_ids, + sortable_values) from trytond.transaction import Transaction from .sepa_handler import CAMT054 @@ -503,12 +504,19 @@ class Mandate(Workflow, ModelSQL, ModelView): 'company': Eval('company', -1), }, depends={'company'}) + address = fields.Many2One( + 'party.address', "Address", + domain=[ + ('party', '=', Eval('party', -1)), + ], + states={ + 'readonly': Eval('state').in_(['validated', 'cancelled']), + 'required': Eval('state') == 'validated', + }) account_number = fields.Many2One('bank.account.number', 'Account Number', ondelete='RESTRICT', states={ - 'readonly': ( - Eval('state').in_(['validated', 'cancelled']) - | ~Eval('party')), + 'readonly': Eval('state').in_(['validated', 'cancelled']), 'required': Eval('state') == 'validated', }, domain=[ @@ -603,6 +611,14 @@ class Mandate(Workflow, ModelSQL, ModelView): t, (t.state, Index.Equality(cardinality='low')), where=t.state.in_(['draft', 'requested']))) + @fields.depends('party', '_parent_party.id') + def on_change_party(self): + if self.party and self.party.id >= 0: + self.address = self.party.address_get() + else: + self.address = None + self.account_number = None + @staticmethod def default_company(): return Transaction().context.get('company') @@ -612,6 +628,10 @@ class Mandate(Workflow, ModelSQL, ModelView): self.identification_readonly = self.default_identification_readonly( company=self.company.id if self.company else None) + @cached_property + def company_address(self): + return self.company.party.address_get() + @staticmethod def default_type(): return 'recurrent' diff --git a/modules/account_payment_sepa/tests/scenario_account_payment_sepa.rst b/modules/account_payment_sepa/tests/scenario_account_payment_sepa.rst index bc08ec86f2..4c3b3b8d56 100644 --- a/modules/account_payment_sepa/tests/scenario_account_payment_sepa.rst +++ b/modules/account_payment_sepa/tests/scenario_account_payment_sepa.rst @@ -82,6 +82,12 @@ Create mandate:: >>> mandate.identification = 'MANDATE' >>> mandate.type = 'recurrent' >>> mandate.click('request') + >>> mandate.state + 'requested' + + >>> mandate_report = Report('account.payment.sepa.mandate') + >>> _ = mandate_report.execute([mandate]) + >>> mandate.signature_date = today >>> mandate.click('validate_mandate') >>> mandate.state diff --git a/modules/account_payment_sepa/tests/test_module.py b/modules/account_payment_sepa/tests/test_module.py index e01593b97a..91e9d1e2d0 100644 --- a/modules/account_payment_sepa/tests/test_module.py +++ b/modules/account_payment_sepa/tests/test_module.py @@ -74,6 +74,7 @@ def setup_mandate(company, customer, account): return Mandate.create([{ 'company': company, 'party': customer, + 'address': customer.addresses[0], 'account_number': account.numbers[0], 'identification': 'MANDATE', 'type': 'recurrent', diff --git a/modules/account_payment_sepa/view/mandate_form.xml b/modules/account_payment_sepa/view/mandate_form.xml index 16dc3fe46c..cf930adea7 100644 --- a/modules/account_payment_sepa/view/mandate_form.xml +++ b/modules/account_payment_sepa/view/mandate_form.xml @@ -4,8 +4,13 @@ this repository contains the full copyright notices and license terms. -->