Merge PR #711 into 13.0

Signed-off-by thomaspaulb
pull/798/head
OCA-git-bot 2023-07-24 06:52:30 +00:00
commit b9cdde58d1
10 changed files with 126 additions and 17 deletions

View File

@ -32,6 +32,19 @@ This module provides a basic report class to generate csv report.
.. contents:: .. contents::
:local: :local:
Configuration
=============
In case the exported CSV report should be encoded in another system than UTF-8, following
fields of the report record (*Settings > Technical > Reports*) should be populated accordingly.
* Encoding: set an encoding system (such as cp932)
* Encode Error Handling: select 'Ignore' or 'Replace' as necessary.
* 'Ignore': in case of an encoding error, the problematic character will be removed from the exported file.
* 'Replace': in case of an encoding error, the problematic character will be replaced with '?' symbol.
* Leaving the field blank: in case of an encoding error, the report generation fails with an error message.
Usage Usage
===== =====
@ -74,6 +87,8 @@ A report XML record ::
attachment_use="False" attachment_use="False"
/> />
Update encoding with an appropriate value (e.g. cp932) as necessary.
Bug Tracker Bug Tracker
=========== ===========
@ -98,6 +113,9 @@ Contributors
* Enric Tobella <etobella@creublanca.es> * Enric Tobella <etobella@creublanca.es>
* Jaime Arroyo <jaime.arroyo@creublanca.es> * Jaime Arroyo <jaime.arroyo@creublanca.es>
* Rattapong Chokmasermkul <rattapongc@ecosoft.co.th> * Rattapong Chokmasermkul <rattapongc@ecosoft.co.th>
* `Quartile <https://www.quartile.co>`__:
* Aung Ko Ko Lin
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~

View File

@ -9,7 +9,7 @@
"version": "13.0.1.0.2", "version": "13.0.1.0.2",
"license": "AGPL-3", "license": "AGPL-3",
"depends": ["base", "web"], "depends": ["base", "web"],
"data": ["views/webclient_templates.xml"], "data": ["views/webclient_templates.xml", "views/ir_actions_views.xml"],
"demo": ["demo/report.xml"], "demo": ["demo/report.xml"],
"installable": True, "installable": True,
} }

View File

@ -9,6 +9,14 @@ class ReportAction(models.Model):
_inherit = "ir.actions.report" _inherit = "ir.actions.report"
report_type = fields.Selection(selection_add=[("csv", "csv")]) report_type = fields.Selection(selection_add=[("csv", "csv")])
encoding = fields.Char(
help="Encoding to be applied to the generated CSV file. e.g. cp932"
)
encode_error_handling = fields.Selection(
selection=[("ignore", "Ignore"), ("replace", "Replace")],
help="If nothing is selected, CSV export will fail with an error message when "
"there is a character that fail to be encoded.",
)
@api.model @api.model
def render_csv(self, docids, data): def render_csv(self, docids, data):
@ -17,7 +25,11 @@ class ReportAction(models.Model):
if report_model is None: if report_model is None:
raise UserError(_("%s model was not found" % report_model_name)) raise UserError(_("%s model was not found" % report_model_name))
return report_model.with_context( return report_model.with_context(
{"active_model": self.model} {
"active_model": self.model,
"encoding": self.encoding,
"encode_error_handling": self.encode_error_handling,
}
).create_csv_report(docids, data) ).create_csv_report(docids, data)
@api.model @api.model

View File

@ -0,0 +1,9 @@
In case the exported CSV report should be encoded in another system than UTF-8, following
fields of the report record (*Settings > Technical > Reports*) should be populated accordingly.
* Encoding: set an encoding system (such as cp932)
* Encode Error Handling: select 'Ignore' or 'Replace' as necessary.
* 'Ignore': in case of an encoding error, the problematic character will be removed from the exported file.
* 'Replace': in case of an encoding error, the problematic character will be replaced with '?' symbol.
* Leaving the field blank: in case of an encoding error, the report generation fails with an error message.

View File

@ -1,3 +1,6 @@
* Enric Tobella <etobella@creublanca.es> * Enric Tobella <etobella@creublanca.es>
* Jaime Arroyo <jaime.arroyo@creublanca.es> * Jaime Arroyo <jaime.arroyo@creublanca.es>
* Rattapong Chokmasermkul <rattapongc@ecosoft.co.th> * Rattapong Chokmasermkul <rattapongc@ecosoft.co.th>
* `Quartile <https://www.quartile.co>`__:
* Aung Ko Ko Lin

View File

@ -36,3 +36,5 @@ A report XML record ::
file="res_partner" file="res_partner"
attachment_use="False" attachment_use="False"
/> />
Update encoding with an appropriate value (e.g. cp932) as necessary.

View File

@ -4,7 +4,8 @@
import logging import logging
from io import StringIO from io import StringIO
from odoo import models from odoo import _, models
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@ -46,7 +47,18 @@ class ReportCSVAbstract(models.AbstractModel):
file = csv.DictWriter(file_data, **self.csv_report_options()) file = csv.DictWriter(file_data, **self.csv_report_options())
self.generate_csv_report(file, data, objs) self.generate_csv_report(file, data, objs)
file_data.seek(0) file_data.seek(0)
encoding = self._context.get("encoding")
if not encoding:
return file_data.read(), "csv" return file_data.read(), "csv"
error_handling = self._context.get("encode_error_handling")
if error_handling:
return file_data.read().encode(encoding, errors=error_handling), "csv"
try:
return file_data.read().encode(encoding), "csv"
except Exception:
raise UserError(
_("Failed to encode the data with the encoding set in the report.")
)
def csv_report_options(self): def csv_report_options(self):
""" """

View File

@ -3,7 +3,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.15.1: http://docutils.sourceforge.net/" /> <meta name="generator" content="Docutils: http://docutils.sourceforge.net/" />
<title>Base report csv</title> <title>Base report csv</title>
<style type="text/css"> <style type="text/css">
@ -372,18 +372,33 @@ ul.auto-toc {
<p><strong>Table of contents</strong></p> <p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents"> <div class="contents local topic" id="contents">
<ul class="simple"> <ul class="simple">
<li><a class="reference internal" href="#usage" id="id1">Usage</a></li> <li><a class="reference internal" href="#configuration" id="id1">Configuration</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id2">Bug Tracker</a></li> <li><a class="reference internal" href="#usage" id="id2">Usage</a></li>
<li><a class="reference internal" href="#credits" id="id3">Credits</a><ul> <li><a class="reference internal" href="#bug-tracker" id="id3">Bug Tracker</a></li>
<li><a class="reference internal" href="#authors" id="id4">Authors</a></li> <li><a class="reference internal" href="#credits" id="id4">Credits</a><ul>
<li><a class="reference internal" href="#contributors" id="id5">Contributors</a></li> <li><a class="reference internal" href="#authors" id="id5">Authors</a></li>
<li><a class="reference internal" href="#maintainers" id="id6">Maintainers</a></li> <li><a class="reference internal" href="#contributors" id="id6">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id7">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="configuration">
<h1><a class="toc-backref" href="#id1">Configuration</a></h1>
<p>In case the exported CSV report should be encoded in another system than UTF-8, following
fields of the report record (<em>Settings &gt; Technical &gt; Reports</em>) should be populated accordingly.</p>
<ul class="simple">
<li>Encoding: set an encoding system (such as cp932)</li>
<li>Encode Error Handling: select Ignore or Replace as necessary.<ul>
<li>Ignore: in case of an encoding error, the problematic character will be removed from the exported file.</li>
<li>Replace: in case of an encoding error, the problematic character will be replaced with ? symbol.</li>
<li>Leaving the field blank: in case of an encoding error, the report generation fails with an error message.</li>
</ul> </ul>
</li> </li>
</ul> </ul>
</div> </div>
<div class="section" id="usage"> <div class="section" id="usage">
<h1><a class="toc-backref" href="#id1">Usage</a></h1> <h1><a class="toc-backref" href="#id2">Usage</a></h1>
<p>An example of CSV report for partners on a module called <cite>module_name</cite>:</p> <p>An example of CSV report for partners on a module called <cite>module_name</cite>:</p>
<p>A python class</p> <p>A python class</p>
<pre class="literal-block"> <pre class="literal-block">
@ -421,9 +436,10 @@ class PartnerCSV(models.AbstractModel):
attachment_use=&quot;False&quot; attachment_use=&quot;False&quot;
/&gt; /&gt;
</pre> </pre>
<p>Update encoding with an appropriate value (e.g. cp932) as necessary.</p>
</div> </div>
<div class="section" id="bug-tracker"> <div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id2">Bug Tracker</a></h1> <h1><a class="toc-backref" href="#id3">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/reporting-engine/issues">GitHub Issues</a>. <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. 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 If you spotted it first, help us smashing it by providing a detailed and welcomed
@ -431,23 +447,27 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<p>Do not contact contributors directly about support or help with technical issues.</p> <p>Do not contact contributors directly about support or help with technical issues.</p>
</div> </div>
<div class="section" id="credits"> <div class="section" id="credits">
<h1><a class="toc-backref" href="#id3">Credits</a></h1> <h1><a class="toc-backref" href="#id4">Credits</a></h1>
<div class="section" id="authors"> <div class="section" id="authors">
<h2><a class="toc-backref" href="#id4">Authors</a></h2> <h2><a class="toc-backref" href="#id5">Authors</a></h2>
<ul class="simple"> <ul class="simple">
<li>Creu Blanca</li> <li>Creu Blanca</li>
</ul> </ul>
</div> </div>
<div class="section" id="contributors"> <div class="section" id="contributors">
<h2><a class="toc-backref" href="#id5">Contributors</a></h2> <h2><a class="toc-backref" href="#id6">Contributors</a></h2>
<ul class="simple"> <ul class="simple">
<li>Enric Tobella &lt;<a class="reference external" href="mailto:etobella&#64;creublanca.es">etobella&#64;creublanca.es</a>&gt;</li> <li>Enric Tobella &lt;<a class="reference external" href="mailto:etobella&#64;creublanca.es">etobella&#64;creublanca.es</a>&gt;</li>
<li>Jaime Arroyo &lt;<a class="reference external" href="mailto:jaime.arroyo&#64;creublanca.es">jaime.arroyo&#64;creublanca.es</a>&gt;</li> <li>Jaime Arroyo &lt;<a class="reference external" href="mailto:jaime.arroyo&#64;creublanca.es">jaime.arroyo&#64;creublanca.es</a>&gt;</li>
<li>Rattapong Chokmasermkul &lt;<a class="reference external" href="mailto:rattapongc&#64;ecosoft.co.th">rattapongc&#64;ecosoft.co.th</a>&gt;</li> <li>Rattapong Chokmasermkul &lt;<a class="reference external" href="mailto:rattapongc&#64;ecosoft.co.th">rattapongc&#64;ecosoft.co.th</a>&gt;</li>
<li><a class="reference external" href="https://www.quartile.co">Quartile</a>:<ul>
<li>Aung Ko Ko Lin</li>
</ul>
</li>
</ul> </ul>
</div> </div>
<div class="section" id="maintainers"> <div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id6">Maintainers</a></h2> <h2><a class="toc-backref" href="#id7">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p> <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> <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 <p>OCA, or the Odoo Community Association, is a nonprofit organization whose

View File

@ -3,6 +3,7 @@
import logging import logging
from io import StringIO from io import StringIO
from odoo.exceptions import UserError
from odoo.tests import common from odoo.tests import common
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@ -56,3 +57,15 @@ class TestReport(common.TransactionCase):
# Typical call from render # Typical call from render
objs = self.csv_report._get_objs_for_report(self.docs.ids, {}) objs = self.csv_report._get_objs_for_report(self.docs.ids, {})
self.assertEquals(objs, self.docs) self.assertEquals(objs, self.docs)
def test_report_with_encoding(self):
report = self.report
report.write({"encoding": "cp932"})
rep = report.render_csv(self.docs.ids, {})
str_io = StringIO(rep[0].decode())
dict_report = list(csv.DictReader(str_io, delimiter=";", quoting=csv.QUOTE_ALL))
self.assertEqual(self.docs.name, dict(dict_report[0])["name"])
report.write({"encoding": "xyz"})
with self.assertRaises(UserError):
rep = report.render_csv(self.docs.ids, {})

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="act_report_xml_view" model="ir.ui.view">
<field name="name">ir.actions.report</field>
<field name="model">ir.actions.report</field>
<field name="inherit_id" ref="base.act_report_xml_view" />
<field name="arch" type="xml">
<xpath expr="//field[@name='report_type']" position="after">
<field
name="encoding"
attrs="{'invisible': [('report_type', '!=', 'csv')]}"
/>
<field
name="encode_error_handling"
attrs="{'invisible': [('encoding', '=', False)]}"
/>
</xpath>
</field>
</record>
</odoo>