[IMP] account: Allow custom invoice PDF template/values for localizations in send & print

The logic of the send & print wizard is to generate all EDI documents and PDF at the same time
to ensure the consistency between all business documents.
In some localizations, we need custom references to the generated EDI documents inside the PDF.
The problem is the current PDF engine is not designed to easily extend such PDF template and provide
custom values to render it. Also, you absolutely need an ir.actions.report to use the PDF rendering.
To make such customizations less paintful, this commit adds a hook on the send & print wizard allowing
to provide a custom template inheriting the standard one and custom values for the rendering.

Task: 3069324
Part-of: odoo/odoo#128395
This commit is contained in:
Laurent Smet
2023-07-20 20:53:06 +02:00
parent 1de5c98c3a
commit fc0464427f
9 changed files with 49 additions and 87 deletions
+1 -1
View File
@@ -4586,7 +4586,7 @@ class AccountMove(models.Model):
""" This method need to be inherit by the localizations if they want to print a custom invoice report instead of
the default one. For example please review the l10n_ar module """
self.ensure_one()
return 'account.report_invoice_document'
return self._context.get('force_report_invoice_template') or 'account.report_invoice_document'
def _is_downpayment(self):
''' Return true if the invoice is a downpayment.
@@ -755,3 +755,19 @@ class TestAccountMoveSend(TestAccountMoveSendCommon):
# The PDF is generated even in case of error.
self.assertTrue(invoice.invoice_pdf_report_id)
def test_get_invoice_pdf_report_to_render(self):
invoice = self.init_invoice("out_invoice", amounts=[1000], post=True)
_get_name_invoice_report = invoice._get_name_invoice_report
wizard = self.create_send_and_print(invoice)
def get_invoice_pdf_report_to_render(record, *args, **kwargs):
return 'account.report_invoice_document', {}
def get_name_invoice_report(record, *args, **kwargs):
self.assertEqual(record._context.get('force_report_invoice_template'), 'account.report_invoice_document')
return _get_name_invoice_report(*args, **kwargs)
with patch.object(type(wizard), '_get_invoice_pdf_report_to_render', get_invoice_pdf_report_to_render), \
patch.object(type(invoice), '_get_name_invoice_report', get_name_invoice_report):
wizard.action_send_and_print(allow_fallback_pdf=True)
+3 -9
View File
@@ -426,20 +426,14 @@
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-set="lang" t-value="o.partner_id.lang"/>
<t t-if="o._get_name_invoice_report() == 'account.report_invoice_document'"
t-call="account.report_invoice_document" t-lang="lang"/>
<t t-call="{{o._get_name_invoice_report()}}" t-lang="lang"/>
</t>
</t>
</template>
<template id="report_invoice_with_payments">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-set="lang" t-value="o.partner_id.lang"/>
<t t-set="print_with_payments" t-value="True"/>
<t t-if="o._get_name_invoice_report() == 'account.report_invoice_document'"
t-call="account.report_invoice_document" t-lang="lang"/>
</t>
<t t-call="account.report_invoice">
<t t-set="print_with_payments" t-value="True"/>
</t>
</template>
+29 -1
View File
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
from unittest.mock import patch
from odoo import _, api, fields, models, modules, tools, Command
from odoo.exceptions import UserError
@@ -306,6 +307,10 @@ class AccountMoveSend(models.Model):
"""
self.ensure_one()
def _get_invoice_pdf_report_to_render(self, invoice, invoice_data):
self.ensure_one()
return None, {}
def _prepare_invoice_pdf_report(self, invoice, invoice_data):
""" Prepare the pdf report for the invoice passed as parameter.
@@ -317,7 +322,30 @@ class AccountMoveSend(models.Model):
if invoice.invoice_pdf_report_id:
return
content, _report_format = self.env['ir.actions.report']._render('account.account_invoices', invoice.ids)
# Render the invoice PDF but allow to set a custom report_name and custom values.
# That way, all invoice reports are separated from the main one but don't need an
# extra report every time.
IrActionsReport = type(self.env['ir.actions.report'])
_render_template = IrActionsReport._render_template
inv_report, inv_report_values = self._get_invoice_pdf_report_to_render(invoice, invoice_data)
def render_template(records, template, values=None):
return _render_template(
records,
template,
values={
**(values or {}),
**inv_report_values,
},
)
with patch.object(IrActionsReport, '_render_template', side_effect=render_template, autospec=True):
content, _report_format = self.env['ir.actions.report']\
.with_context(force_report_invoice_template=inv_report)\
._render(
'account.account_invoices',
invoice.ids,
)
invoice_data['pdf_attachment_values'] = {
'raw': content,
-16
View File
@@ -286,20 +286,4 @@
<attribute name="t-if">not o._l10n_ar_include_vat()</attribute>
</xpath>
</template>
<!-- FIXME: Temp fix to allow fetching invoice_documemt in Studio Reports with localisation -->
<template id="report_invoice" inherit_id="account.report_invoice">
<xpath expr='//t[@t-call="account.report_invoice_document"]' position="after">
<t t-if="o._get_name_invoice_report() == 'l10n_ar.report_invoice_document'"
t-call="l10n_ar.report_invoice_document" t-lang="lang"/>
</xpath>
</template>
<template id="report_invoice_with_payments" inherit_id="account.report_invoice_with_payments">
<xpath expr='//t[@t-call="account.report_invoice_document"]' position="after">
<t t-if="o._get_name_invoice_report() == 'l10n_ar.report_invoice_document'"
t-call="l10n_ar.report_invoice_document" t-lang="lang"/>
</xpath>
</template>
</odoo>
-14
View File
@@ -1,19 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="report_invoice" inherit_id="account.report_invoice">
<xpath expr='//t[@t-call="account.report_invoice_document"]' position="after">
<t t-if="o._get_name_invoice_report() == 'l10n_au.report_invoice_document'"
t-call="l10n_au.report_invoice_document" t-lang="lang"/>
</xpath>
</template>
<template id="report_invoice_with_payments" inherit_id="account.report_invoice_with_payments">
<xpath expr='//t[@t-call="account.report_invoice_document"]' position="after">
<t t-if="o._get_name_invoice_report() == 'l10n_au.report_invoice_document'"
t-call="l10n_au.report_invoice_document" t-lang="lang"/>
</xpath>
</template>
<template id="report_invoice_document" inherit_id="account.report_invoice_document" primary="True">
<xpath expr="//div[hasclass('page')]/h2" position="replace">
<h2>
-16
View File
@@ -221,20 +221,4 @@
</xpath>
</template>
<!-- FIXME: Temp fix to allow fetching invoice_documemt in Studio Reports with localisation -->
<template id="report_invoice" inherit_id="account.report_invoice">
<xpath expr='//t[@t-call="account.report_invoice_document"]' position="after">
<t t-if="o._get_name_invoice_report() == 'l10n_cl.report_invoice_document'"
t-call="l10n_cl.report_invoice_document" t-lang="lang"/>
</xpath>
</template>
<template id="report_invoice_with_payments" inherit_id="account.report_invoice_with_payments">
<xpath expr='//t[@t-call="account.report_invoice_document"]' position="after">
<t t-if="o._get_name_invoice_report() == 'l10n_cl.report_invoice_document'"
t-call="l10n_cl.report_invoice_document" t-lang="lang"/>
</xpath>
</template>
</odoo>
@@ -1,20 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="report_invoice" inherit_id="account.report_invoice">
<xpath expr='//t[@t-call="account.report_invoice_document"]' position="after">
<t t-if="o._get_name_invoice_report() == 'l10n_gcc_invoice.arabic_english_invoice'"
t-call="l10n_gcc_invoice.arabic_english_invoice" t-lang="lang"/>
</xpath>
</template>
<template id="report_invoice_with_payments" inherit_id="account.report_invoice_with_payments">
<xpath expr='//t[@t-call="account.report_invoice_document"]' position="after">
<t t-if="o._get_name_invoice_report() == 'l10n_gcc_invoice.arabic_english_invoice'"
t-call="l10n_gcc_invoice.arabic_english_invoice" t-lang="lang"/>
</xpath>
</template>
<template id="arabic_english_invoice">
<t t-call="web.external_layout">
<t t-set="o" t-value="o.with_context(lang=lang)" />
-15
View File
@@ -28,21 +28,6 @@
</t>
</template>
<template id="report_invoice" inherit_id="account.report_invoice">
<xpath expr='//t[@t-call="account.report_invoice_document"]' position="after">
<t t-if="o._get_name_invoice_report() == 'l10n_th.report_invoice_document'"
t-call="l10n_th.report_invoice_document" t-lang="lang"/>
</xpath>
</template>
<template id="report_invoice_with_payments" inherit_id="account.report_invoice_with_payments">
<xpath expr='//t[@t-call="account.report_invoice_document"]' position="after">
<t t-if="o._get_name_invoice_report() == 'l10n_th.report_invoice_document'"
t-call="l10n_th.report_invoice_document" t-lang="lang"/>
</xpath>
</template>
<record id="action_report_commercial_invoice" model="ir.actions.report">
<field name="name">Commercial Invoice</field>
<field name="model">account.move</field>