Skip to content

Commit ee72b6d

Browse files
committed
Merge PR #1072 into 19.0
Signed-off-by pedrobaeza
2 parents ea06cd3 + acd45cc commit ee72b6d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+12426
-0
lines changed

report_xml/README.rst

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
.. image:: https://odoo-community.org/readme-banner-image
2+
:target: https://odoo-community.org/get-involved?utm_source=readme
3+
:alt: Odoo Community Association
4+
5+
===========
6+
XML Reports
7+
===========
8+
9+
..
10+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
11+
!! This file is generated by oca-gen-addon-readme !!
12+
!! changes will be overwritten. !!
13+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
14+
!! source digest: sha256:ae8dbb5c7fd44cf63b6044b05c8f8dc9146a383e2e5176552c8af4d2adda50e8
15+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
16+
17+
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
18+
:target: https://odoo-community.org/page/development-status
19+
:alt: Production/Stable
20+
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
21+
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
22+
:alt: License: AGPL-3
23+
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Freporting--engine-lightgray.png?logo=github
24+
:target: https://github.com/OCA/reporting-engine/tree/19.0/report_xml
25+
:alt: OCA/reporting-engine
26+
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
27+
:target: https://translation.odoo-community.org/projects/reporting-engine-19-0/reporting-engine-19-0-report_xml
28+
:alt: Translate me on Weblate
29+
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
30+
:target: https://runboat.odoo-community.org/builds?repo=OCA/reporting-engine&target_branch=19.0
31+
:alt: Try me on Runboat
32+
33+
|badge1| |badge2| |badge3| |badge4| |badge5|
34+
35+
This module was written to extend the functionality of the reporting
36+
engine to support XML reports and allow modules to generate them by code
37+
or by QWeb templates.
38+
39+
**Table of contents**
40+
41+
.. contents::
42+
:local:
43+
44+
Use Cases / Context
45+
===================
46+
47+
We create this module to allow the system to generate and download XMLs
48+
as reports.
49+
50+
Otherwise, the system can generate XMLs, but will be downloaded as HTML
51+
or PDF.
52+
53+
Installation
54+
============
55+
56+
To install this module, you need to:
57+
58+
- Install `lxml <http://lxml.de/>`__ in Odoo's ``$PYTHONPATH``.
59+
- Install the repository
60+
`reporting-engine <https://github.com/OCA/reporting-engine>`__.
61+
62+
But this module does nothing for the end user by itself, so if you have
63+
it installed it's probably because there is another module that depends
64+
on it.
65+
66+
Usage
67+
=====
68+
69+
This module is intended as a base engine for other modules to use it, so
70+
no direct result if you are a user.
71+
72+
If you are a developer
73+
----------------------
74+
75+
To learn from an example, just check the `demo
76+
report <https://github.com/OCA/reporting-engine/blob/13.0/report_xml/demo/demo_report.xml>`__
77+
on GitHub for the model ``res.company`` or check it in interface from
78+
companies views.
79+
80+
To develop with this module, you need to:
81+
82+
- Create a module.
83+
- Make it depend on this one.
84+
- Follow `instructions to create
85+
reports <https://www.odoo.com/documentation/13.0/reference/reports.html>`__
86+
having in mind that the ``report_type`` field in your
87+
``ir.actions.report`` record must be ``qweb-xml``.
88+
89+
In case you want to create a `custom
90+
report <https://www.odoo.com/documentation/13.0/reference/reports.html#custom-reports>`__,
91+
the instructions remain the same as for HTML reports, and the method
92+
that you must override is also called ``_get_report_values``, even when
93+
this time you are creating a XML report.
94+
95+
You can make your custom report inherit ``report.report_xml.abstract``,
96+
name it in such way ``report.<module.report_name>``. Also you can add a
97+
XSD file for report validation into ``xsd_schema`` field of your report
98+
(check `report
99+
definition <https://github.com/OCA/reporting-engine/blob/13.0/report_xml/demo/report.xml>`__)
100+
and have XSD automatic checking for free.
101+
102+
You can customize rendering process and validation way via changing
103+
logic of ``generate_report`` and ``validate_report`` methods in your
104+
report class.
105+
106+
You can visit
107+
``http://<server-address>/report/xml/<module.report_name>/<ids>`` to see
108+
your XML report online as a web page.
109+
110+
For further information, please visit:
111+
112+
- https://www.odoo.com/forum/help-1
113+
- https://github.com/OCA/reporting-engine
114+
115+
Bug Tracker
116+
===========
117+
118+
Bugs are tracked on `GitHub Issues <https://github.com/OCA/reporting-engine/issues>`_.
119+
In case of trouble, please check there if your issue has already been reported.
120+
If you spotted it first, help us to smash it by providing a detailed and welcomed
121+
`feedback <https://github.com/OCA/reporting-engine/issues/new?body=module:%20report_xml%0Aversion:%2019.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
122+
123+
Do not contact contributors directly about support or help with technical issues.
124+
125+
Credits
126+
=======
127+
128+
Authors
129+
-------
130+
131+
* Tecnativa
132+
* Avoin.Systems
133+
134+
Contributors
135+
------------
136+
137+
- `Dixmit <https://www.dixmit.com>`__
138+
139+
- Enric Tobella
140+
141+
- `Tecnativa <https://www.tecnativa.com>`__:
142+
143+
- Jairo Llopis
144+
145+
- `Avoin.Systems <https://avoin.systems/>`__:
146+
147+
- Tatiana Deribina
148+
149+
- Iván Antón <[email protected]>
150+
151+
Other credits
152+
-------------
153+
154+
- Icon taken from http://commons.wikimedia.org/wiki/File:Text-xml.svg
155+
156+
Maintainers
157+
-----------
158+
159+
This module is maintained by the OCA.
160+
161+
.. image:: https://odoo-community.org/logo.png
162+
:alt: Odoo Community Association
163+
:target: https://odoo-community.org
164+
165+
OCA, or the Odoo Community Association, is a nonprofit organization whose
166+
mission is to support the collaborative development of Odoo features and
167+
promote its widespread use.
168+
169+
This module is part of the `OCA/reporting-engine <https://github.com/OCA/reporting-engine/tree/19.0/report_xml>`_ project on GitHub.
170+
171+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

report_xml/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).
2+
3+
from . import controllers
4+
from . import models
5+
from . import reports
6+
from .hooks import post_init_hook

report_xml/__manifest__.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright (C) 2014-2015 Grupo ESOC <www.grupoesoc.es>
2+
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).
3+
{
4+
"name": "XML Reports",
5+
"version": "19.0.1.0.0",
6+
"category": "Reporting",
7+
"website": "https://github.com/OCA/reporting-engine",
8+
"development_status": "Production/Stable",
9+
"author": "Tecnativa, Odoo Community Association (OCA), Avoin.Systems",
10+
"license": "AGPL-3",
11+
"installable": True,
12+
"application": False,
13+
"summary": "Allow to generate XML reports",
14+
"depends": ["web"],
15+
"data": [
16+
"views/ir_actions_report_view.xml",
17+
],
18+
"assets": {
19+
"web.assets_backend": [
20+
"report_xml/static/src/js/report/action_manager_report.esm.js",
21+
],
22+
},
23+
"demo": [
24+
"demo/report.xml", # register report in the system
25+
"demo/demo_report.xml", # report body definition
26+
],
27+
"post_init_hook": "post_init_hook",
28+
}

report_xml/controllers/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).
2+
3+
from . import report

report_xml/controllers/report.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Copyright (C) 2014-2015 Grupo ESOC <www.grupoesoc.es>
2+
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).
3+
4+
import json
5+
import logging
6+
7+
from werkzeug.urls import url_parse
8+
9+
from odoo.http import content_disposition, request, route, serialize_exception
10+
from odoo.tools import html_escape
11+
from odoo.tools.safe_eval import safe_eval, time
12+
13+
from odoo.addons.web.controllers import report
14+
15+
_logger = logging.getLogger(__name__)
16+
17+
18+
class ReportController(report.ReportController):
19+
@route()
20+
def report_routes(
21+
self, reportname, docids=None, converter=None, options=None, **kwargs
22+
):
23+
if converter != "xml":
24+
return super().report_routes(
25+
reportname,
26+
docids=docids,
27+
converter=converter,
28+
options=options,
29+
**kwargs,
30+
)
31+
if docids:
32+
docids = [int(_id) for _id in docids.split(",")]
33+
data = {**json.loads(options or "{}"), **kwargs}
34+
context = dict(request.env.context)
35+
if "context" in data:
36+
data["context"] = json.loads(data["context"] or "{}")
37+
# Ignore 'lang' here, because the context in data is the one from the
38+
# webclient *but* if the user explicitely wants to change the lang, this
39+
# mechanism overwrites it.
40+
if "lang" in data["context"]:
41+
del data["context"]["lang"]
42+
context.update(data["context"])
43+
report_Obj = request.env["ir.actions.report"]
44+
xml = report_Obj.with_context(**context)._render_qweb_xml(
45+
reportname, docids, data=data
46+
)[0]
47+
xmlhttpheaders = [("Content-Type", "text/xml"), ("Content-Length", len(xml))]
48+
return request.make_response(xml, headers=xmlhttpheaders)
49+
50+
@route()
51+
def report_download(self, data, context=None, token=None, readonly=True):
52+
requestcontent = json.loads(data)
53+
url, report_type = requestcontent[0], requestcontent[1]
54+
reportname = "???"
55+
if report_type != "qweb-xml":
56+
return super().report_download(
57+
data, context, token=token, readonly=readonly
58+
)
59+
try:
60+
reportname = url.split("/report/xml/")[1].split("?")[0]
61+
docids = None
62+
if "/" in reportname:
63+
reportname, docids = reportname.split("/")
64+
report = request.env["ir.actions.report"]._get_report_from_name(reportname)
65+
filename = None
66+
if docids:
67+
response = self.report_routes(
68+
reportname, docids=docids, converter="xml", context=context
69+
)
70+
ids = [int(x) for x in docids.split(",")]
71+
obj = request.env[report.model].browse(ids)
72+
if report.print_report_name and not len(obj) > 1:
73+
report_name = safe_eval(
74+
report.print_report_name, {"object": obj, "time": time}
75+
)
76+
filename = f"{report_name}.{report.xml_extension}"
77+
else:
78+
data = url_parse(url).decode_query(cls=dict)
79+
if "context" in data:
80+
context = json.loads(context or "{}")
81+
data_context = json.loads(data.pop("context"))
82+
context = json.dumps({**context, **data_context})
83+
response = self.report_routes(
84+
reportname, converter="xml", context=context, **data
85+
)
86+
filename = filename or f"{report.name}.{report.xml_extension}"
87+
response.headers.add("Content-Disposition", content_disposition(filename))
88+
return response
89+
except Exception as e:
90+
_logger.exception(f"Error while generating report {reportname}")
91+
se = serialize_exception(e)
92+
error = {"code": 200, "message": "Odoo Server Error", "data": se}
93+
return request.make_response(html_escape(json.dumps(error)))

report_xml/demo/demo_report.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<odoo>
3+
<template id="demo_report_xml_view">
4+
<root>
5+
<user t-foreach="docs" t-as="doc">
6+
<id t-esc="doc.id" />
7+
<name t-esc="doc.name" />
8+
<vat t-esc="doc.vat" />
9+
</user>
10+
</root>
11+
</template>
12+
</odoo>

report_xml/demo/demo_report.xsd

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3+
4+
<xs:element name="root" type="root_type" />
5+
6+
<xs:complexType name="root_type">
7+
<xs:sequence>
8+
<xs:element
9+
name="user"
10+
type="user_type"
11+
minOccurs="0"
12+
maxOccurs="unbounded"
13+
/>
14+
</xs:sequence>
15+
</xs:complexType>
16+
17+
<xs:complexType name="user_type">
18+
<xs:sequence>
19+
<xs:element name="id" type="xs:int" />
20+
<xs:element name="name" type="xs:string" />
21+
<xs:element name="vat" type="xs:string" minOccurs="0" />
22+
</xs:sequence>
23+
</xs:complexType>
24+
25+
</xs:schema>

report_xml/demo/report.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<odoo>
3+
<record id="demo_xml_report" model="ir.actions.report">
4+
<field name="name">Demo xml report</field>
5+
<field name="model">res.company</field>
6+
<field name="report_type">qweb-xml</field>
7+
<field name="report_name">report_xml.demo_report_xml_view</field>
8+
<field name="report_file">res_company</field>
9+
<field name="binding_model_id" ref="base.model_res_company" />
10+
<field name="binding_type">report</field>
11+
<!--
12+
In case of demo data next definition will not work. So it just example
13+
how it should look. If report is a part of demo data you will need
14+
add file to report instance via `post_install_hook`
15+
-->
16+
<field name="xsd_schema" type="base64" file="report_xml/demo/demo_report.xsd" />
17+
</record>
18+
</odoo>

0 commit comments

Comments
 (0)