diff --git a/report_py3o/__manifest__.py b/report_py3o/__manifest__.py index a7ea4d1e..fc975fe4 100644 --- a/report_py3o/__manifest__.py +++ b/report_py3o/__manifest__.py @@ -1,18 +1,17 @@ -# -*- coding: utf-8 -*- # Copyright 2013 XCG Consulting (http://odoo.consulting) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { 'name': 'Py3o Report Engine', 'summary': 'Reporting engine based on Libreoffice (ODT -> ODT, ' 'ODT -> PDF, ODT -> DOC, ODT -> DOCX, ODS -> ODS, etc.)', - 'version': '10.0.2.0.2', + 'version': '12.0.2.0.2', 'category': 'Reporting', 'license': 'AGPL-3', 'author': 'XCG Consulting,' 'ACSONE SA/NV,' 'Odoo Community Association (OCA)', 'website': 'http://odoo.consulting/', - 'depends': ['report'], + 'depends': ['web'], 'external_dependencies': { 'python': ['py3o.template', 'py3o.formats'] @@ -21,7 +20,7 @@ 'security/ir.model.access.csv', 'views/menu.xml', 'views/py3o_template.xml', - 'views/ir_report.xml', + 'views/ir_actions_report.xml', 'views/report_py3o.xml', 'demo/report_py3o.xml', ], diff --git a/report_py3o/controllers/main.py b/report_py3o/controllers/main.py index 71d1ca08..e18a1871 100644 --- a/report_py3o/controllers/main.py +++ b/report_py3o/controllers/main.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) import json @@ -7,7 +6,7 @@ from werkzeug import exceptions, url_decode from odoo.http import route, request -from odoo.addons.report.controllers import main +from odoo.addons.web.controllers import main from odoo.addons.web.controllers.main import ( _serialize_exception, content_disposition @@ -38,20 +37,18 @@ class ReportController(main.ReportController): del data['context']['lang'] context.update(data['context']) - ir_action = request.env['ir.actions.report.xml'] + ir_action = request.env['ir.actions.report'] action_py3o_report = ir_action.get_from_report_name( reportname, "py3o").with_context(context) if not action_py3o_report: raise exceptions.HTTPException( description='Py3o action report not found for report_name ' '%s' % reportname) - context['report_name'] = reportname - py3o_report = request.env['py3o.report'].create({ - 'ir_actions_report_xml_id': action_py3o_report.id - }).with_context(context) - res, filetype = py3o_report.create_report(docids, data) + res, filetype = action_py3o_report._render_py3o(docids, data) filename = action_py3o_report.gen_report_download_filename( docids, data) + if not filename.endswith(filetype): + filename = "{}.{}".format(filename, filetype) content_type = mimetypes.guess_type("x." + filetype)[0] http_headers = [('Content-Type', content_type), ('Content-Length', len(res)), @@ -69,8 +66,8 @@ class ReportController(main.ReportController): :returns: Response with a filetoken cookie and an attachment header """ requestcontent = json.loads(data) - url, type = requestcontent[0], requestcontent[1] - if type != 'py3o': + url, report_type = requestcontent[0], requestcontent[1] + if 'py3o' not in report_type: return super(ReportController, self).report_download(data, token) try: reportname = url.split('/report/py3o/')[1].split('?')[0] @@ -85,12 +82,12 @@ class ReportController(main.ReportController): else: # Particular report: # decoding the args represented in JSON - data = url_decode(url.split('?')[1]).items() + data = list(url_decode(url.split('?')[1]).items()) response = self.report_routes( reportname, converter='py3o', **dict(data)) response.set_cookie('fileToken', token) return response - except Exception, e: + except Exception as e: se = _serialize_exception(e) error = { 'code': 200, diff --git a/report_py3o/demo/report_py3o.xml b/report_py3o/demo/report_py3o.xml index 4a47c38a..6d894153 100644 --- a/report_py3o/demo/report_py3o.xml +++ b/report_py3o/demo/report_py3o.xml @@ -4,23 +4,17 @@ - + Py3o Demo Report - ir.actions.report.xml + ir.actions.report res.users py3o_user_info py3o odt report_py3o demo/res_user.odt + + report - - - - - res.users - Py3o Demo Report - - - - + + diff --git a/report_py3o/i18n/am.po b/report_py3o/i18n/am.po index e0386c62..cf64bd8d 100644 --- a/report_py3o/i18n/am.po +++ b/report_py3o/i18n/am.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/ar.po b/report_py3o/i18n/ar.po index 89db1fdc..5d00c66c 100644 --- a/report_py3o/i18n/ar.po +++ b/report_py3o/i18n/ar.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/bg.po b/report_py3o/i18n/bg.po index 24d6cdd3..9a319149 100644 --- a/report_py3o/i18n/bg.po +++ b/report_py3o/i18n/bg.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/bs.po b/report_py3o/i18n/bs.po index 3d71d93d..b6aa1691 100644 --- a/report_py3o/i18n/bs.po +++ b/report_py3o/i18n/bs.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/ca.po b/report_py3o/i18n/ca.po index f442c53f..03ce289e 100644 --- a/report_py3o/i18n/ca.po +++ b/report_py3o/i18n/ca.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/cs.po b/report_py3o/i18n/cs.po index 5bc29b8b..bd3c9dff 100644 --- a/report_py3o/i18n/cs.po +++ b/report_py3o/i18n/cs.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/da.po b/report_py3o/i18n/da.po index f2e60592..0eb9a20e 100644 --- a/report_py3o/i18n/da.po +++ b/report_py3o/i18n/da.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/de.po b/report_py3o/i18n/de.po index cd7278f4..121086b5 100644 --- a/report_py3o/i18n/de.po +++ b/report_py3o/i18n/de.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/el_GR.po b/report_py3o/i18n/el_GR.po index 5001b84d..a79459b1 100644 --- a/report_py3o/i18n/el_GR.po +++ b/report_py3o/i18n/el_GR.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/en_GB.po b/report_py3o/i18n/en_GB.po index 38ae7eb0..c48a6a44 100644 --- a/report_py3o/i18n/en_GB.po +++ b/report_py3o/i18n/en_GB.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/es.po b/report_py3o/i18n/es.po index 5d821638..a1babcd3 100644 --- a/report_py3o/i18n/es.po +++ b/report_py3o/i18n/es.po @@ -89,7 +89,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "Ir a los informes de acciones xml id" diff --git a/report_py3o/i18n/es_AR.po b/report_py3o/i18n/es_AR.po index 9ad7756d..9662ca3b 100644 --- a/report_py3o/i18n/es_AR.po +++ b/report_py3o/i18n/es_AR.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/es_CL.po b/report_py3o/i18n/es_CL.po index e0a3250e..d6705814 100644 --- a/report_py3o/i18n/es_CL.po +++ b/report_py3o/i18n/es_CL.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/es_CO.po b/report_py3o/i18n/es_CO.po index 46c4d7d5..a7313316 100644 --- a/report_py3o/i18n/es_CO.po +++ b/report_py3o/i18n/es_CO.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/es_CR.po b/report_py3o/i18n/es_CR.po index 8d8981fe..71e7bda7 100644 --- a/report_py3o/i18n/es_CR.po +++ b/report_py3o/i18n/es_CR.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/es_DO.po b/report_py3o/i18n/es_DO.po index 400b60c2..ac47d533 100644 --- a/report_py3o/i18n/es_DO.po +++ b/report_py3o/i18n/es_DO.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/es_EC.po b/report_py3o/i18n/es_EC.po index d45628d9..4cf97575 100644 --- a/report_py3o/i18n/es_EC.po +++ b/report_py3o/i18n/es_EC.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/es_ES.po b/report_py3o/i18n/es_ES.po index 131fc662..ce57b9f0 100644 --- a/report_py3o/i18n/es_ES.po +++ b/report_py3o/i18n/es_ES.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/es_MX.po b/report_py3o/i18n/es_MX.po index 22cdcba1..4212d799 100644 --- a/report_py3o/i18n/es_MX.po +++ b/report_py3o/i18n/es_MX.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/es_PE.po b/report_py3o/i18n/es_PE.po index 0f18e01e..ede6a919 100644 --- a/report_py3o/i18n/es_PE.po +++ b/report_py3o/i18n/es_PE.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/es_PY.po b/report_py3o/i18n/es_PY.po index 1b613915..1f71626e 100644 --- a/report_py3o/i18n/es_PY.po +++ b/report_py3o/i18n/es_PY.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/es_VE.po b/report_py3o/i18n/es_VE.po index d1d322de..9e6debc7 100644 --- a/report_py3o/i18n/es_VE.po +++ b/report_py3o/i18n/es_VE.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/et.po b/report_py3o/i18n/et.po index 98fa256e..326cd91d 100644 --- a/report_py3o/i18n/et.po +++ b/report_py3o/i18n/et.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/eu.po b/report_py3o/i18n/eu.po index fba1b1a1..857aede3 100644 --- a/report_py3o/i18n/eu.po +++ b/report_py3o/i18n/eu.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/fa.po b/report_py3o/i18n/fa.po index 44e34d14..7b606150 100644 --- a/report_py3o/i18n/fa.po +++ b/report_py3o/i18n/fa.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/fi.po b/report_py3o/i18n/fi.po index 3be8a617..02f08764 100644 --- a/report_py3o/i18n/fi.po +++ b/report_py3o/i18n/fi.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/fr.po b/report_py3o/i18n/fr.po index 8b5ca4cd..b7a2228d 100644 --- a/report_py3o/i18n/fr.po +++ b/report_py3o/i18n/fr.po @@ -94,7 +94,7 @@ msgstr "" "rapport pour les enregistrements sélectionnés." #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "Ir actions report xml id" diff --git a/report_py3o/i18n/fr_CA.po b/report_py3o/i18n/fr_CA.po index d061ad61..2273e296 100644 --- a/report_py3o/i18n/fr_CA.po +++ b/report_py3o/i18n/fr_CA.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/fr_CH.po b/report_py3o/i18n/fr_CH.po index 6d6807d3..f68ebf25 100644 --- a/report_py3o/i18n/fr_CH.po +++ b/report_py3o/i18n/fr_CH.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/gl.po b/report_py3o/i18n/gl.po index 6fb8ca86..889a1801 100644 --- a/report_py3o/i18n/gl.po +++ b/report_py3o/i18n/gl.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/gl_ES.po b/report_py3o/i18n/gl_ES.po index 33065de7..d0ea89e3 100644 --- a/report_py3o/i18n/gl_ES.po +++ b/report_py3o/i18n/gl_ES.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/he.po b/report_py3o/i18n/he.po index 3264d512..683fc7f5 100644 --- a/report_py3o/i18n/he.po +++ b/report_py3o/i18n/he.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/hr.po b/report_py3o/i18n/hr.po index b4df1c30..1a0583d0 100644 --- a/report_py3o/i18n/hr.po +++ b/report_py3o/i18n/hr.po @@ -87,7 +87,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/hr_HR.po b/report_py3o/i18n/hr_HR.po index 85061614..dd877a5e 100644 --- a/report_py3o/i18n/hr_HR.po +++ b/report_py3o/i18n/hr_HR.po @@ -88,7 +88,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/hu.po b/report_py3o/i18n/hu.po index a762a8bd..d6032ef4 100644 --- a/report_py3o/i18n/hu.po +++ b/report_py3o/i18n/hu.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/id.po b/report_py3o/i18n/id.po index 2a727ba7..7447c450 100644 --- a/report_py3o/i18n/id.po +++ b/report_py3o/i18n/id.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/it.po b/report_py3o/i18n/it.po index 18def6f9..bb5226f4 100644 --- a/report_py3o/i18n/it.po +++ b/report_py3o/i18n/it.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/ja.po b/report_py3o/i18n/ja.po index ca8c85c5..c267062e 100644 --- a/report_py3o/i18n/ja.po +++ b/report_py3o/i18n/ja.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/ko.po b/report_py3o/i18n/ko.po index a1fb6c0f..a8682af8 100644 --- a/report_py3o/i18n/ko.po +++ b/report_py3o/i18n/ko.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/lt.po b/report_py3o/i18n/lt.po index 7e5afc1f..c73149a0 100644 --- a/report_py3o/i18n/lt.po +++ b/report_py3o/i18n/lt.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/lt_LT.po b/report_py3o/i18n/lt_LT.po index bbd70c96..7596b9f6 100644 --- a/report_py3o/i18n/lt_LT.po +++ b/report_py3o/i18n/lt_LT.po @@ -87,7 +87,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/lv.po b/report_py3o/i18n/lv.po index 98042d6c..f60add86 100644 --- a/report_py3o/i18n/lv.po +++ b/report_py3o/i18n/lv.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/mk.po b/report_py3o/i18n/mk.po index 65fb389d..069a2148 100644 --- a/report_py3o/i18n/mk.po +++ b/report_py3o/i18n/mk.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/mn.po b/report_py3o/i18n/mn.po index ef63ecd5..aff882a2 100644 --- a/report_py3o/i18n/mn.po +++ b/report_py3o/i18n/mn.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/nb.po b/report_py3o/i18n/nb.po index ecdba90f..9edadfab 100644 --- a/report_py3o/i18n/nb.po +++ b/report_py3o/i18n/nb.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/nb_NO.po b/report_py3o/i18n/nb_NO.po index 113002c8..9b066e07 100644 --- a/report_py3o/i18n/nb_NO.po +++ b/report_py3o/i18n/nb_NO.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/nl.po b/report_py3o/i18n/nl.po index 3de8513a..1670c4b5 100644 --- a/report_py3o/i18n/nl.po +++ b/report_py3o/i18n/nl.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/nl_BE.po b/report_py3o/i18n/nl_BE.po index 91550589..4b4a85a0 100644 --- a/report_py3o/i18n/nl_BE.po +++ b/report_py3o/i18n/nl_BE.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/nl_NL.po b/report_py3o/i18n/nl_NL.po index 3da26951..d9ae49bb 100644 --- a/report_py3o/i18n/nl_NL.po +++ b/report_py3o/i18n/nl_NL.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/pl.po b/report_py3o/i18n/pl.po index 68b5e2be..000328c7 100644 --- a/report_py3o/i18n/pl.po +++ b/report_py3o/i18n/pl.po @@ -87,7 +87,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/pt.po b/report_py3o/i18n/pt.po index 01ef3f27..e6c76667 100644 --- a/report_py3o/i18n/pt.po +++ b/report_py3o/i18n/pt.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/pt_BR.po b/report_py3o/i18n/pt_BR.po index d112163d..bd532fa6 100644 --- a/report_py3o/i18n/pt_BR.po +++ b/report_py3o/i18n/pt_BR.po @@ -87,7 +87,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/pt_PT.po b/report_py3o/i18n/pt_PT.po index ec9efef2..04c3a7f5 100644 --- a/report_py3o/i18n/pt_PT.po +++ b/report_py3o/i18n/pt_PT.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/report_py3o.pot b/report_py3o/i18n/report_py3o.pot index 0d206745..40d44f49 100644 --- a/report_py3o/i18n/report_py3o.pot +++ b/report_py3o/i18n/report_py3o.pot @@ -75,7 +75,7 @@ msgid "If you execute a report on several records, by default Odoo will generate msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/ro.po b/report_py3o/i18n/ro.po index bcd5bf58..698c2bb7 100644 --- a/report_py3o/i18n/ro.po +++ b/report_py3o/i18n/ro.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/ru.po b/report_py3o/i18n/ru.po index 75bb8ad3..71b22567 100644 --- a/report_py3o/i18n/ru.po +++ b/report_py3o/i18n/ru.po @@ -87,7 +87,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/sk.po b/report_py3o/i18n/sk.po index de5bfe26..3b22698e 100644 --- a/report_py3o/i18n/sk.po +++ b/report_py3o/i18n/sk.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/sl.po b/report_py3o/i18n/sl.po index 6cdcd681..551d65b4 100644 --- a/report_py3o/i18n/sl.po +++ b/report_py3o/i18n/sl.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/sr.po b/report_py3o/i18n/sr.po index 31543ae4..0ea54a0a 100644 --- a/report_py3o/i18n/sr.po +++ b/report_py3o/i18n/sr.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/sr@latin.po b/report_py3o/i18n/sr@latin.po index 83e68127..428ec80b 100644 --- a/report_py3o/i18n/sr@latin.po +++ b/report_py3o/i18n/sr@latin.po @@ -87,7 +87,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/sv.po b/report_py3o/i18n/sv.po index 6458fc38..498f97fd 100644 --- a/report_py3o/i18n/sv.po +++ b/report_py3o/i18n/sv.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/th.po b/report_py3o/i18n/th.po index b7e5cdcb..9f4825ec 100644 --- a/report_py3o/i18n/th.po +++ b/report_py3o/i18n/th.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/tr.po b/report_py3o/i18n/tr.po index a59ab413..cb160c3a 100644 --- a/report_py3o/i18n/tr.po +++ b/report_py3o/i18n/tr.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/tr_TR.po b/report_py3o/i18n/tr_TR.po index 28c9dc83..feedf120 100644 --- a/report_py3o/i18n/tr_TR.po +++ b/report_py3o/i18n/tr_TR.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/uk.po b/report_py3o/i18n/uk.po index 844214af..a677e022 100644 --- a/report_py3o/i18n/uk.po +++ b/report_py3o/i18n/uk.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/vi.po b/report_py3o/i18n/vi.po index 09e2d3b8..472c026e 100644 --- a/report_py3o/i18n/vi.po +++ b/report_py3o/i18n/vi.po @@ -85,7 +85,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/vi_VN.po b/report_py3o/i18n/vi_VN.po index b1d73ab5..20738743 100644 --- a/report_py3o/i18n/vi_VN.po +++ b/report_py3o/i18n/vi_VN.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/zh_CN.po b/report_py3o/i18n/zh_CN.po index 1b9a025d..faed9c72 100644 --- a/report_py3o/i18n/zh_CN.po +++ b/report_py3o/i18n/zh_CN.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/i18n/zh_TW.po b/report_py3o/i18n/zh_TW.po index d0ac3a9b..f7d0bf4e 100644 --- a/report_py3o/i18n/zh_TW.po +++ b/report_py3o/i18n/zh_TW.po @@ -86,7 +86,7 @@ msgid "" msgstr "" #. module: report_py3o -#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id +#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id msgid "Ir actions report xml id" msgstr "" diff --git a/report_py3o/migrations/10.0.2.0.0/pre-migration.py b/report_py3o/migrations/10.0.2.0.0/pre-migration.py index e697ceec..df6c5f29 100644 --- a/report_py3o/migrations/10.0.2.0.0/pre-migration.py +++ b/report_py3o/migrations/10.0.2.0.0/pre-migration.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2018 Therp BV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). diff --git a/report_py3o/models/__init__.py b/report_py3o/models/__init__.py index e050d2c7..3da72d0f 100644 --- a/report_py3o/models/__init__.py +++ b/report_py3o/models/__init__.py @@ -1,4 +1,3 @@ -from . import ir_actions_report_xml from . import py3o_template -from . import report +from . import ir_actions_report from . import py3o_report diff --git a/report_py3o/models/ir_actions_report_xml.py b/report_py3o/models/ir_actions_report.py similarity index 61% rename from report_py3o/models/ir_actions_report_xml.py rename to report_py3o/models/ir_actions_report.py index 0b6a16d3..a5b63bfc 100644 --- a/report_py3o/models/ir_actions_report_xml.py +++ b/report_py3o/models/ir_actions_report.py @@ -1,5 +1,5 @@ -# -*- coding: utf-8 -*- # Copyright 2013 XCG Consulting (http://odoo.consulting) +# Copyright 2018 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import logging import time @@ -15,13 +15,13 @@ except ImportError: logger.debug('Cannot import py3o.formats') -class IrActionsReportXml(models.Model): - """ Inherit from ir.actions.report.xml to allow customizing the template +class IrActionsReport(models.Model): + """ Inherit from ir.actions.report to allow customizing the template file. The user cam chose a template from a list. The list is configurable in the configuration tab, see py3o_template.py """ - _inherit = 'ir.actions.report.xml' + _inherit = 'ir.actions.report' @api.multi @api.constrains("py3o_filetype", "report_type") @@ -43,6 +43,9 @@ class IrActionsReportXml(models.Model): selections.append((name, description)) return selections + report_type = fields.Selection( + selection_add=[("py3o", "py3o")] + ) py3o_filetype = fields.Selection( selection="_get_py3o_filetypes", string="Output Format") @@ -78,12 +81,21 @@ class IrActionsReportXml(models.Model): def render_report(self, res_ids, name, data): action_py3o_report = self.get_from_report_name(name, "py3o") if action_py3o_report: - return self.env['py3o.report'].create({ - 'ir_actions_report_xml_id': action_py3o_report.id - }).create_report(res_ids, data) - return super(IrActionsReportXml, self).render_report( + return action_py3o_report._render_py3o(res_ids, data) + return super(IrActionsReport, self).render_report( res_ids, name, data) + @api.multi + def _render_py3o(self, res_ids, data): + self.ensure_one() + if self.report_type != "py3o": + raise RuntimeError( + "py3o rendition is only available on py3o report.\n" + "(current: '{}', expected 'py3o'".format(self.report_type)) + return self.env['py3o.report'].create({ + 'ir_actions_report_id': self.id + }).create_report(res_ids, data) + @api.multi def gen_report_download_filename(self, res_ids, data): """Override this function to change the name of the downloaded report @@ -95,3 +107,34 @@ class IrActionsReportXml(models.Model): return safe_eval(report.print_report_name, {'object': obj, 'time': time}) return "%s.%s" % (self.name, self.py3o_filetype) + + @api.model + def _get_report_from_name(self, report_name): + """Get the first record of ir.actions.report having the + ``report_name`` as value for the field report_name. + """ + res = super(IrActionsReport, self)._get_report_from_name(report_name) + if res: + return res + # maybe a py3o report + context = self.env['res.users'].context_get() + return self.with_context(context).search( + [('report_type', '=', 'py3o'), + ('report_name', '=', report_name)], limit=1) + + @api.multi + def _get_attachments(self, res_ids): + """ Return the report already generated for the given res_ids + """ + self.ensure_one() + save_in_attachment = {} + if res_ids: + # Dispatch the records by ones having an attachment + Model = self.env[self.model] + record_ids = Model.browse(res_ids) + if self.attachment: + for record_id in record_ids: + attachment_id = self.retrieve_attachment(record_id) + if attachment_id: + save_in_attachment[record_id.id] = attachment_id + return save_in_attachment diff --git a/report_py3o/models/py3o_report.py b/report_py3o/models/py3o_report.py index 1e2866c3..29b947f5 100644 --- a/report_py3o/models/py3o_report.py +++ b/report_py3o/models/py3o_report.py @@ -1,10 +1,9 @@ -# -*- coding: utf-8 -*- # Copyright 2013 XCG Consulting (http://odoo.consulting) # Copyright 2016 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) import base64 from base64 import b64decode -from cStringIO import StringIO +from io import BytesIO import logging import os import cgi @@ -16,8 +15,6 @@ import sys import tempfile from zipfile import ZipFile, ZIP_DEFLATED -from odoo.exceptions import AccessError -from odoo.report.report_sxw import rml_parse from odoo import api, fields, models, tools, _ logger = logging.getLogger(__name__) @@ -71,7 +68,7 @@ def format_multiline_value(value): @py3o_report_extender() -def defautl_extend(report_xml, localcontext): +def default_extend(report_xml, localcontext): # add the base64decode function to be able do decode binary fields into # the template localcontext['b64decode'] = b64decode @@ -82,11 +79,10 @@ def defautl_extend(report_xml, localcontext): class Py3oReport(models.TransientModel): _name = "py3o.report" - _inherit = 'report' _description = "Report Py30" - ir_actions_report_xml_id = fields.Many2one( - comodel_name="ir.actions.report.xml", + ir_actions_report_id = fields.Many2one( + comodel_name="ir.actions.report", required=True ) @@ -134,7 +130,7 @@ class Py3oReport(models.TransientModel): """ if not tmpl_name: return None - report_xml = self.ir_actions_report_xml_id + report_xml = self.ir_actions_report_id flbk_filename = None if report_xml.module: # if the default is defined @@ -145,7 +141,7 @@ class Py3oReport(models.TransientModel): elif self._is_valid_template_path(tmpl_name): flbk_filename = os.path.realpath(tmpl_name) if self._is_valid_template_filename(flbk_filename): - with open(flbk_filename, 'r') as tmpl: + with open(flbk_filename, 'rb') as tmpl: return tmpl.read() return None @@ -156,7 +152,7 @@ class Py3oReport(models.TransientModel): :return: """ self.ensure_one() - report_xml = self.ir_actions_report_xml_id + report_xml = self.ir_actions_report_id return self._get_template_from_path(report_xml.py3o_template_fallback) @api.multi @@ -174,7 +170,7 @@ class Py3oReport(models.TransientModel): odoo.exceptions.DeferredException """ self.ensure_one() - report_xml = self.ir_actions_report_xml_id + report_xml = self.ir_actions_report_id if report_xml.py3o_template_id.py3o_template_data: # if a user gave a report template tmpl_data = b64decode( @@ -187,7 +183,7 @@ class Py3oReport(models.TransientModel): if tmpl_data is None: # if for any reason the template is not found raise TemplateNotFound( - _(u'No template found. Aborting.'), + _('No template found. Aborting.'), sys.exc_info(), ) @@ -197,47 +193,35 @@ class Py3oReport(models.TransientModel): def _extend_parser_context(self, context_instance, report_xml): # add default extenders for fct in _extender_functions.get(None, []): - fct(report_xml, context_instance.localcontext) + fct(report_xml, context_instance) # add extenders for registered on the template xml_id = report_xml.get_external_id().get(report_xml.id) if xml_id in _extender_functions: for fct in _extender_functions[xml_id]: - fct(report_xml, context_instance.localcontext) + fct(report_xml, context_instance) @api.multi def _get_parser_context(self, model_instance, data): - report_xml = self.ir_actions_report_xml_id - context_instance = rml_parse(self.env.cr, self.env.uid, - report_xml.name, - context=self.env.context) - context_instance.set_context(model_instance, data, model_instance.ids, - report_xml.report_type) - self._extend_parser_context(context_instance, report_xml) - return context_instance.localcontext + report_xml = self.ir_actions_report_id + context = report_xml._get_rendering_context(model_instance.ids, data) + context['objects'] = model_instance + self._extend_parser_context(context, report_xml) + return context - @api.model - def _postprocess_report(self, report_path, res_id, save_in_attachment): - if save_in_attachment.get(res_id): - with open(report_path, 'rb') as pdfreport: - attachment = { - 'name': save_in_attachment.get(res_id), - 'datas': base64.encodestring(pdfreport.read()), - 'datas_fname': save_in_attachment.get(res_id), - 'res_model': save_in_attachment.get('model'), - 'res_id': res_id, - } - try: - self.env['ir.attachment'].create(attachment) - except AccessError: - logger.info("Cannot save PDF report %r as attachment", - attachment['name']) - else: - logger.info( - 'The PDF document %s is now saved in the database', - attachment['name']) + @api.multi + def _postprocess_report(self, model_instance, result_path): + if len(model_instance) == 1 and self.ir_actions_report_id.attachment: + with open(result_path, 'rb') as f: + # we do all the generation process using files to avoid memory + # consumption... + # ... but odoo wants the whole data in memory anyways :) + buffer = BytesIO(f.read()) + self.ir_actions_report_id.postprocess_pdf_report( + model_instance, buffer) + return result_path @api.multi - def _create_single_report(self, model_instance, data, save_in_attachment): + def _create_single_report(self, model_instance, data): """ This function to generate our py3o report """ self.ensure_one() @@ -245,8 +229,8 @@ class Py3oReport(models.TransientModel): suffix='.ods', prefix='p3o.report.tmp.') tmpl_data = self.get_template(model_instance) - in_stream = StringIO(tmpl_data) - with closing(os.fdopen(result_fd, 'w+')) as out_stream: + in_stream = BytesIO(tmpl_data) + with closing(os.fdopen(result_fd, 'wb+')) as out_stream: template = Template(in_stream, out_stream, escape_false=True) localcontext = self._get_parser_context(model_instance, data) template.render(localcontext) @@ -260,16 +244,12 @@ class Py3oReport(models.TransientModel): result_path, model_instance, data ) - if len(model_instance) == 1: - self._postprocess_report( - result_path, model_instance.id, save_in_attachment) - - return result_path + return self._postprocess_report(model_instance, result_path) @api.multi def _convert_single_report(self, result_path, model_instance, data): """Run a command to convert to our target format""" - filetype = self.ir_actions_report_xml_id.py3o_filetype + filetype = self.ir_actions_report_id.py3o_filetype if not Formats().get_format(filetype).native: command = self._convert_single_report_cmd( result_path, model_instance, data, @@ -297,30 +277,30 @@ class Py3oReport(models.TransientModel): ), '--headless', '--convert-to', - self.ir_actions_report_xml_id.py3o_filetype, + self.ir_actions_report_id.py3o_filetype, result_path, ] @api.multi def _get_or_create_single_report(self, model_instance, data, - save_in_attachment): + existing_reports_attachment): self.ensure_one() - if save_in_attachment and save_in_attachment[ - 'loaded_documents'].get(model_instance.id): - d = save_in_attachment[ - 'loaded_documents'].get(model_instance.id) + attachment = existing_reports_attachment.get( + model_instance.id) + if attachment and self.ir_actions_report_id.attachment_use: + content = base64.decodestring(attachment.datas) report_file = tempfile.mktemp( - "." + self.ir_actions_report_xml_id.py3o_filetype) + "." + self.ir_actions_report_id.py3o_filetype) with open(report_file, "wb") as f: - f.write(d) + f.write(content) return report_file return self._create_single_report( - model_instance, data, save_in_attachment) + model_instance, data) @api.multi def _zip_results(self, reports_path): self.ensure_one() - zfname_prefix = self.ir_actions_report_xml_id.name + zfname_prefix = self.ir_actions_report_id.name result_path = tempfile.mktemp(suffix="zip", prefix='py3o-zip-result') with ZipFile(result_path, 'w', ZIP_DEFLATED) as zf: cpt = 0 @@ -335,7 +315,7 @@ class Py3oReport(models.TransientModel): @api.multi def _merge_results(self, reports_path): self.ensure_one() - filetype = self.ir_actions_report_xml_id.py3o_filetype + filetype = self.ir_actions_report_id.py3o_filetype if not reports_path: return False, False if len(reports_path) == 1: @@ -359,22 +339,22 @@ class Py3oReport(models.TransientModel): def create_report(self, res_ids, data): """ Override this function to handle our py3o report """ - model_instances = self.env[self.ir_actions_report_xml_id.model].browse( + model_instances = self.env[self.ir_actions_report_id.model].browse( res_ids) - save_in_attachment = self._check_attachment_use( - res_ids, self.ir_actions_report_xml_id) or {} reports_path = [] if ( len(res_ids) > 1 and - self.ir_actions_report_xml_id.py3o_multi_in_one): + self.ir_actions_report_id.py3o_multi_in_one): reports_path.append( self._create_single_report( - model_instances, data, save_in_attachment)) + model_instances, data)) else: + existing_reports_attachment = \ + self.ir_actions_report_id._get_attachments(res_ids) for model_instance in model_instances: reports_path.append( self._get_or_create_single_report( - model_instance, data, save_in_attachment)) + model_instance, data, existing_reports_attachment)) result_path, filetype = self._merge_results(reports_path) reports_path.append(result_path) diff --git a/report_py3o/models/py3o_template.py b/report_py3o/models/py3o_template.py index 0cce01b4..e2a3632b 100644 --- a/report_py3o/models/py3o_template.py +++ b/report_py3o/models/py3o_template.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2013 XCG Consulting (http://odoo.consulting) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import fields, models @@ -6,6 +5,7 @@ from odoo import fields, models class Py3oTemplate(models.Model): _name = 'py3o.template' + _description = 'Py3o template' name = fields.Char(required=True) py3o_template_data = fields.Binary("LibreOffice Template") diff --git a/report_py3o/models/report.py b/report_py3o/models/report.py deleted file mode 100644 index 0666861c..00000000 --- a/report_py3o/models/report.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2017 Akretion (http://www.akretion.com/) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo import api, models - - -class Report(models.Model): - - _inherit = 'report' - - @api.model - def _get_report_from_name(self, report_name): - """Get the first record of ir.actions.report.xml having the - ``report_name`` as value for the field report_name. - """ - res = super(Report, self)._get_report_from_name(report_name) - if res: - return res - # maybe a py3o report - report_obj = self.env['ir.actions.report.xml'] - context = self.env['res.users'].context_get() - return report_obj.with_context(context).search( - [('report_type', '=', 'py3o'), - ('report_name', '=', report_name)], limit=1) diff --git a/report_py3o/static/src/js/py3oactionmanager.js b/report_py3o/static/src/js/py3oactionmanager.js index 408d180a..1cbfdcc2 100644 --- a/report_py3o/static/src/js/py3oactionmanager.js +++ b/report_py3o/static/src/js/py3oactionmanager.js @@ -25,34 +25,33 @@ var trigger_download = function(session, response, c, action, options) { }; ActionManager.include({ - ir_actions_report_xml: function(action, options) { - var self = this; - + _executeReportAction: function (action, options) { // Py3o reports - if ('report_type' in action && action.report_type == 'py3o' ) { - framework.blockUI(); - action = _.clone(action); - _t = core._t; - var report_url = '/report/py3o/' + action.report_name;; - // generic report: no query string - // particular: query string of action.data.form and context - if (!('data' in action) || !(action.data)) { - if ('active_ids' in action.context) { - report_url += "/" + action.context.active_ids.join(','); - } - } else { - report_url += "&options=" + encodeURIComponent(JSON.stringify(action.data)); - report_url += "&context=" + encodeURIComponent(JSON.stringify(action.context)); - } + if ('report_type' in action && action.report_type === 'py3o' ) { + return this._triggerDownload(action, options, 'py3o'); + } else { + return this._super.apply(this, arguments); + } + }, - var response = new Array(); - response[0] = report_url; - response[1] = action.report_type; - var c = crash_manager; - return trigger_download(self.session, response, c, action, options); + _makeReportUrls: function(action) { + var reportUrls = this._super.apply(this, arguments); + reportUrls.py3o = '/report/py3o/' + action.report_name; + // We may have to build a query string with `action.data`. It's the place + // were report's using a wizard to customize the output traditionally put + // their options. + if (_.isUndefined(action.data) || _.isNull(action.data) || + (_.isObject(action.data) && _.isEmpty(action.data))) { + if (action.context.active_ids) { + var activeIDsPath = '/' + action.context.active_ids.join(','); + reportUrls.py3o += activeIDsPath;; + } } else { - return self._super(action, options); + var serializedOptionsPath = '?options=' + encodeURIComponent(JSON.stringify(action.data)); + serializedOptionsPath += '&context=' + encodeURIComponent(JSON.stringify(action.context)); + reportUrls.py3o += serializedOptionsPath; } + return reportUrls; } }); diff --git a/report_py3o/tests/test_report_py3o.py b/report_py3o/tests/test_report_py3o.py index 2cf49550..c29c0e98 100644 --- a/report_py3o/tests/test_report_py3o.py +++ b/report_py3o/tests/test_report_py3o.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2016 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).). @@ -14,6 +13,7 @@ from contextlib import contextmanager from odoo import tools from odoo.tests.common import TransactionCase from odoo.exceptions import ValidationError +from odoo.addons.base.tests.test_mimetypes import PNG from ..models.py3o_report import TemplateNotFound, format_multiline_value from base64 import b64encode @@ -42,9 +42,10 @@ class TestReportPy3o(TransactionCase): def setUp(self): super(TestReportPy3o, self).setUp() + self.env.user.image = PNG self.report = self.env.ref("report_py3o.res_users_report_py3o") self.py3o_report = self.env['py3o.report'].create({ - 'ir_actions_report_xml_id': self.report.id}) + 'ir_actions_report_id': self.report.id}) def test_required_py3_filetype(self): self.assertEqual(self.report.report_type, "py3o") @@ -56,15 +57,17 @@ class TestReportPy3o(TransactionCase): def _render_patched(self, result_text='test result', call_count=1): py3o_report = self.env['py3o.report'] + py3o_report_obj = py3o_report.create({ + "ir_actions_report_id": self.report.id + }) with mock.patch.object( py3o_report.__class__, '_create_single_report') as patched_pdf: result = tempfile.mktemp('.txt') with open(result, 'w') as fp: fp.write(result_text) - patched_pdf.return_value = result - patched_pdf.side_effect = lambda record, data, save_attachments:\ - py3o_report._postprocess_report( - result, record.id, save_attachments, + patched_pdf.side_effect = lambda record, data:\ + py3o_report_obj._postprocess_report( + record, result ) or result # test the call the the create method inside our custom parser self.report.render_report(self.env.user.ids, @@ -92,14 +95,14 @@ class TestReportPy3o(TransactionCase): created_attachement = new_attachments - attachments self.assertEqual(1, len(created_attachement)) content = b64decode(created_attachement.datas) - self.assertEqual("test result", content) + self.assertEqual(b"test result", content) # put a new content into tha attachement and check that the next # time we ask the report we received the saved attachment not a newly # generated document - created_attachement.datas = base64.encodestring("new content") + created_attachement.datas = base64.encodestring(b"new content") res = self.report.render_report( self.env.user.ids, self.report.report_name, {}) - self.assertEqual(('new content', self.report.py3o_filetype), res) + self.assertEqual((b'new content', self.report.py3o_filetype), res) def test_report_post_process(self): """ @@ -115,7 +118,7 @@ class TestReportPy3o(TransactionCase): self.assertEqual(self.env.user.name + '.txt', attachements.name) self.assertEqual(self.env.user._name, attachements.res_model) self.assertEqual(self.env.user.id, attachements.res_id) - self.assertEqual('test result', b64decode(attachements.datas)) + self.assertEqual(b'test result', b64decode(attachements.datas)) @tools.misc.mute_logger('odoo.addons.report_py3o.models.py3o_report') def test_report_template_configs(self): @@ -152,7 +155,7 @@ class TestReportPy3o(TransactionCase): # the tempalte can also be provided as a binary field self.report.py3o_template_fallback = False - with open(flbk_filename) as tmpl_file: + with open(flbk_filename, 'rb') as tmpl_file: tmpl_data = b64encode(tmpl_file.read()) py3o_template = self.env['py3o.template'].create({ 'name': 'test_template', diff --git a/report_py3o/views/ir_report.xml b/report_py3o/views/ir_actions_report.xml similarity index 92% rename from report_py3o/views/ir_report.xml rename to report_py3o/views/ir_actions_report.xml index b0468231..d4c90aac 100644 --- a/report_py3o/views/ir_report.xml +++ b/report_py3o/views/ir_actions_report.xml @@ -5,7 +5,7 @@ py3o_report_view - ir.actions.report.xml + ir.actions.report @@ -29,7 +29,7 @@ py3o_report_search_view - ir.actions.report.xml + ir.actions.report diff --git a/report_py3o/views/menu.xml b/report_py3o/views/menu.xml index 8960a20d..4ee9c005 100644 --- a/report_py3o/views/menu.xml +++ b/report_py3o/views/menu.xml @@ -3,6 +3,6 @@ + parent="base.reporting_menuitem" /> diff --git a/report_py3o_fusion_server/__init__.py b/report_py3o_fusion_server/__init__.py index a3e818a4..9c74cdad 100644 --- a/report_py3o_fusion_server/__init__.py +++ b/report_py3o_fusion_server/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Therp BV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from . import models diff --git a/report_py3o_fusion_server/__manifest__.py b/report_py3o_fusion_server/__manifest__.py index 58d561c6..18b5126d 100644 --- a/report_py3o_fusion_server/__manifest__.py +++ b/report_py3o_fusion_server/__manifest__.py @@ -1,10 +1,9 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Therp BV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { 'name': 'Py3o Report Engine - Fusion server support', 'summary': 'Let the fusion server handle format conversion.', - 'version': '10.0.1.0.0', + 'version': '12.0.1.0.0', 'category': 'Reporting', 'license': 'AGPL-3', 'author': 'XCG Consulting,' @@ -23,7 +22,7 @@ "demo/py3o_pdf_options.xml", ], 'data': [ - "views/ir_report.xml", + "views/ir_actions_report.xml", 'security/ir.model.access.csv', 'views/py3o_server.xml', 'views/py3o_pdf_options.xml', diff --git a/report_py3o_fusion_server/demo/report_py3o.xml b/report_py3o_fusion_server/demo/report_py3o.xml index ac4f194c..ce9de5c4 100644 --- a/report_py3o_fusion_server/demo/report_py3o.xml +++ b/report_py3o_fusion_server/demo/report_py3o.xml @@ -1,6 +1,6 @@ - + diff --git a/report_py3o_fusion_server/models/__init__.py b/report_py3o_fusion_server/models/__init__.py index 8ae69cab..5eec9fc3 100644 --- a/report_py3o_fusion_server/models/__init__.py +++ b/report_py3o_fusion_server/models/__init__.py @@ -1,7 +1,6 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Therp BV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from . import ir_actions_report_xml +from . import ir_actions_report from . import py3o_pdf_options from . import py3o_report from . import py3o_server diff --git a/report_py3o_fusion_server/models/ir_actions_report_xml.py b/report_py3o_fusion_server/models/ir_actions_report.py similarity index 93% rename from report_py3o_fusion_server/models/ir_actions_report_xml.py rename to report_py3o_fusion_server/models/ir_actions_report.py index 167b4e62..f95a1b09 100644 --- a/report_py3o_fusion_server/models/ir_actions_report_xml.py +++ b/report_py3o_fusion_server/models/ir_actions_report.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2013 XCG Consulting # © 2017 Therp BV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). @@ -14,8 +13,8 @@ except ImportError: logger.debug('Cannot import py3o.formats') -class IrActionsReportXml(models.Model): - _inherit = 'ir.actions.report.xml' +class IrActionsReport(models.Model): + _inherit = 'ir.actions.report' @api.multi @api.constrains("py3o_is_local_fusion", "py3o_server_id", "py3o_filetype") diff --git a/report_py3o_fusion_server/models/py3o_pdf_options.py b/report_py3o_fusion_server/models/py3o_pdf_options.py index 1211feb9..d292fa18 100644 --- a/report_py3o_fusion_server/models/py3o_pdf_options.py +++ b/report_py3o_fusion_server/models/py3o_pdf_options.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2018 Akretion (http://www.akretion.com) # @author: Alexis de Lattre # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). diff --git a/report_py3o_fusion_server/models/py3o_report.py b/report_py3o_fusion_server/models/py3o_report.py index a4c9a125..6e6cf507 100644 --- a/report_py3o_fusion_server/models/py3o_report.py +++ b/report_py3o_fusion_server/models/py3o_report.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # © 2013 XCG Consulting # © 2016 ACSONE SA/NV # © 2017 Therp BV @@ -12,7 +11,7 @@ from datetime import datetime from contextlib import closing from openerp import _, api, models from openerp.exceptions import UserError -from StringIO import StringIO +from io import BytesIO logger = logging.getLogger(__name__) @@ -27,15 +26,15 @@ class Py3oReport(models.TransientModel): _inherit = 'py3o.report' @api.multi - def _create_single_report(self, model_instance, data, save_in_attachment): + def _create_single_report(self, model_instance, data): """ This function to generate our py3o report """ self.ensure_one() - report_xml = self.ir_actions_report_xml_id + report_xml = self.ir_actions_report_id filetype = report_xml.py3o_filetype if not report_xml.py3o_server_id: return super(Py3oReport, self)._create_single_report( - model_instance, data, save_in_attachment, + model_instance, data, ) elif report_xml.py3o_is_local_fusion: result_path = super( @@ -43,9 +42,9 @@ class Py3oReport(models.TransientModel): report_py3o_skip_conversion=True, ) )._create_single_report( - model_instance, data, save_in_attachment, + model_instance, data ) - with closing(open(result_path, 'r')) as out_stream: + with closing(open(result_path, 'rb')) as out_stream: tmpl_data = out_stream.read() datadict = {} else: @@ -53,8 +52,8 @@ class Py3oReport(models.TransientModel): suffix='.' + filetype, prefix='p3o.report.tmp.') tmpl_data = self.get_template(model_instance) - in_stream = StringIO(tmpl_data) - with closing(os.fdopen(result_fd, 'w+')) as out_stream: + in_stream = BytesIO(tmpl_data) + with closing(os.fdopen(result_fd, 'wb+')) as out_stream: template = Template(in_stream, out_stream, escape_false=True) localcontext = self._get_parser_context(model_instance, data) expressions = template.get_all_user_python_expression() @@ -107,5 +106,5 @@ class Py3oReport(models.TransientModel): report_xml.report_name, filetype, convert_seconds) if len(model_instance) == 1: self._postprocess_report( - result_path, model_instance.id, save_in_attachment) + result_path, model_instance.id) return result_path diff --git a/report_py3o_fusion_server/models/py3o_server.py b/report_py3o_fusion_server/models/py3o_server.py index 30d7d81a..cab1ee2f 100644 --- a/report_py3o_fusion_server/models/py3o_server.py +++ b/report_py3o_fusion_server/models/py3o_server.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2013 XCG Consulting (http://odoo.consulting) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import fields, models @@ -6,6 +5,7 @@ from odoo import fields, models class Py3oServer(models.Model): _name = 'py3o.server' + _description = 'Py3o server' _rec_name = 'url' url = fields.Char( diff --git a/report_py3o_fusion_server/tests/__init__.py b/report_py3o_fusion_server/tests/__init__.py index 06cc0dee..546c2c05 100644 --- a/report_py3o_fusion_server/tests/__init__.py +++ b/report_py3o_fusion_server/tests/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Therp BV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from . import test_report_py3o_fusion_server diff --git a/report_py3o_fusion_server/tests/test_report_py3o_fusion_server.py b/report_py3o_fusion_server/tests/test_report_py3o_fusion_server.py index 127ed967..6fb4d0e7 100644 --- a/report_py3o_fusion_server/tests/test_report_py3o_fusion_server.py +++ b/report_py3o_fusion_server/tests/test_report_py3o_fusion_server.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Therp BV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). import mock diff --git a/report_py3o_fusion_server/views/ir_report.xml b/report_py3o_fusion_server/views/ir_actions_report.xml similarity index 90% rename from report_py3o_fusion_server/views/ir_report.xml rename to report_py3o_fusion_server/views/ir_actions_report.xml index 173d6b3e..a013fba3 100644 --- a/report_py3o_fusion_server/views/ir_report.xml +++ b/report_py3o_fusion_server/views/ir_actions_report.xml @@ -1,7 +1,7 @@ - ir.actions.report.xml + ir.actions.report diff --git a/report_py3o_fusion_server/views/py3o_pdf_options.xml b/report_py3o_fusion_server/views/py3o_pdf_options.xml index 3109758a..dfade709 100644 --- a/report_py3o_fusion_server/views/py3o_pdf_options.xml +++ b/report_py3o_fusion_server/views/py3o_pdf_options.xml @@ -27,7 +27,6 @@