Browse Source

[MIG] report_xml: Migration to 12.0

pull/295/head
ernesto 6 years ago
parent
commit
bb86558bc0
  1. 86
      report_xml/README.rst
  2. 1
      report_xml/__init__.py
  3. 8
      report_xml/__manifest__.py
  4. 1
      report_xml/controllers/__init__.py
  5. 99
      report_xml/controllers/main.py
  6. 5
      report_xml/demo/report.xml
  7. 1
      report_xml/models/__init__.py
  8. 27
      report_xml/models/report_action.py
  9. 4
      report_xml/readme/CONTRIBUTORS.rst
  10. 1
      report_xml/readme/CREDITS.rst
  11. 3
      report_xml/readme/DESCRIPTION.rst
  12. 10
      report_xml/readme/INSTALL.rst
  13. 35
      report_xml/readme/USAGE.rst
  14. 13
      report_xml/static/description/icon.svg
  15. 477
      report_xml/static/description/index.html
  16. 20
      report_xml/static/src/js/report/action_manager_report.js
  17. 41
      report_xml/static/src/js/report/qwebactionmanager.js
  18. 1
      report_xml/tests/__init__.py
  19. 1
      report_xml/tests/test_report_xml.py
  20. 13
      report_xml/views/ir_actions_views.xml
  21. 9
      report_xml/views/report_xml_templates.xml
  22. 3
      report_xml/views/webclient_templates.xml

86
report_xml/README.rst

@ -1,15 +1,39 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
=========== ===========
XML Reports XML Reports
=========== ===========
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Freporting--engine-lightgray.png?logo=github
:target: https://github.com/OCA/reporting-engine/tree/12.0/report_xml
:alt: OCA/reporting-engine
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/reporting-engine-12-0/reporting-engine-12-0-report_xml
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/143/12.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
This module was written to extend the functionality of the reporting engine to 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 support XML reports and allow modules to generate them by code or by QWeb
templates. templates.
**Table of contents**
.. contents::
:local:
Installation Installation
============ ============
@ -21,13 +45,16 @@ To install this module, you need to:
But this module does nothing for the end user by itself, so if you have it 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. installed it's probably because there is another module that depends on it.
.. _reporting-engine: https://github.com/OCA/reporting-engine
.. _lxml: http://lxml.de/
Usage Usage
===== =====
This module is intended as a base engine for other modules to use it, so no direct result if you are a user. This module is intended as a base engine for other modules to use it, so no direct result if you are a user.
If you are a developer If you are a developer
----------------------
~~~~~~~~~~~~~~~~~~~~~~
To learn from an example, just check the `sample module`_. To learn from an example, just check the `sample module`_.
@ -41,7 +68,7 @@ To develop with this module, you need to:
In case you want to create a `custom report`_, the instructions remain the same In case you want to create a `custom report`_, the instructions remain the same
as for HTML reports, and the method that you must override is also called as for HTML reports, and the method that you must override is also called
``render_html``, even when this time you are creating a XML report.
``_get_report_values``, even when this time you are creating a XML report.
You can make your custom report inherit ``report_xml.xsd_checked_report``, name You can make your custom report inherit ``report_xml.xsd_checked_report``, name
it like your XML ``<template>`` id prepended by ``report.``, add a ``xsd()`` it like your XML ``<template>`` id prepended by ``report.``, add a ``xsd()``
@ -56,35 +83,54 @@ For further information, please visit:
* https://www.odoo.com/forum/help-1 * https://www.odoo.com/forum/help-1
* https://github.com/OCA/reporting-engine * https://github.com/OCA/reporting-engine
.. _custom report: https://www.odoo.com/documentation/12.0/reference/reports.html#custom-reports
.. _instructions to create reports: https://www.odoo.com/documentation/12.0/reference/reports.html
.. _sample module: https://github.com/OCA/reporting-engine/tree/12.0/report_xml_sample
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/reporting-engine/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/reporting-engine/issues/new?body=module:%20report_xml%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits Credits
======= =======
* Icon taken from http://commons.wikimedia.org/wiki/File:Text-xml.svg.
Authors
~~~~~~~
* Tecnativa
Contributors Contributors
------------
~~~~~~~~~~~~
* Jairo Llopis <j.llopis@grupoesoc.es>
* Enric Tobella <etobella@creublanca.es> * Enric Tobella <etobella@creublanca.es>
* `Tecnativa <https://www.tecnativa.com>`_:
Jairo Llopis
Maintainer
----------
Other credits
~~~~~~~~~~~~~
* Icon taken from http://commons.wikimedia.org/wiki/File:Text-xml.svg
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png .. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association :alt: Odoo Community Association
:target: https://odoo-community.org :target: https://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and mission is to support the collaborative development of Odoo features and
promote its widespread use. promote its widespread use.
To contribute to this module, please visit https://odoo-community.org.
This module is part of the `OCA/reporting-engine <https://github.com/OCA/reporting-engine/tree/12.0/report_xml>`_ project on GitHub.
.. _custom report: https://www.odoo.com/documentation/8.0/reference/reports.html#custom-reports
.. _instructions to create reports: https://www.odoo.com/documentation/8.0/reference/reports.html
.. _reporting-engine: https://github.com/OCA/reporting-engine
.. _sample module: https://github.com/OCA/reporting-engine/tree/8.0/report_xml_sample
.. _lxml: http://lxml.de/
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

1
report_xml/__init__.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html). # License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).
from . import controllers from . import controllers

8
report_xml/__manifest__.py

@ -1,13 +1,11 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2014-2015 Grupo ESOC <www.grupoesoc.es> # Copyright (C) 2014-2015 Grupo ESOC <www.grupoesoc.es>
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html). # License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).
{ {
"name": "XML Reports", "name": "XML Reports",
"version": "11.0.1.0.2",
"version": "12.0.1.0.0",
"category": "Reporting", "category": "Reporting",
"website": "https://github.com/OCA/reporting-engine", "website": "https://github.com/OCA/reporting-engine",
"author": "Grupo ESOC Ingeniería de Servicios, "
"author": "Tecnativa, "
"Odoo Community Association (OCA)", "Odoo Community Association (OCA)",
"license": "AGPL-3", "license": "AGPL-3",
"installable": True, "installable": True,
@ -17,8 +15,8 @@
"web", "web",
], ],
"data": [ "data": [
"views/report_xml_templates.xml",
"views/webclient_templates.xml", "views/webclient_templates.xml",
"views/ir_actions_views.xml",
], ],
"demo": [ "demo": [
"demo/report.xml", "demo/report.xml",

1
report_xml/controllers/__init__.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html). # License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).
from . import main from . import main

99
report_xml/controllers/main.py

@ -1,40 +1,91 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2014-2015 Grupo ESOC <www.grupoesoc.es> # Copyright (C) 2014-2015 Grupo ESOC <www.grupoesoc.es>
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html). # License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).
import json
import time import time
from odoo.addons.web.controllers import main as report from odoo.addons.web.controllers import main as report
from odoo.http import content_disposition, request, route
from odoo.tools.safe_eval import safe_eval
from odoo.http import content_disposition, request, route, serialize_exception
from odoo.tools import safe_eval, html_escape
from werkzeug.urls import url_decode
class ReportController(report.ReportController): class ReportController(report.ReportController):
@route() @route()
def report_routes(self, reportname, docids=None, converter=None, **data): def report_routes(self, reportname, docids=None, converter=None, **data):
# Trick the main reporter to think we want an HTML report
new_converter = converter if converter != "xml" else "html"
response = super(ReportController, self).report_routes(
reportname, docids, new_converter, **data)
# If it was an XML report, just download the generated response
if converter == "xml":
# XML header must be before any spaces, and it is a common error,
# so let's fix that here and make developers happier
response.data = response.data.strip()
response.headers.set("Content-Type", "text/xml")
response.headers.set('Content-length', len(response.data))
# set filename
action_report_obj = request.env['ir.actions.report']
report = action_report_obj._get_report_from_name(reportname)
filename = report.name
if converter == 'xml':
report = request.env['ir.actions.report']._get_report_from_name(
reportname)
context = dict(request.env.context)
if docids:
docids = [int(i) for i in docids.split(',')]
if data.get('options'):
data.update(json.loads(data.pop('options')))
if data.get('context'):
# Ignore 'lang' here, because the context in data is the one
# from the webclient *but* if the user explicitely wants to
# change the lang, this mechanism overwrites it.
data['context'] = json.loads(data['context'])
if data['context'].get('lang'):
del data['context']['lang']
context.update(data['context'])
xml = report.with_context(context).render_qweb_xml(docids,
data=data)[0]
xmlhttpheaders = [('Content-Type', 'text/xml'),
('Content-Length', len(xml))]
return request.make_response(xml, headers=xmlhttpheaders)
else:
return super(ReportController, self).report_routes(
reportname, docids, converter, **data)
@route()
def report_download(self, data, token):
requestcontent = json.loads(data)
url, report_type = requestcontent[0], requestcontent[1]
if report_type == 'qweb-xml':
try:
reportname = url.split('/report/xml/')[1].split('?')[0]
docids = None
if '/' in reportname:
reportname, docids = reportname.split('/')
if docids:
# Generic report:
response = self.report_routes(
reportname, docids=docids, converter='xml')
else:
# Particular report:
# decoding the args represented in JSON
data = url_decode(url.split('?')[1]).items()
response = self.report_routes(
reportname, converter='xml', **dict(data))
report_obj = request.env['ir.actions.report']
report = report_obj._get_report_from_name(reportname)
filename = "%s.xml" % (report.name)
if docids: if docids:
ids = [int(x) for x in docids.split(",")] ids = [int(x) for x in docids.split(",")]
records = request.env[report.model].browse(ids) records = request.env[report.model].browse(ids)
if report.print_report_name and not len(records) > 1: if report.print_report_name and not len(records) > 1:
filename = safe_eval(report.print_report_name,
{'object': records, 'time': time})
response.headers.set(
'Content-Disposition',
content_disposition(filename + ".xml"))
report_name = safe_eval(report.print_report_name,
{'object': records,
'time': time})
filename = "%s.xml" % (report_name)
response.headers.add('Content-Disposition',
content_disposition(filename))
response.set_cookie('fileToken', token)
return response return response
except Exception as e:
se = serialize_exception(e)
error = {
'code': 200,
'message': "Odoo Server Error",
'data': se
}
return request.make_response(html_escape(json.dumps(error)))
else:
return super(ReportController, self).report_download(data, token)

5
report_xml/demo/report.xml

@ -1,16 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<odoo> <odoo>
<template id="demo_report_xml_view"> <template id="demo_report_xml_view">
<t t-call="report_xml.utf8_header">
<root> <root>
<user t-foreach="docs" t-as="doc"> <user t-foreach="docs" t-as="doc">
<name t-esc="doc.name"/> <name t-esc="doc.name"/>
<vat t-esc="doc.vat"/> <vat t-esc="doc.vat"/>
</user> </user>
</root> </root>
</t>
</template> </template>
<report id="demo_xml_report" <report id="demo_xml_report"
name="report_xml.demo_report_xml_view" name="report_xml.demo_report_xml_view"
string="Demo xml report" string="Demo xml report"
@ -18,5 +16,4 @@
print_report_name="'Demo xml report'" print_report_name="'Demo xml report'"
file="report_xml.xml" file="report_xml.xml"
model="res.company"/> model="res.company"/>
</odoo> </odoo>

1
report_xml/models/__init__.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html). # License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).
from . import report_action from . import report_action

27
report_xml/models/report_action.py

@ -1,14 +1,9 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2014-2015 Grupo ESOC <www.grupoesoc.es> # Copyright (C) 2014-2015 Grupo ESOC <www.grupoesoc.es>
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html). # License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).
import logging
from odoo import api, fields, models from odoo import api, fields, models
from lxml import etree from lxml import etree
_logger = logging.getLogger(__name__)
class ReportAction(models.Model): class ReportAction(models.Model):
_inherit = "ir.actions.report" _inherit = "ir.actions.report"
@ -16,23 +11,15 @@ class ReportAction(models.Model):
report_type = fields.Selection(selection_add=[("qweb-xml", "XML")]) report_type = fields.Selection(selection_add=[("qweb-xml", "XML")])
@api.model @api.model
def _get_report_from_name(self, report_name):
res = super(ReportAction, self)._get_report_from_name(report_name)
if res:
return res
report_obj = self.env['ir.actions.report']
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)
@api.model
def render_qweb_xml(self, docids, data):
result = self.render_qweb_html(docids, data=data)
def render_qweb_xml(self, docids, data=None):
if not data:
data = {}
data.setdefault('report_type', 'text')
data = self._get_rendering_context(docids, data)
result = self.render_template(self.report_name, data)
return etree.tostring( return etree.tostring(
etree.fromstring( etree.fromstring(
str(result[0], 'UTF-8').lstrip('\n').lstrip().encode('UTF-8')
str(result, 'UTF-8').lstrip('\n').lstrip().encode('UTF-8')
), ),
encoding='UTF-8', encoding='UTF-8',
xml_declaration=True, xml_declaration=True,

4
report_xml/readme/CONTRIBUTORS.rst

@ -0,0 +1,4 @@
* Enric Tobella <etobella@creublanca.es>
* `Tecnativa <https://www.tecnativa.com>`_:
Jairo Llopis

1
report_xml/readme/CREDITS.rst

@ -0,0 +1 @@
* Icon taken from http://commons.wikimedia.org/wiki/File:Text-xml.svg

3
report_xml/readme/DESCRIPTION.rst

@ -0,0 +1,3 @@
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
templates.

10
report_xml/readme/INSTALL.rst

@ -0,0 +1,10 @@
To install this module, you need to:
* Install lxml_ in Odoo's ``$PYTHONPATH``.
* Install the repository `reporting-engine`_.
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.
.. _reporting-engine: https://github.com/OCA/reporting-engine
.. _lxml: http://lxml.de/

35
report_xml/readme/USAGE.rst

@ -0,0 +1,35 @@
This module is intended as a base engine for other modules to use it, so no direct result if you are a user.
If you are a developer
~~~~~~~~~~~~~~~~~~~~~~
To learn from an example, just check the `sample module`_.
To develop with this module, you need to:
* Create a module.
* Make it depend on this one.
* Follow `instructions to create reports`_ having in mind that the
``report_type`` field in your ``ir.actions.report.xml`` record must be
``qweb-xml``.
In case you want to create a `custom report`_, the instructions remain the same
as for HTML reports, and the method that you must override is also called
``_get_report_values``, even when this time you are creating a XML report.
You can make your custom report inherit ``report_xml.xsd_checked_report``, name
it like your XML ``<template>`` id prepended by ``report.``, add a ``xsd()``
method that returns a XSD in a string, and have XSD automatic checking for
free.
You can visit ``http://<server-address>/report/xml/<module.report_name>/<ids>``
to see your XML report online as a web page.
For further information, please visit:
* https://www.odoo.com/forum/help-1
* https://github.com/OCA/reporting-engine
.. _custom report: https://www.odoo.com/documentation/12.0/reference/reports.html#custom-reports
.. _instructions to create reports: https://www.odoo.com/documentation/12.0/reference/reports.html
.. _sample module: https://github.com/OCA/reporting-engine/tree/12.0/report_xml_sample

13
report_xml/static/description/icon.svg

@ -1,16 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
id="svg2"
version="1.1"
viewBox="-66 148 822 822"
height="822"
width="822">
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="svg2" version="1.1" viewBox="-66 148 822 822" height="822" width="822">
<defs <defs
id="defs4"> id="defs4">
<linearGradient <linearGradient

477
report_xml/static/description/index.html

@ -0,0 +1,477 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" />
<title>XML Reports</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="xml-reports">
<h1 class="title">XML Reports</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/reporting-engine/tree/12.0/report_xml"><img alt="OCA/reporting-engine" src="https://img.shields.io/badge/github-OCA%2Freporting--engine-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/reporting-engine-12-0/reporting-engine-12-0-report_xml"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/143/12.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>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
templates.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#installation" id="id1">Installation</a></li>
<li><a class="reference internal" href="#usage" id="id2">Usage</a><ul>
<li><a class="reference internal" href="#if-you-are-a-developer" id="id3">If you are a developer</a></li>
</ul>
</li>
<li><a class="reference internal" href="#bug-tracker" id="id4">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id5">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id6">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id7">Contributors</a></li>
<li><a class="reference internal" href="#other-credits" id="id8">Other credits</a></li>
<li><a class="reference internal" href="#maintainers" id="id9">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="installation">
<h1><a class="toc-backref" href="#id1">Installation</a></h1>
<p>To install this module, you need to:</p>
<ul class="simple">
<li>Install <a class="reference external" href="http://lxml.de/">lxml</a> in Odoo’s <tt class="docutils literal">$PYTHONPATH</tt>.</li>
<li>Install the repository <a class="reference external" href="https://github.com/OCA/reporting-engine">reporting-engine</a>.</li>
</ul>
<p>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.</p>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#id2">Usage</a></h1>
<p>This module is intended as a base engine for other modules to use it, so no direct result if you are a user.</p>
<div class="section" id="if-you-are-a-developer">
<h2><a class="toc-backref" href="#id3">If you are a developer</a></h2>
<p>To learn from an example, just check the <a class="reference external" href="https://github.com/OCA/reporting-engine/tree/12.0/report_xml_sample">sample module</a>.</p>
<p>To develop with this module, you need to:</p>
<ul class="simple">
<li>Create a module.</li>
<li>Make it depend on this one.</li>
<li>Follow <a class="reference external" href="https://www.odoo.com/documentation/12.0/reference/reports.html">instructions to create reports</a> having in mind that the
<tt class="docutils literal">report_type</tt> field in your <tt class="docutils literal">ir.actions.report.xml</tt> record must be
<tt class="docutils literal"><span class="pre">qweb-xml</span></tt>.</li>
</ul>
<p>In case you want to create a <a class="reference external" href="https://www.odoo.com/documentation/12.0/reference/reports.html#custom-reports">custom report</a>, the instructions remain the same
as for HTML reports, and the method that you must override is also called
<tt class="docutils literal">_get_report_values</tt>, even when this time you are creating a XML report.</p>
<p>You can make your custom report inherit <tt class="docutils literal">report_xml.xsd_checked_report</tt>, name
it like your XML <tt class="docutils literal">&lt;template&gt;</tt> id prepended by <tt class="docutils literal">report.</tt>, add a <tt class="docutils literal">xsd()</tt>
method that returns a XSD in a string, and have XSD automatic checking for
free.</p>
<p>You can visit <tt class="docutils literal"><span class="pre">http://&lt;server-address&gt;/report/xml/&lt;module.report_name&gt;/&lt;ids&gt;</span></tt>
to see your XML report online as a web page.</p>
<p>For further information, please visit:</p>
<ul class="simple">
<li><a class="reference external" href="https://www.odoo.com/forum/help-1">https://www.odoo.com/forum/help-1</a></li>
<li><a class="reference external" href="https://github.com/OCA/reporting-engine">https://github.com/OCA/reporting-engine</a></li>
</ul>
</div>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id4">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/reporting-engine/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/reporting-engine/issues/new?body=module:%20report_xml%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#id5">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id6">Authors</a></h2>
<ul class="simple">
<li>Tecnativa</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id7">Contributors</a></h2>
<ul>
<li><p class="first">Enric Tobella &lt;<a class="reference external" href="mailto:etobella&#64;creublanca.es">etobella&#64;creublanca.es</a>&gt;</p>
</li>
<li><p class="first"><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a>:</p>
<p>Jairo Llopis</p>
</li>
</ul>
</div>
<div class="section" id="other-credits">
<h2><a class="toc-backref" href="#id8">Other credits</a></h2>
<ul class="simple">
<li>Icon taken from <a class="reference external" href="http://commons.wikimedia.org/wiki/File:Text-xml.svg">http://commons.wikimedia.org/wiki/File:Text-xml.svg</a></li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id9">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/reporting-engine/tree/12.0/report_xml">OCA/reporting-engine</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

20
report_xml/static/src/js/report/action_manager_report.js

@ -0,0 +1,20 @@
odoo.define('report_xml.ReportActionManager', function(require){
'use strict';
var ActionManager = require('web.ActionManager');
ActionManager.include({
_executeReportAction: function (action, options) {
if (action.report_type === 'qweb-xml') {
return this._triggerDownload(action, options, 'xml');
}
return this._super(action, options);
},
_makeReportUrls: function (action) {
var reportUrls = this._super(action);
reportUrls.xml = reportUrls.text.replace(
'/report/text/', '/report/xml/');
return reportUrls;
},
});
});

41
report_xml/static/src/js/report/qwebactionmanager.js

@ -1,41 +0,0 @@
odoo.define('report_xml.report', function(require){
'use strict';
var ActionManager= require('web.ActionManager');
var crash_manager = require('web.crash_manager');
var framework = require('web.framework');
ActionManager.include({
ir_actions_report: function (action, options){
var self = this;
action = _.clone(action);
if (action.report_type === 'qweb-xml') {
framework.blockUI()
var report_xml_url = 'report/xml/' + action.report_name;
if(action.context.active_ids){
report_xml_url += '/' + action.context.active_ids.join(',');
}
else{
report_xml_url += '?options=' + encodeURIComponent(JSON.stringify(action.data));
report_xml_url += '&context=' + encodeURIComponent(JSON.stringify(action.context));
}
self.getSession().get_file({
url: report_xml_url,
data: {data: JSON.stringify([
report_xml_url,
action.report_type,
])},
error: crash_manager.rpc_error.bind(crash_manager),
success: function (){
if(action && options && !action.dialog){
options.on_close();
}
},
});
framework.unblockUI();
return
}
return self._super(action, options);
}
});
});

1
report_xml/tests/__init__.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html). # License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).
from . import test_report_xml from . import test_report_xml

1
report_xml/tests/test_report_xml.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Creu Blanca # Copyright 2017 Creu Blanca
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl). # License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl).

13
report_xml/views/ir_actions_views.xml

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="act_report_xml_view" model="ir.ui.view">
<field name="name">ir.actions.report.report.xml</field>
<field name="model">ir.actions.report</field>
<field name="inherit_id" ref="base.act_report_xml_view"/>
<field name="arch" type="xml">
<button name="associated_view" position="attributes">
<attribute name="attrs">{'invisible':[('report_type', 'not in', ['qweb-pdf', 'qweb-html', 'qweb-text', 'qweb-xml'])]}</attribute>
</button>
</field>
</record>
</odoo>

9
report_xml/views/report_xml_templates.xml

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="utf8_header">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
<t t-raw="0"/>
</template>
</odoo>

3
report_xml/views/webclient_templates.xml

@ -2,8 +2,7 @@
<odoo> <odoo>
<template id="report_xml.assets_backend" inherit_id="web.assets_backend"> <template id="report_xml.assets_backend" inherit_id="web.assets_backend">
<xpath expr="." position="inside"> <xpath expr="." position="inside">
<script type="text/javascript" src="/report_xml/static/src/js/report/qwebactionmanager.js"/>
<script type="text/javascript" src="/report_xml/static/src/js/report/action_manager_report.js"/>
</xpath> </xpath>
</template> </template>
</odoo> </odoo>
Loading…
Cancel
Save