diff --git a/report_xml/README.rst b/report_xml/README.rst index 564bedf3..c668ad4f 100644 --- a/report_xml/README.rst +++ b/report_xml/README.rst @@ -1,8 +1,10 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 - -Qweb XML Reports -================ + +=========== +XML Reports +=========== This module was written to extend the functionality of the reporting engine to support XML reports and allow modules to generate them by code or by QWeb @@ -19,11 +21,6 @@ To install this module, you need to: But this module does nothing for the end user by itself, so if you have it installed it's probably because there is another module that depends on it. -Configuration -============= - -No manual configuration is needed. - Usage ===== @@ -63,11 +60,6 @@ For further information, please visit: * https://www.odoo.com/forum/help-1 * https://github.com/OCA/reporting-engine -Known issues / Roadmap -====================== - -None - Credits ======= @@ -77,6 +69,7 @@ Contributors ------------ * Jairo Llopis +* Enric Tobella Maintainer ---------- diff --git a/report_xml/__init__.py b/report_xml/__init__.py index d7a2f526..43f32976 100644 --- a/report_xml/__init__.py +++ b/report_xml/__init__.py @@ -1,4 +1,5 @@ -# -*- encoding: utf-8 -*- -# Copyright (C) 2014-2015 Grupo ESOC +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from . import controllers, models +from . import controllers +from . import models diff --git a/report_xml/__openerp__.py b/report_xml/__manifest__.py similarity index 62% rename from report_xml/__openerp__.py rename to report_xml/__manifest__.py index 14671457..3af20cb7 100644 --- a/report_xml/__openerp__.py +++ b/report_xml/__manifest__.py @@ -1,11 +1,12 @@ -# -*- encoding: utf-8 -*- +# -*- coding: utf-8 -*- # Copyright (C) 2014-2015 Grupo ESOC +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { - "name": "Qweb XML Reports", - "version": "8.0.1.0.0", + "name": "XML Reports", + "version": "10.0.1.0.0", "category": "Reporting", - "website": "https://grupoesoc.es", + "website": "https://github.com/OCA/reporting-engine", "author": "Grupo ESOC IngenierĂ­a de Servicios, " "Odoo Community Association (OCA)", "license": "AGPL-3", @@ -17,5 +18,8 @@ ], "data": [ "views/report_xml_templates.xml", + ], + "demo": [ + "demo/report.xml", ] } diff --git a/report_xml/controllers/__init__.py b/report_xml/controllers/__init__.py new file mode 100644 index 00000000..230ef7d3 --- /dev/null +++ b/report_xml/controllers/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import main diff --git a/report_xml/controllers.py b/report_xml/controllers/main.py similarity index 83% rename from report_xml/controllers.py rename to report_xml/controllers/main.py index 332b4d5a..1c73ea62 100644 --- a/report_xml/controllers.py +++ b/report_xml/controllers/main.py @@ -1,8 +1,9 @@ -# -*- encoding: utf-8 -*- +# -*- coding: utf-8 -*- # Copyright (C) 2014-2015 Grupo ESOC +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openerp.http import route -from openerp.addons.report.controllers import main as report +from odoo.addons.report.controllers import main as report +from odoo.http import route class ReportController(report.ReportController): diff --git a/report_xml/demo/report.xml b/report_xml/demo/report.xml new file mode 100644 index 00000000..cd8c7b12 --- /dev/null +++ b/report_xml/demo/report.xml @@ -0,0 +1,21 @@ + + + + + + + + diff --git a/report_xml/models.py b/report_xml/models.py deleted file mode 100644 index 9a88d46e..00000000 --- a/report_xml/models.py +++ /dev/null @@ -1,111 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright (C) 2014-2015 Grupo ESOC - -import logging -from lxml import etree -from openerp import api, fields, models - - -_logger = logging.getLogger(__name__) - - -class ReportAction(models.Model): - _inherit = "ir.actions.report.xml" - - report_type = fields.Selection(selection_add=[("qweb-xml", "XML")]) - - def _lookup_report(self, cr, name): - """Enable ``qweb-xml`` report lookup.""" - try: - return super(ReportAction, self)._lookup_report(cr, name) - except Exception as ex: - # Somebody thought it was a good idea to use standard exceptions - if "qweb-xml" not in ex.message: - raise ex - else: - cr.execute( - "SELECT * FROM ir_act_report_xml WHERE report_name=%s", - (name,)) - return cr.dictfetchone()["report_name"] - - @api.model - def render_report(self, res_ids, name, data): - """Special handling for ``qweb-xml`` reports.""" - if data.get("report_type") == u"qweb-xml": - new_report = self._lookup_report(name) - recs = self.env[self.env.context["active_model"]].browse(res_ids) - result = self.env["report"].get_html(recs, new_report, data=data) - - # XML with spaces before the .``. - """ - _name = "report_xml.xsd_checked_report" - _description = "Base model for reports that need XSD checking" - - @api.multi - def xsd(self): - """Return the XSD schema contents.""" - raise NotImplementedError - - @api.multi - def render_html(self, data=None): - """Return the XML report after checking it against an XSD. - - If ``context`` contains a dict called ``docargs``, it will be used as - the Qweb context. The special key ``docs`` will be added to ``docargs`` - automatically if missing. - """ - # Qweb context - docargs = self.env.context.get("docargs", dict()) - if "docs" not in docargs: - docargs["docs"] = (self.env[self.env.context["active_model"]] - .browse(self.env.context["active_ids"])) - - # Load XSD - xsd = etree.XML(self.xsd()) - _logger.debug("XSD schema contents: %s", etree.tostring(xsd)) - xsd = etree.XMLSchema(xsd) - parser = etree.XMLParser(schema=xsd) - - # Generate XML report - result = (self.env["report"] - .render(self._name[len("report."):], docargs) - .strip()) - - # Validate XML with XSD - try: - etree.fromstring(result, parser) - except Exception as error: - _logger.error(result) - raise error - - return result diff --git a/report_xml/models/__init__.py b/report_xml/models/__init__.py new file mode 100644 index 00000000..e8588766 --- /dev/null +++ b/report_xml/models/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import report_action +from . import report_generator diff --git a/report_xml/models/report_action.py b/report_xml/models/report_action.py new file mode 100644 index 00000000..f6e4f3ce --- /dev/null +++ b/report_xml/models/report_action.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2014-2015 Grupo ESOC +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import logging + +from odoo import api, fields, models +from lxml import etree + +_logger = logging.getLogger(__name__) + + +class ReportAction(models.Model): + _inherit = "ir.actions.report.xml" + + report_type = fields.Selection(selection_add=[("qweb-xml", "XML")]) + + def _lookup_report(self, name): + """Enable ``qweb-xml`` report lookup.""" + try: + return super(ReportAction, self)._lookup_report(name) + except Exception as ex: + # Somebody thought it was a good idea to use standard exceptions + if "qweb-xml" not in ex.message: + raise ex + else: + self._cr.execute( + "SELECT * FROM ir_act_report_xml WHERE report_name=%s", + (name,)) + return self._cr.dictfetchone()["report_name"] + + @api.model + def render_report(self, res_ids, name, data): + """Special handling for ``qweb-xml`` reports.""" + xml_report = self.search([('report_name', '=', name), + ('report_type', '=', 'qweb-xml')], limit=1) + if xml_report: + xml_report = xml_report.ensure_one() + result = self.env["report"].get_html(res_ids, + xml_report.report_name, + data=data) + return ( + etree.tostring( + etree.fromstring(result.strip()), + encoding='UTF-8', xml_declaration=True, pretty_print=True + ), "xml") + else: + return super(ReportAction, self).render_report( + res_ids, name, data) diff --git a/report_xml/models/report_generator.py b/report_xml/models/report_generator.py new file mode 100644 index 00000000..af2d9145 --- /dev/null +++ b/report_xml/models/report_generator.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2014-2015 Grupo ESOC +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import logging + +from odoo import api, models + +_logger = logging.getLogger(__name__) + + +class ReportGenerator(models.Model): + _inherit = "report" + + @api.model + def _get_report_from_name(self, report_name): + res = super(ReportGenerator, self)._get_report_from_name(report_name) + if res: + return res + report_obj = self.env['ir.actions.report.xml'] + qwebtypes = ['qweb-xml'] + conditions = [('report_type', 'in', qwebtypes), + ('report_name', '=', report_name)] + context = self.env['res.users'].context_get() + return report_obj.with_context(context).search(conditions, limit=1) diff --git a/report_xml/tests/__init__.py b/report_xml/tests/__init__.py new file mode 100644 index 00000000..61e68940 --- /dev/null +++ b/report_xml/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import test_report_xml diff --git a/report_xml/tests/test_report_xml.py b/report_xml/tests/test_report_xml.py new file mode 100644 index 00000000..7880eb90 --- /dev/null +++ b/report_xml/tests/test_report_xml.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from lxml import etree +from odoo.tests import common + + +class TestXmlReport(common.TransactionCase): + def test_xml(self): + report_object = self.env['ir.actions.report.xml'] + report_name = 'report_xml.demo_report_xml_view' + self.assertEqual( + report_name, report_object._lookup_report(report_name)) + docs = self.env['res.company'].search([], limit=1) + rep = report_object.render_report( + docs.ids, report_name, {} + ) + root = etree.fromstring(rep[0]) + el = root.xpath('/root/user/name') + self.assertEqual( + el[0].text, + docs.ensure_one().name + ) diff --git a/report_xml/views/report_xml_templates.xml b/report_xml/views/report_xml_templates.xml index 811eddec..ef5aabfa 100644 --- a/report_xml/views/report_xml_templates.xml +++ b/report_xml/views/report_xml_templates.xml @@ -1,11 +1,9 @@ - - + - - +