diff options
| author | Christophe Matthieu <chm@odoo.com> | 2018-08-29 13:48:25 +0200 |
|---|---|---|
| committer | Christophe Matthieu <chm@odoo.com> | 2018-09-04 19:01:20 +0200 |
| commit | f29df7fb2eed9bee7fa1f3452e1efa26f2dd4fb1 (patch) | |
| tree | 9654828162bd58d5da1f19d55773a1e97b471352 | |
| parent | b67bb599b84093a53fdbd9185ce9cb4b2bbd52ff (diff) | |
[FIX] web: Fixed the printing of reports.
A new exception has been added to detect inconsistent reports. However, many are not structured as expected. Thus, the change consists mainly of checking only when the print has to be separated in part to attach it to the respective documents.
We now take the page tag instead of the article, because the article tag is in the layout, so to separate the file, the t-call had to be inside the t-foreach (for the separation) and so possibly read the assets several times. Since all templates have the first tag (in the t-foreach) tag page, the choice is more sensible.
The javascripts files used in readonly were taken out of the editing assets.
A turn was made but not activated, it works locally, but on the runbot, an error is triggered when generating assets after choosing the settings.
| -rw-r--r-- | addons/account/views/report_invoice.xml | 2 | ||||
| -rw-r--r-- | addons/stock/static/tests/route_tour.js | 56 | ||||
| -rw-r--r-- | addons/stock/tests/__init__.py | 3 | ||||
| -rw-r--r-- | addons/stock/tests/test_ui.py | 10 | ||||
| -rw-r--r-- | addons/stock/views/stock_template.xml | 1 | ||||
| -rw-r--r-- | addons/web/static/src/js/report/report.editor.js | 24 | ||||
| -rw-r--r-- | addons/web/static/src/js/report/report.js | 40 | ||||
| -rw-r--r-- | addons/web/views/report_templates.xml | 26 | ||||
| -rw-r--r-- | odoo/addons/base/models/ir_actions_report.py | 26 |
9 files changed, 142 insertions, 46 deletions
diff --git a/addons/account/views/report_invoice.xml b/addons/account/views/report_invoice.xml index b43f48eab9e..18fac77f256 100644 --- a/addons/account/views/report_invoice.xml +++ b/addons/account/views/report_invoice.xml @@ -8,7 +8,7 @@ <address t-field="o.partner_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}' /> <div t-if="o.partner_id.vat" class="mt16"><t t-esc="o.company_id.country_id.vat_label or 'Tax ID'"/>: <span t-field="o.partner_id.vat"/></div> </t> - <div class="page"> + <div class="page" t-att-data-model="o._name" t-att-data-id="o.id"> <h2> <span t-if="o.type == 'out_invoice' and o.state in ('open', 'in_payment', 'paid')">Invoice</span> <span t-if="o.type == 'out_invoice' and o.state == 'draft'">Draft Invoice</span> diff --git a/addons/stock/static/tests/route_tour.js b/addons/stock/static/tests/route_tour.js new file mode 100644 index 00000000000..e75695a5f69 --- /dev/null +++ b/addons/stock/static/tests/route_tour.js @@ -0,0 +1,56 @@ +odoo.define('stock.tour', function (require) { +'use strict'; + +var tour = require('web_tour.tour'); + +tour.register('stock', { + test: true, + url: '/web?debug=assets#action=stock.action_stock_config_settings', + }, + [ + { + content: "wait web client", + trigger: ".o_base_settings", + run: function() {} + }, + { + content: "active 'Multi-Step Routes'", + trigger: '.o_field_boolean[name="group_stock_adv_location"]', + run: function() { + if (!this.$anchor.find('input').prop('checked')) { + this.$anchor.find('label').click(); + $('.o_statusbar_buttons button[name="execute"]').click(); + } + } + }, + { + content: "list of product variants", + trigger: '.o_sub_menu .oe_secondary_submenu [data-menu-xmlid="stock.menu_product_variant_config_stock"]', + extra_trigger: '.o_sub_menu .oe_secondary_submenu:has(a[data-menu-xmlid="stock.menu_routes_config"])', + timeout: 5000, + }, + { + content: "select a product variant", + trigger: '.oe_kanban_global_click:first', + }, + { + content: "click on routes", + trigger: 'button.oe_stat_button i.fa-cogs', + }, + { + content: "print the report", + trigger: 'button[name="print_report"]', + }, + { + content: "print inside the report and check the breadcrum", + trigger: '.o_content iframe .o_report_stock_rule_rule_name', + extra_trigger: 'ol.breadcrumb li:eq(2).active', + }, + { + content: "print the report", + trigger: 'ol.breadcrumb li:eq(3).active', + }, + ] +); + +}); diff --git a/addons/stock/tests/__init__.py b/addons/stock/tests/__init__.py index 25ae6888c7c..50780301d3d 100644 --- a/addons/stock/tests/__init__.py +++ b/addons/stock/tests/__init__.py @@ -14,3 +14,6 @@ from . import test_packing from . import test_packing_neg from . import test_proc_rule from . import test_wise_operator + +# TODO enable this test: error on runbot to create asset and open the iframe +# from . import test_ui diff --git a/addons/stock/tests/test_ui.py b/addons/stock/tests/test_ui.py new file mode 100644 index 00000000000..ef434ea678a --- /dev/null +++ b/addons/stock/tests/test_ui.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import odoo.tests + +@odoo.tests.tagged('post_install', '-at_install') +class TestUi(odoo.tests.HttpCase): + + def test_01_admin_stock_route(self): + self.phantom_js("/web", "odoo.__DEBUG__.services['web_tour.tour'].run('stock')", "odoo.__DEBUG__.services['web_tour.tour'].tours.stock.ready", login='admin') diff --git a/addons/stock/views/stock_template.xml b/addons/stock/views/stock_template.xml index fa3ae244ee2..3ca9f6783b2 100644 --- a/addons/stock/views/stock_template.xml +++ b/addons/stock/views/stock_template.xml @@ -3,6 +3,7 @@ <template id="stock_assets_backend" name="mrp_workorder assets" inherit_id="web.assets_backend"> <xpath expr="." position="inside"> + <script type="text/javascript" src="/stock/static/tests/route_tour.js"></script> <script type="text/javascript" src="/stock/static/src/js/stock_traceability_report_backend.js"></script> <script type="text/javascript" src="/stock/static/src/js/stock_traceability_report_widgets.js"></script> <link rel="stylesheet" type="text/scss" href="/stock/static/src/scss/stock_traceability_report.scss"/> diff --git a/addons/web/static/src/js/report/report.editor.js b/addons/web/static/src/js/report/report.editor.js index 15da9885e31..4955417a759 100644 --- a/addons/web/static/src/js/report/report.editor.js +++ b/addons/web/static/src/js/report/report.editor.js @@ -14,7 +14,6 @@ var trusted_origin = utils.build_origin(trusted_protocol, trusted_host); // Patch the editor's behavior when it is launched inside an iframe. if (window.self !== window.top) { - $(document.body).addClass('o_in_iframe'); // in order to apply css rules // And now we chain some deferred to `save` and `cancel` in order to inform // the report's client action that the actions are done. @@ -60,29 +59,6 @@ if (window.self !== window.top) { } } }, false); - - // Allow to send commands to the webclient when the editor is disabled. - if (window.location.search.indexOf('enable_editor') === -1) { - // `do_action` command - $('[res-id][res-model][view-type]') - .wrap('<a/>') - .attr('href', '#') - .on('click', function (ev) { - ev.preventDefault(); - var action = { - 'type': 'ir.actions.act_window', - 'view_type': $(this).attr('view-type'), - 'view_mode': $(this).attr('view-mode') || $(this).attr('view-type'), - 'res_id': Number($(this).attr('res-id')), - 'res_model': $(this).attr('res-model'), - 'views': [[$(this).attr('view-id') || false, $(this).attr('view-type')]], - }; - window.parent.postMessage({ - 'message': 'report:do_action', - 'action': action, - }, trusted_origin); - }); - } } options.registry.many2one.include({ diff --git a/addons/web/static/src/js/report/report.js b/addons/web/static/src/js/report/report.js new file mode 100644 index 00000000000..50d78a9d151 --- /dev/null +++ b/addons/web/static/src/js/report/report.js @@ -0,0 +1,40 @@ +odoo.define('report', function (require) { +'use strict'; + +require('web.dom_ready'); +var utils = require('report.utils'); + +if (window.self === window.top) { + return; +} + +$(document.body).addClass('o_in_iframe'); // in order to apply css rules + +var web_base_url = $('html').attr('web-base-url'); +var trusted_host = utils.get_host_from_url(web_base_url); +var trusted_protocol = utils.get_protocol_from_url(web_base_url); +var trusted_origin = utils.build_origin(trusted_protocol, trusted_host); + +// Allow to send commands to the webclient when the editor is disabled. +if (window.location.search.indexOf('enable_editor') === -1) { + // `do_action` command + $('[res-id][res-model][view-type]') + .wrap('<a/>') + .attr('href', '#') + .on('click', function (ev) { + ev.preventDefault(); + var action = { + 'type': 'ir.actions.act_window', + 'view_type': $(this).attr('view-type'), + 'view_mode': $(this).attr('view-mode') || $(this).attr('view-type'), + 'res_id': Number($(this).attr('res-id')), + 'res_model': $(this).attr('res-model'), + 'views': [[$(this).attr('view-id') || false, $(this).attr('view-type')]], + }; + window.parent.postMessage({ + 'message': 'report:do_action', + 'action': action, + }, trusted_origin); + }); +} +}); diff --git a/addons/web/views/report_templates.xml b/addons/web/views/report_templates.xml index 6f83ae6254c..bc84d62a065 100644 --- a/addons/web/views/report_templates.xml +++ b/addons/web/views/report_templates.xml @@ -25,6 +25,12 @@ <link rel="stylesheet" type="text/scss" href="/web/static/src/scss/layout_background.scss"/> <link rel="stylesheet" type="text/scss" href="/web/static/src/scss/layout_boxed.scss"/> <link rel="stylesheet" type="text/scss" href="/web/static/src/scss/layout_clean.scss"/> + + <script type="text/javascript" src="web/static/src/js/services/session.js"/> + <script type="text/javascript" src="/web/static/src/js/report/utils.js"/> + <script type="text/javascript" src="/web_editor/static/src/js/content/body_manager.js"/> + <script type="text/javascript" src="/web_editor/static/src/js/root_widget.js"/> + <script type="text/javascript" src='/web/static/src/js/report/report.js' /> </template> <template id="report_assets_pdf"> @@ -37,7 +43,6 @@ <link rel="stylesheet" type="text/scss" href="/web/static/src/scss/report.editor.scss"/> <script type="text/javascript" src="/web/static/src/js/services/session.js"/> - <script type="text/javascript" src="/web/static/src/js/report/utils.js"/> <script type="text/javascript" src='/web/static/src/js/report/report.editor.js' /> </template> @@ -65,14 +70,13 @@ <t t-call-assets="web_editor.assets_editor" t-js="false"/> <t t-call-assets="web.report_assets_editor" t-js="false"/> </t> + <t t-call-assets="web.assets_common" t-css="false"/> + <t t-call-assets="web.report_assets_common" t-css="false"/> <t t-if="editable"> - <t t-call-assets="web.assets_common" t-css="false"/> <t t-call-assets="web_editor.summernote" t-css="false"/> <t t-call-assets="web_editor.assets_editor" t-css="false"/> <t t-call-assets="web.report_assets_editor" t-css="false"/> - <script type="text/javascript" src="/web_editor/static/src/js/content/body_manager.js"/> - <script type="text/javascript" src="/web_editor/static/src/js/root_widget.js"/> <script type="text/javascript" src="/web_editor/static/src/js/iframe.js"></script> <script t-if="enable_editor and inline_mode" type="text/javascript" src="/web_editor/static/src/js/inline.js"></script> </t> @@ -178,7 +182,7 @@ <div class="clearfix mb8"/> </div> - <div class="article o_report_layout_background" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id"> + <div class="article o_report_layout_background"> <t t-call="web.address_layout"/> <t t-raw="0"/> </div> @@ -218,7 +222,7 @@ </div> </div> - <div class="article o_report_layout_boxed" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id"> + <div class="article o_report_layout_boxed"> <t t-call="web.address_layout"/> <t t-raw="0"/> </div> @@ -257,7 +261,7 @@ </div> </div> - <div class="article o_report_layout_clean" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id"> + <div class="article o_report_layout_clean"> <t t-call="web.address_layout"/> <t t-raw="0"/> </div> @@ -305,7 +309,7 @@ </div> </div> - <div class="article o_report_layout_standard" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id"> + <div class="article o_report_layout_standard"> <t t-call="web.address_layout"/> <t t-raw="0"/> </div> @@ -386,16 +390,14 @@ </div> </div> </div> - <div class="article" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id"> + <div class="article"> <t t-raw="0"/> </div> </template> <template id="basic_layout"> - <t t-if="not o" t-set="o" t-value="doc"/> - <t t-call="web.html_container"> - <div class="article" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id"> + <div class="article"> <t t-raw="0"/> </div> </t> diff --git a/odoo/addons/base/models/ir_actions_report.py b/odoo/addons/base/models/ir_actions_report.py index 5e81443d2bb..eedcb4e8e2d 100644 --- a/odoo/addons/base/models/ir_actions_report.py +++ b/odoo/addons/base/models/ir_actions_report.py @@ -300,27 +300,31 @@ class IrActionsReport(models.Model): bodies = [] res_ids = [] + body_parent = root.xpath('//main') # Retrieve headers for node in root.xpath(match_klass.format('header')): + body_parent = node.getparent() + node.getparent().remove(node) header_node.append(node) # Retrieve footers for node in root.xpath(match_klass.format('footer')): + body_parent = node.getparent() + node.getparent().remove(node) footer_node.append(node) # Retrieve bodies - for node in root.xpath(match_klass.format('article')): - if node.get('data-oe-model') == self.model: - body = layout.render(dict(subst=False, body=lxml.html.tostring(node), base_url=base_url)) - bodies.append(body) - res_ids.append(int(node.get('data-oe-id', False))) + for node in root.xpath(match_klass.format('page')): + body = layout.render(dict(subst=False, body=lxml.html.tostring(node), base_url=base_url)) + bodies.append(body) + if node.get('data-model') == self.model: + res_ids.append(int(node.get('data-id', 0))) else: - _logger.warning("The report's template '%s' does not contains the attributes 'data-oe-model' and 'data-oe-id' on the container (with class 'article')", self.name) - raise UserError(_("The report's template is wrong, please contact your administrator")) + res_ids.append(None) if not bodies: - _logger.warning("The report's template '%s' does not contains the container with the class 'article'", self.name) - raise UserError(_("The report's template is wrong, please contact your administrator")) + body = bytearray().join([lxml.html.tostring(c) for c in body_parent.getchildren()]) + bodies.append(body) # Get paperformat arguments set in the root html tag. They are prioritized over # paperformat-record arguments. @@ -660,6 +664,10 @@ class IrActionsReport(models.Model): bodies, html_ids, header, footer, specific_paperformat_args = self.with_context(context)._prepare_html(html) + if self.attachment and set(res_ids) != set(html_ids): + raise UserError(_("The report's template '%s' is wrong, please contact your administrator. \n\n" + "Can not separate file to save as attachment because the report's template does not contains the attributes 'data-model' and 'data-id' on the div with 'page' classname.") % self.name) + pdf_content = self._run_wkhtmltopdf( bodies, header=header, |
