I'm in a similar situation like:
Odoo DIN5008 append or change information_block
I'd like to add some fields (e.g. the customer number) to the DIN5008 information_block
in quotation and invoice PDF reports, but I'd like to do it via QWeb inheritance only, i.e. without patching the python code. However, I cannot seem to get to the information_block
via XPATH at all, neither via <xpath expr="//t[@t-foreach='template_data']" position="after">
(as taken from the source template) nor via <xpath expr="//div[@class='information_block'] position=after>
(as taken from the code that's been rendered to the client).
I assume this is due to the template being a different file than what I can reach via inheriting from report_saleorder_document
.
I can't figure out how to inherit from external_layout_din5008
, and even if I figured that out, how would I differentiate the document type that's currently rendered?
You can use the inherit_id
template attribute, used to alter existing templates in-place.
Example:
<template id="external_layout_din5008" inherit_id="l10n_de.external_layout_din5008">
<xpath expr="//t[@t-foreach='template_data']" position="after">
<tr><td>Mobile:</td><td><t t-esc="o.partner_id.mobile"/></td></tr>
</xpath>
</template>
You can use o._name
to get the model name (purchase.order
in the following example) but it it better to customize the information block for each document by defining the following three fields in the model: l10n_de_template_data
, l10n_de_document_title
and l10n_de_addresses
Example:
class PurchaseOrder(models.Model):
_inherit = 'purchase.order'
l10n_de_template_data = fields.Binary(compute='_compute_l10n_de_template_data')
l10n_de_document_title = fields.Char(compute='_compute_l10n_de_document_title')
l10n_de_addresses = fields.Binary(compute='_compute_l10n_de_addresses')
def _compute_l10n_de_template_data(self):
for record in self:
record.l10n_de_template_data = data = []
if record.state == 'draft':
data.append((_("Request for Quotation No."), record.name))
elif record.state in ['sent', 'to approve', 'purchase', 'done']:
data.append((_("Purchase Order No."), record.name))
elif record.state == 'cancel':
data.append((_("Cancelled Purchase Order No."), record.name))
if record.user_id:
data.append((_("Purchase Representative"), record.user_id.name))
if record.partner_ref:
data.append((_("Order Reference"), record.partner_ref))
if record.date_order:
data.append((_("Order Date"), format_date(self.env, record.date_order)))
if record.incoterm_id:
data.append((_("Incoterm"), record.incoterm_id.code))
def _compute_l10n_de_document_title(self):
for record in self:
if record.state in ['draft', 'sent', 'to approve']:
record.l10n_de_document_title = _("Request for Quotation")
elif record.state in ['purchase', 'done']:
record.l10n_de_document_title = _("Purchase Order")
elif record.state == 'cancel':
record.l10n_de_document_title = _("Cancelled Purchase Order")
def _compute_l10n_de_addresses(self):
for record in self:
record.l10n_de_addresses = data = []
if record.dest_address_id:
data.append((_("Shipping Address:"), record.dest_address_id))
elif 'picking_type_id' in record._fields and record.picking_type_id.warehouse_id:
data.append((_("Shipping Address:"), record.picking_type_id.warehouse_id.partner_id))
Example taken from l10n_de_purchase
Update:
The information bloc values come from the l10n_de_template_data
field and in the compute method you can see that it just appends a tuple holding the field label and value to a list so you can use the t-esc
directive to append new values to l10n_de_template_data
field before calling the external layout.
Example:
<?xml version="1.0"?>
<data inherit_id="sale.report_saleorder_document">
<xpath expr="//th[@name='th_taxes']" position="replace" />
<xpath expr="//td[@name='td_taxes']" position="replace" />
<xpath expr="//t[@t-call='web.external_layout']" position="before">
<t t-esc="doc.l10n_de_template_data.append(('Mobile', doc.partner_id.mobile))"/>
</xpath>
</data>