From 78789cfc2853d247f928a460fbc1be59515c453d Mon Sep 17 00:00:00 2001 From: "John Laterre (jol)" Date: Wed, 3 Aug 2022 13:06:59 +0000 Subject: [PATCH] [FIX] account,base,web: fix "Send & Print" on invoices The purpose of the task is twofold: 1. Remove empty lines in the company address. Until now, the address format was fixed, which could lead to empty lines if one or more field(s) were missing. We are now removing empty fields to avoid that. 2. Make sure the external report layout is configured before generating the PDF. This will ensure that the company data will appear in the file. If no layout is defined, it would not be shown. task-2834517 closes odoo/odoo#100936 X-original-commit: f36bb6acdacaaba26afdd8f62c48fd2c8784d1e1 Signed-off-by: Olivier Colson (oco) Signed-off-by: John Laterre (jol) --- addons/account/models/account_move.py | 9 ++++++++- addons/web/models/base_document_layout.py | 8 ++++++++ addons/web/tests/test_base_document_layout.py | 13 +++++++++++++ odoo/addons/base/models/ir_actions_report.py | 16 +++++++++------- 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 9947816b8b1..97d24fb7048 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -3446,8 +3446,10 @@ class AccountMove(models.Model): default_email_layout_xmlid="mail.mail_notification_layout_with_responsible_signature", model_description=self.with_context(lang=lang).type_name, force_email=True, + active_ids=self.ids, ) - return { + + report_action = { 'name': _('Send Invoice'), 'type': 'ir.actions.act_window', 'view_type': 'form', @@ -3459,6 +3461,11 @@ class AccountMove(models.Model): 'context': ctx, } + if self.env.is_admin() and not self.env.company.external_report_layout_id and not self.env.context.get('discard_logo_check'): + return self.env['ir.actions.report']._action_configure_external_report_layout(report_action) + + return report_action + def preview_invoice(self): self.ensure_one() return { diff --git a/addons/web/models/base_document_layout.py b/addons/web/models/base_document_layout.py index ff685b32073..47df92452da 100644 --- a/addons/web/models/base_document_layout.py +++ b/addons/web/models/base_document_layout.py @@ -40,12 +40,20 @@ class BaseDocumentLayout(models.TransientModel): def _default_company_details(self): company = self.env.company address_format, company_data = company.partner_id._prepare_display_address() + address_format = self._clean_address_format(address_format, company_data) # company_name may *still* be missing from prepared address in case commercial_company_name is falsy if 'company_name' not in address_format: address_format = '%(company_name)s\n' + address_format company_data['company_name'] = company_data['company_name'] or company.name return Markup(nl2br(address_format)) % company_data + def _clean_address_format(self, address_format, company_data): + missing_company_data = [k for k, v in company_data.items() if not v] + for key in missing_company_data: + if key in address_format: + address_format = address_format.replace(f'%({key})s\n', '') + return address_format + company_id = fields.Many2one( 'res.company', default=lambda self: self.env.company, required=True) diff --git a/addons/web/tests/test_base_document_layout.py b/addons/web/tests/test_base_document_layout.py index fb658fff5fa..14afbc0acdb 100644 --- a/addons/web/tests/test_base_document_layout.py +++ b/addons/web/tests/test_base_document_layout.py @@ -223,3 +223,16 @@ class TestBaseDocumentLayout(TestBaseDocumentLayoutHelpers): # self.assertColors(doc_layout, default_colors) # doc_layout.report_layout_id = self.report_layout2 # self.assertColors(doc_layout, self.report_layout2) + + def test_company_details_blank_lines(self): + """Test that the company address is generated dynamically using only the fields that are defined, + without leaving any blank lines.""" + # Make sure there is no blank line in the company details. + doc_layout_1 = self.env['base.document.layout'].create({'company_id': self.company.id}) + self.assertFalse('\n
\n' in doc_layout_1.company_details) + + # Make sure that 'street2' (an optional field, initially blank), + # appears in the company details when it is defined. + self.company.write({'street2': 'street_2_detail'}) + doc_layout_2 = self.env['base.document.layout'].create({'company_id': self.company.id}) + self.assertTrue('street_2_detail' in doc_layout_2.company_details) diff --git a/odoo/addons/base/models/ir_actions_report.py b/odoo/addons/base/models/ir_actions_report.py index bf9b13e3971..187bb7266fb 100644 --- a/odoo/addons/base/models/ir_actions_report.py +++ b/odoo/addons/base/models/ir_actions_report.py @@ -926,12 +926,14 @@ class IrActionsReport(models.Model): discard_logo_check = self.env.context.get('discard_logo_check') if self.env.is_admin() and not self.env.company.external_report_layout_id and config and not discard_logo_check: - action = self.env["ir.actions.actions"]._for_xml_id("web.action_base_document_layout_configurator") - ctx = action.get('context') - py_ctx = json.loads(ctx) if ctx else {} - report_action['close_on_report_download'] = True - py_ctx['report_action'] = report_action - action['context'] = py_ctx - return action + return self._action_configure_external_report_layout(report_action) return report_action + + def _action_configure_external_report_layout(self, report_action): + action = self.env["ir.actions.actions"]._for_xml_id("web.action_base_document_layout_configurator") + py_ctx = json.loads(action.get('context', {})) + report_action['close_on_report_download'] = True + py_ctx['report_action'] = report_action + action['context'] = py_ctx + return action