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>