xpathodooqwebodoo-15

Odoo DIN5008 append or change information_block via XPATH


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?


Solution

  • 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>