Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
6056c1d
Add module report_xml.
Jun 1, 2015
5e05153
Add template utf8_header.
Jun 12, 2015
fb729cb
Easier XSD checking reports.
Jun 12, 2015
f4b32cd
Add sample module.
Jun 12, 2015
6cfa8df
Sort links.
Jun 12, 2015
739e910
Fix XML tag mismatch.
Jun 12, 2015
56718b8
Allow docargs to be loaded from context.
Jun 15, 2015
c89a557
Only replace the docs key if it is missing.
Jun 15, 2015
9a86bc1
Clearer code comments, add logging.
Jun 15, 2015
9c56eba
Oops, this header belongs to other module.
Jun 17, 2015
4adedde
Add module report_xml_sample.
Jun 17, 2015
f73f159
Clean AGPL garbage preserving copyright.
Jul 3, 2015
e6b41bc
Return supers.
Oct 15, 2015
792cf05
Credit creators, using same name across modules to avoid split statis…
Jan 5, 2016
06f2b35
prefix versions with 8.0
sbidoul Oct 8, 2016
43ca169
[MIG] report_xml: Migration to 10.0
etobella Jun 23, 2017
2f0eb42
OCA Transbot updated translations from Transifex
oca-transbot Mar 13, 2016
dbde390
[MIG] report_xml: Migration to 11.0
etobella Oct 5, 2017
66b0f29
OCA Transbot updated translations from Transifex
oca-transbot Mar 3, 2018
330cda0
[IMP] report_fillpdf, report_xlsx, report_xml: Use content_dispositio…
naglis Mar 11, 2018
87d00a4
[FIX] report_xml readme
tarteo Jul 18, 2018
c290973
[UPD] Update report_xml.pot
oca-travis Jul 24, 2018
78a861e
[IMP] report_xml: Clarification in README
pedrobaeza Dec 20, 2018
9ab53da
report_xml: add custom filename to response headers
ernestotejeda May 24, 2019
fe6452b
[MIG] report_xml: Migration to 12.0
ernestotejeda Jun 10, 2019
3a9c181
[UPD] Update report_xml.pot
oca-travis Jun 12, 2019
6d83129
Update translation files
oca-transbot Jun 16, 2019
a9bcd2a
[UPD] README.rst
OCA-git-bot Jul 31, 2019
74ef6e3
[IMP] report_xml: black, isort
Tatider Dec 20, 2019
1fe7248
[MIG][13.0] report_xml: Migration to 13.0
Tatider Dec 23, 2019
fb31353
[UPD] Update report_xml.pot
oca-travis Apr 24, 2020
0196028
[UPD] README.rst
OCA-git-bot Apr 24, 2020
333c97b
Update translation files
oca-transbot May 13, 2020
a63f561
Update translation files
oca-transbot Aug 16, 2020
e45e199
[IMP] report_xml: black, isort, prettier
ozono Jan 25, 2021
cea9416
[MIG] report_xml: Migration to 14.0
ozono Jan 25, 2021
aaf17d4
[UPD] Update report_xml.pot
oca-travis May 26, 2021
f01b82d
[UPD] README.rst
OCA-git-bot May 26, 2021
30e3170
report_xml: context and safe_eval fix
Du-ma Jun 4, 2021
1cf7690
report_xml 14.0.1.0.1
OCA-git-bot Jun 9, 2021
6e786a0
[IMP] report_xml: black, isort, prettier
aisopuro Nov 25, 2021
3239f91
[MIG] report_xml: migrate 14 -> 15
aisopuro Nov 26, 2021
3b241e7
[UPD] Update report_xml.pot
Jan 17, 2022
9e788fc
[UPD] README.rst
OCA-git-bot Jan 17, 2022
0993d74
[IMP] report_xml: Promote to Stable
etobella Apr 19, 2022
13bed22
[UPD] README.rst
OCA-git-bot Apr 21, 2022
4de285e
report_xml 15.0.1.0.1
OCA-git-bot Apr 21, 2022
2bdf833
Translated using Weblate (Catalan)
jabelchi Jun 15, 2022
33a5503
[MIG] report_xml: Migration to 16.0
Du-ma Oct 18, 2022
b8de4ba
[UPD] Update report_xml.pot
Oct 19, 2022
5c60bfb
[UPD] README.rst
OCA-git-bot Oct 19, 2022
9a075f6
Update translation files
weblate Oct 19, 2022
ea147ce
[IMP] update dotfiles [ci skip]
OCA-git-bot Dec 11, 2022
6e95917
[16.0][IMP] report_xml: Added xml_extension
Mantux11 Jan 27, 2023
9b5fdbc
[UPD] Update report_xml.pot
Mar 6, 2023
ab70412
report_xml 16.0.1.1.0
OCA-git-bot Mar 6, 2023
17afd49
Update translation files
weblate Mar 6, 2023
2669801
[UPD] README.rst
OCA-git-bot Sep 3, 2023
4f1351f
fix for report.py per docids = none
TennyMkt Sep 14, 2023
d45cd2f
[BOT] post-merge updates
OCA-git-bot Nov 18, 2023
1e056ff
[IMP] report_xml: pre-commit auto fixes
viktor-anikeenko-avsys Dec 7, 2023
932e06b
[MIG] report_xml: Migration to 17.0
viktor-anikeenko-avsys Dec 7, 2023
addbc47
[UPD] Update report_xml.pot
Feb 5, 2024
33ce284
[BOT] post-merge updates
OCA-git-bot Feb 5, 2024
1b25619
Translated using Weblate (Spanish)
Ivorra78 Feb 11, 2024
d765c6f
Translated using Weblate (Italian)
mymage Feb 12, 2024
8f4391b
Translated using Weblate (Swedish)
jakobkrabbe Jun 12, 2024
0a5a69f
[MIG] report_xml: Migration to 18.0
dariodelzozzo Sep 12, 2024
ef64710
[UPD] Update report_xml.pot
Mar 6, 2025
a8f5e24
[BOT] post-merge updates
OCA-git-bot Mar 6, 2025
f3e0155
Translated using Weblate (Italian)
mymage Jul 24, 2025
c9239ca
[FIX] *: align inherited method signature with odoo update
niyasraphy Aug 24, 2025
efe6b97
[BOT] post-merge updates
OCA-git-bot Aug 25, 2025
3b7b138
Translated using Weblate (Turkish)
tsezgin Sep 11, 2025
acd45cc
[MIG] report_xml: Migration to 19.0
etobella Oct 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 171 additions & 0 deletions report_xml/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

===========
XML Reports
===========

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:ae8dbb5c7fd44cf63b6044b05c8f8dc9146a383e2e5176552c8af4d2adda50e8
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
:target: https://odoo-community.org/page/development-status
:alt: Production/Stable
.. |badge2| image:: https://img.shields.io/badge/license-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/19.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-19-0/reporting-engine-19-0-report_xml
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/reporting-engine&target_branch=19.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

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.

**Table of contents**

.. contents::
:local:

Use Cases / Context
===================

We create this module to allow the system to generate and download XMLs
as reports.

Otherwise, the system can generate XMLs, but will be downloaded as HTML
or PDF.

Installation
============

To install this module, you need to:

- Install `lxml <http://lxml.de/>`__ in Odoo's ``$PYTHONPATH``.
- Install the repository
`reporting-engine <https://github.com/OCA/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.

Usage
=====

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 `demo
report <https://github.com/OCA/reporting-engine/blob/13.0/report_xml/demo/demo_report.xml>`__
on GitHub for the model ``res.company`` or check it in interface from
companies views.

To develop with this module, you need to:

- Create a module.
- Make it depend on this one.
- Follow `instructions to create
reports <https://www.odoo.com/documentation/13.0/reference/reports.html>`__
having in mind that the ``report_type`` field in your
``ir.actions.report`` record must be ``qweb-xml``.

In case you want to create a `custom
report <https://www.odoo.com/documentation/13.0/reference/reports.html#custom-reports>`__,
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.report_xml.abstract``,
name it in such way ``report.<module.report_name>``. Also you can add a
XSD file for report validation into ``xsd_schema`` field of your report
(check `report
definition <https://github.com/OCA/reporting-engine/blob/13.0/report_xml/demo/report.xml>`__)
and have XSD automatic checking for free.

You can customize rendering process and validation way via changing
logic of ``generate_report`` and ``validate_report`` methods in your
report class.

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

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 to smash it by providing a detailed and welcomed
`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**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Tecnativa
* Avoin.Systems

Contributors
------------

- `Dixmit <https://www.dixmit.com>`__

- Enric Tobella

- `Tecnativa <https://www.tecnativa.com>`__:

- Jairo Llopis

- `Avoin.Systems <https://avoin.systems/>`__:

- Tatiana Deribina

- Iván Antón <[email protected]>

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
:alt: Odoo Community Association
:target: https://odoo-community.org

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.

This module is part of the `OCA/reporting-engine <https://github.com/OCA/reporting-engine/tree/19.0/report_xml>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
6 changes: 6 additions & 0 deletions report_xml/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).

from . import controllers
from . import models
from . import reports
from .hooks import post_init_hook
28 changes: 28 additions & 0 deletions report_xml/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright (C) 2014-2015 Grupo ESOC <www.grupoesoc.es>
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).
{
"name": "XML Reports",
"version": "19.0.1.0.0",
"category": "Reporting",
"website": "https://github.com/OCA/reporting-engine",
"development_status": "Production/Stable",
"author": "Tecnativa, Odoo Community Association (OCA), Avoin.Systems",
"license": "AGPL-3",
"installable": True,
"application": False,
"summary": "Allow to generate XML reports",
"depends": ["web"],
"data": [
"views/ir_actions_report_view.xml",
],
"assets": {
"web.assets_backend": [
"report_xml/static/src/js/report/action_manager_report.esm.js",
],
},
"demo": [
"demo/report.xml", # register report in the system
"demo/demo_report.xml", # report body definition
],
"post_init_hook": "post_init_hook",
}
3 changes: 3 additions & 0 deletions report_xml/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).

from . import report
93 changes: 93 additions & 0 deletions report_xml/controllers/report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Copyright (C) 2014-2015 Grupo ESOC <www.grupoesoc.es>
# License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).

import json
import logging

from werkzeug.urls import url_parse

from odoo.http import content_disposition, request, route, serialize_exception
from odoo.tools import html_escape
from odoo.tools.safe_eval import safe_eval, time

from odoo.addons.web.controllers import report

_logger = logging.getLogger(__name__)


class ReportController(report.ReportController):
@route()
def report_routes(
self, reportname, docids=None, converter=None, options=None, **kwargs
):
if converter != "xml":
return super().report_routes(
reportname,
docids=docids,
converter=converter,
options=options,
**kwargs,
)
if docids:
docids = [int(_id) for _id in docids.split(",")]
data = {**json.loads(options or "{}"), **kwargs}
context = dict(request.env.context)
if "context" in data:
data["context"] = json.loads(data["context"] or "{}")
# 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.
if "lang" in data["context"]:
del data["context"]["lang"]
context.update(data["context"])
report_Obj = request.env["ir.actions.report"]
xml = report_Obj.with_context(**context)._render_qweb_xml(
reportname, docids, data=data
)[0]
xmlhttpheaders = [("Content-Type", "text/xml"), ("Content-Length", len(xml))]
return request.make_response(xml, headers=xmlhttpheaders)

@route()
def report_download(self, data, context=None, token=None, readonly=True):
requestcontent = json.loads(data)
url, report_type = requestcontent[0], requestcontent[1]
reportname = "???"
if report_type != "qweb-xml":
return super().report_download(
data, context, token=token, readonly=readonly
)
try:
reportname = url.split("/report/xml/")[1].split("?")[0]
docids = None
if "/" in reportname:
reportname, docids = reportname.split("/")
report = request.env["ir.actions.report"]._get_report_from_name(reportname)
filename = None
if docids:
response = self.report_routes(
reportname, docids=docids, converter="xml", context=context
)
ids = [int(x) for x in docids.split(",")]
obj = request.env[report.model].browse(ids)
if report.print_report_name and not len(obj) > 1:
report_name = safe_eval(
report.print_report_name, {"object": obj, "time": time}
)
filename = f"{report_name}.{report.xml_extension}"
else:
data = url_parse(url).decode_query(cls=dict)
if "context" in data:
context = json.loads(context or "{}")
data_context = json.loads(data.pop("context"))
context = json.dumps({**context, **data_context})
response = self.report_routes(
reportname, converter="xml", context=context, **data
)
filename = filename or f"{report.name}.{report.xml_extension}"
response.headers.add("Content-Disposition", content_disposition(filename))
return response
except Exception as e:
_logger.exception(f"Error while generating report {reportname}")
se = serialize_exception(e)
error = {"code": 200, "message": "Odoo Server Error", "data": se}
return request.make_response(html_escape(json.dumps(error)))
12 changes: 12 additions & 0 deletions report_xml/demo/demo_report.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<template id="demo_report_xml_view">
<root>
<user t-foreach="docs" t-as="doc">
<id t-esc="doc.id" />
<name t-esc="doc.name" />
<vat t-esc="doc.vat" />
</user>
</root>
</template>
</odoo>
25 changes: 25 additions & 0 deletions report_xml/demo/demo_report.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="root" type="root_type" />

<xs:complexType name="root_type">
<xs:sequence>
<xs:element
name="user"
type="user_type"
minOccurs="0"
maxOccurs="unbounded"
/>
</xs:sequence>
</xs:complexType>

<xs:complexType name="user_type">
<xs:sequence>
<xs:element name="id" type="xs:int" />
<xs:element name="name" type="xs:string" />
<xs:element name="vat" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>

</xs:schema>
18 changes: 18 additions & 0 deletions report_xml/demo/report.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="demo_xml_report" model="ir.actions.report">
<field name="name">Demo xml report</field>
<field name="model">res.company</field>
<field name="report_type">qweb-xml</field>
<field name="report_name">report_xml.demo_report_xml_view</field>
<field name="report_file">res_company</field>
<field name="binding_model_id" ref="base.model_res_company" />
<field name="binding_type">report</field>
<!--
In case of demo data next definition will not work. So it just example
how it should look. If report is a part of demo data you will need
add file to report instance via `post_install_hook`
-->
<field name="xsd_schema" type="base64" file="report_xml/demo/demo_report.xsd" />
</record>
</odoo>
Loading