From 5181591ed733404bdc4a36f3fcc879a6cf108e2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 4 Jan 2024 18:55:06 +0100 Subject: [PATCH] Use template substitution for company header/footer Closes #12699 --- modules/account_dunning_email/email.html | 4 +- modules/account_dunning_letter/letter.fodt | 4 +- modules/account_invoice/invoice.fodt | 4 +- modules/account_payment_sepa/mandate.fodt | 6 +-- modules/account_statement/statement.fodt | 4 +- modules/company/CHANGELOG | 1 + modules/company/company.py | 46 ++++++++++++++++++- modules/company/letter.fodt | 6 +-- modules/company/tests/test_module.py | 24 ++++++++++ modules/party_siret/__init__.py | 5 +- modules/party_siret/company.py | 21 +++++++++ modules/party_siret/tryton.cfg | 2 + modules/purchase/purchase.fodt | 6 +-- .../purchase_request_quotation/quotation.fodt | 4 +- modules/sale/sale.fodt | 6 +-- .../customer_return_restocking_list.fodt | 4 +- modules/stock/delivery_note.fodt | 4 +- modules/stock/internal_shipment.fodt | 4 +- modules/stock/picking_list.fodt | 4 +- modules/stock/supplier_restocking_list.fodt | 4 +- 20 files changed, 128 insertions(+), 35 deletions(-) create mode 100644 modules/party_siret/company.py diff --git a/modules/account_dunning_email/email.html b/modules/account_dunning_email/email.html index 4b003185b1..9f7cc41384 100644 --- a/modules/account_dunning_email/email.html +++ b/modules/account_dunning_email/email.html @@ -8,7 +8,7 @@

${company.rec_name}

-

${line}

+

${line}

Reminder Notice

@@ -74,7 +74,7 @@ diff --git a/modules/account_dunning_letter/letter.fodt b/modules/account_dunning_letter/letter.fodt index b119647e44..854d3668b2 100644 --- a/modules/account_dunning_letter/letter.fodt +++ b/modules/account_dunning_letter/letter.fodt @@ -518,7 +518,7 @@ <if test="company and company.header"> - <for each="line in company.header.split('\n')"> + <for each="line in company.header_used.split('\n')"> <line> </for> </if> @@ -526,7 +526,7 @@ <if test="company and company.footer"> - <for each="line in company.footer.split('\n')"> + <for each="line in company.footer_used.split('\n')"> <line> </for> </if> diff --git a/modules/account_invoice/invoice.fodt b/modules/account_invoice/invoice.fodt index 6b31af359d..53036bad04 100644 --- a/modules/account_invoice/invoice.fodt +++ b/modules/account_invoice/invoice.fodt @@ -710,7 +710,7 @@ <if test="invoice.company.header"> - <for each="line in invoice.company.header.split('\n')"> + <for each="line in invoice.company.header_used.split('\n')"> <line> </for> </if> @@ -718,7 +718,7 @@ <if test="invoice.company.footer"> - <for each="line in invoice.company.footer.split('\n')"> + <for each="line in invoice.company.footer_used.split('\n')"> <line> </for> </if> diff --git a/modules/account_payment_sepa/mandate.fodt b/modules/account_payment_sepa/mandate.fodt index ad2b90f683..cfca81209f 100644 --- a/modules/account_payment_sepa/mandate.fodt +++ b/modules/account_payment_sepa/mandate.fodt @@ -560,7 +560,7 @@ <if test="company and company.header"> - <for each="line in company.header.split('\n')"> + <for each="line in company.header_used.split('\n')"> <line> </for> </if> @@ -568,7 +568,7 @@ <if test="company and company.footer"> - <for each="line in company.footer.split('\n')"> + <for each="line in company.footer_used.split('\n')"> <line> </for> </if> @@ -948,4 +948,4 @@ </for> - \ No newline at end of file + diff --git a/modules/account_statement/statement.fodt b/modules/account_statement/statement.fodt index 7c98edc62b..35b49ecdea 100644 --- a/modules/account_statement/statement.fodt +++ b/modules/account_statement/statement.fodt @@ -444,7 +444,7 @@ <if test="company and company.header"> - <for each="line in company.header.split('\n')"> + <for each="line in company.header_used.split('\n')"> <line> </for> </if> @@ -452,7 +452,7 @@ <if test="company and company.footer"> - <for each="line in company.footer.split('\n')"> + <for each="line in company.footer_used.split('\n')"> <line> </for> </if> diff --git a/modules/company/CHANGELOG b/modules/company/CHANGELOG index 5ae3e74806..3b57a92340 100644 --- a/modules/company/CHANGELOG +++ b/modules/company/CHANGELOG @@ -1,3 +1,4 @@ +* Use template substitution for company header/footer Version 7.0.0 - 2023-10-30 -------------------------- diff --git a/modules/company/company.py b/modules/company/company.py index 241971d704..2a0bc7e752 100644 --- a/modules/company/company.py +++ b/modules/company/company.py @@ -1,5 +1,8 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. + +from string import Template + from trytond.model import ModelSQL, ModelView, fields from trytond.pool import Pool from trytond.pyson import Eval, If @@ -13,6 +16,18 @@ TIMEZONES += [(None, '')] Transaction.cache_keys.update({'company', 'employee'}) +_SUBSTITUTION_HELP = ( + "The following placeholders can be used:\n" + "- ${name}\n" + "- ${phone}\n" + "- ${mobile}\n" + "- ${fax}\n" + "- ${email}\n" + "- ${website}\n" + "- ${address}\n" + "- ${tax_identifier}\n" + ) + class Company(ModelSQL, ModelView): 'Company' @@ -20,9 +35,11 @@ class Company(ModelSQL, ModelView): party = fields.Many2One('party.party', 'Party', required=True, ondelete='CASCADE') header = fields.Text( - 'Header', help="The text to display on report headers.") + 'Header', + help="The text to display on report headers.\n" + _SUBSTITUTION_HELP) footer = fields.Text( - 'Footer', help="The text to display on report footers.") + 'Footer', + help="The text to display on report footers.\n" + _SUBSTITUTION_HELP) currency = fields.Many2One('currency.currency', 'Currency', required=True, help="The main currency for the company.") timezone = fields.Selection(TIMEZONES, 'Timezone', translate=False, @@ -30,6 +47,31 @@ class Company(ModelSQL, ModelView): employees = fields.One2Many('company.employee', 'company', 'Employees', help="Add employees to the company.") + @property + def header_used(self): + return Template(self.header or '').safe_substitute(self._substitutions) + + @property + def footer_used(self): + return Template(self.footer or '').safe_substitute(self._substitutions) + + @property + def _substitutions(self): + address = self.party.address_get() + tax_identifier = self.party.tax_identifier + return { + 'name': self.party.name, + 'phone': self.party.phone, + 'mobile': self.party.mobile, + 'fax': self.party.fax, + 'email': self.party.email, + 'website': self.party.website, + 'address': ( + ' '.join(address.full_address.splitlines()) + if address else ''), + 'tax_identifier': tax_identifier.code if tax_identifier else '', + } + def get_rec_name(self, name): return self.party.rec_name diff --git a/modules/company/letter.fodt b/modules/company/letter.fodt index 476ec8ab4c..d784561190 100644 --- a/modules/company/letter.fodt +++ b/modules/company/letter.fodt @@ -350,7 +350,7 @@ <if test="user.company.header"> - <for each="line in user.company.header.split('\n')"> + <for each="line in user.company.header_used.split('\n')"> <line> </for> </if> @@ -358,7 +358,7 @@ <if test="user.company.footer"> - <for each="line in user.company.footer.split('\n')"> + <for each="line in user.company.footer_used.split('\n')"> <line> </for> </if> @@ -391,4 +391,4 @@ </for> - \ No newline at end of file + diff --git a/modules/company/tests/test_module.py b/modules/company/tests/test_module.py index 9f9a4b3e68..abcc5cd767 100644 --- a/modules/company/tests/test_module.py +++ b/modules/company/tests/test_module.py @@ -305,5 +305,29 @@ class CompanyTestCase( root = User(0) self.assertEqual(root.employee, employee) + @with_transaction() + def test_company_header(self): + "Test company header" + company = create_company() + company.party.email = 'company@example.com' + company.party.save() + company.header = "${name} - ${email}" + company.save() + + self.assertEqual( + company.header_used, "Dunder Mifflin - company@example.com") + + @with_transaction() + def test_company_footer(self): + "Test company footer" + company = create_company() + company.party.email = 'company@example.com' + company.party.save() + company.footer = "${name} - ${email}" + company.save() + + self.assertEqual( + company.footer_used, "Dunder Mifflin - company@example.com") + del ModuleTestCase diff --git a/modules/party_siret/__init__.py b/modules/party_siret/__init__.py index 40283c69a9..d389b3fadd 100644 --- a/modules/party_siret/__init__.py +++ b/modules/party_siret/__init__.py @@ -3,7 +3,7 @@ from trytond.pool import Pool -from . import address, party +from . import address, company, party def register(): @@ -11,3 +11,6 @@ def register(): party.Party, address.Address, module='party_siret', type_='model') + Pool.register( + company.Company, + module='party_siret', type_='model', depends=['company']) diff --git a/modules/party_siret/company.py b/modules/party_siret/company.py new file mode 100644 index 0000000000..7930ec35eb --- /dev/null +++ b/modules/party_siret/company.py @@ -0,0 +1,21 @@ +# This file is part of Tryton. The COPYRIGHT file at the top level of +# this repository contains the full copyright notices and license terms. + +from trytond.pool import PoolMeta + + +class Company(metaclass=PoolMeta): + __name__ = 'company.company' + + @classmethod + def __setup__(cls): + super().__setup__() + cls.header.help += "- ${siren}\n" + cls.footer.help += "- ${siren}\n" + + @property + def _substitutions(self): + substitutions = super()._substitutions + siren = self.party.siren + substitutions['siren'] = siren.value if siren else '' + return substitutions diff --git a/modules/party_siret/tryton.cfg b/modules/party_siret/tryton.cfg index 1390bdb070..bb371f53c5 100644 --- a/modules/party_siret/tryton.cfg +++ b/modules/party_siret/tryton.cfg @@ -3,6 +3,8 @@ version=7.1.0 depends: ir party +extras_depend: + company xml: party.xml address.xml diff --git a/modules/purchase/purchase.fodt b/modules/purchase/purchase.fodt index d0cf2e6dbe..53b2add235 100644 --- a/modules/purchase/purchase.fodt +++ b/modules/purchase/purchase.fodt @@ -600,7 +600,7 @@ <if test="company and company.header"> - <for each="line in company.header.split('\n')"> + <for each="line in company.header_used.split('\n')"> <line> </for> </if> @@ -608,7 +608,7 @@ <if test="company and company.footer"> - <for each="line in company.footer.split('\n')"> + <for each="line in company.footer_used.split('\n')"> <line> </for> </if> @@ -905,4 +905,4 @@ </for> - \ No newline at end of file + diff --git a/modules/purchase_request_quotation/quotation.fodt b/modules/purchase_request_quotation/quotation.fodt index fb70b00d19..c73ae0f5b6 100644 --- a/modules/purchase_request_quotation/quotation.fodt +++ b/modules/purchase_request_quotation/quotation.fodt @@ -599,7 +599,7 @@ <if test="company and company.header"> - <for each="line in company.header.split('\n')"> + <for each="line in company.header_used.split('\n')"> <line> </for> </if> @@ -607,7 +607,7 @@ <if test="company and company.footer"> - <for each="line in company.footer.split('\n')"> + <for each="line in company.footer_used.split('\n')"> <line> </for> </if> diff --git a/modules/sale/sale.fodt b/modules/sale/sale.fodt index 5d7c920be3..e59c16b2ab 100644 --- a/modules/sale/sale.fodt +++ b/modules/sale/sale.fodt @@ -592,7 +592,7 @@ <if test="company and company.header"> - <for each="line in company.header.split('\n')"> + <for each="line in company.header_used.split('\n')"> <line> </for> </if> @@ -600,7 +600,7 @@ <if test="company and company.footer"> - <for each="line in company.footer.split('\n')"> + <for each="line in company.footer_used.split('\n')"> <line> </for> </if> @@ -888,4 +888,4 @@ </for> - \ No newline at end of file + diff --git a/modules/stock/customer_return_restocking_list.fodt b/modules/stock/customer_return_restocking_list.fodt index 1714a26468..45136c0cc6 100644 --- a/modules/stock/customer_return_restocking_list.fodt +++ b/modules/stock/customer_return_restocking_list.fodt @@ -448,7 +448,7 @@ <if test="company and company.header"> - <for each="line in company.header.split('\n')"> + <for each="line in company.header_used.split('\n')"> <line> </for> </if> @@ -456,7 +456,7 @@ <if test="company and company.footer"> - <for each="line in company.footer.split('\n')"> + <for each="line in company.footer_used.split('\n')"> <line> </for> </if> diff --git a/modules/stock/delivery_note.fodt b/modules/stock/delivery_note.fodt index 8d39aa66c3..c6c1552e3e 100644 --- a/modules/stock/delivery_note.fodt +++ b/modules/stock/delivery_note.fodt @@ -445,7 +445,7 @@ <if test="company and company.header"> - <for each="line in company.header.split('\n')"> + <for each="line in company.header_used.split('\n')"> <line> </for> </if> @@ -453,7 +453,7 @@ <if test="company and company.footer"> - <for each="line in company.footer.split('\n')"> + <for each="line in company.footer_used.split('\n')"> <line> </for> </if> diff --git a/modules/stock/internal_shipment.fodt b/modules/stock/internal_shipment.fodt index 5881da7c20..034fc0febd 100644 --- a/modules/stock/internal_shipment.fodt +++ b/modules/stock/internal_shipment.fodt @@ -447,7 +447,7 @@ <if test="company and company.header"> - <for each="line in company.header.split('\n')"> + <for each="line in company.header_used.split('\n')"> <line> </for> </if> @@ -455,7 +455,7 @@ <if test="company and company.footer"> - <for each="line in company.footer.split('\n')"> + <for each="line in company.footer_used.split('\n')"> <line> </for> </if> diff --git a/modules/stock/picking_list.fodt b/modules/stock/picking_list.fodt index 6f3ba6f91c..45bd9526c9 100644 --- a/modules/stock/picking_list.fodt +++ b/modules/stock/picking_list.fodt @@ -444,7 +444,7 @@ <if test="company and company.header"> - <for each="line in company.header.split('\n')"> + <for each="line in company.header_used.split('\n')"> <line> </for> </if> @@ -452,7 +452,7 @@ <if test="company and company.footer"> - <for each="line in company.footer.split('\n')"> + <for each="line in company.footer_used.split('\n')"> <line> </for> </if> diff --git a/modules/stock/supplier_restocking_list.fodt b/modules/stock/supplier_restocking_list.fodt index ba32c77440..56dea21b43 100644 --- a/modules/stock/supplier_restocking_list.fodt +++ b/modules/stock/supplier_restocking_list.fodt @@ -439,7 +439,7 @@ <if test="company and company.header"> - <for each="line in company.header.split('\n')"> + <for each="line in company.header_used.split('\n')"> <line> </for> </if> @@ -447,7 +447,7 @@ <if test="company and company.footer"> - <for each="line in company.footer.split('\n')"> + <for each="line in company.footer_used.split('\n')"> <line> </for> </if>