Skip to content

Commit

Permalink
[IMP] report_csv: add encoding option
Browse files Browse the repository at this point in the history
  • Loading branch information
AungKoKoLin1997 committed Jul 24, 2023
1 parent aed350d commit 9bf1b70
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 17 deletions.
18 changes: 18 additions & 0 deletions report_csv/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,19 @@ This module provides a basic report class to generate csv report.
.. contents::
: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
=====

Expand Down Expand Up @@ -74,6 +87,8 @@ A report XML record ::
attachment_use="False"
/>

Update encoding with an appropriate value (e.g. cp932) as necessary.

Bug Tracker
===========

Expand All @@ -98,6 +113,9 @@ Contributors
* Enric Tobella <etobella@creublanca.es>
* Jaime Arroyo <jaime.arroyo@creublanca.es>
* Rattapong Chokmasermkul <rattapongc@ecosoft.co.th>
* `Quartile <https://www.quartile.co>`__:

* Aung Ko Ko Lin

Maintainers
~~~~~~~~~~~
Expand Down
2 changes: 1 addition & 1 deletion report_csv/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"version": "13.0.1.0.2",
"license": "AGPL-3",
"depends": ["base", "web"],
"data": ["views/webclient_templates.xml"],
"data": ["views/webclient_templates.xml", "views/ir_actions_views.xml"],
"demo": ["demo/report.xml"],
"installable": True,
}
14 changes: 13 additions & 1 deletion report_csv/models/ir_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ class ReportAction(models.Model):
_inherit = "ir.actions.report"

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
def render_csv(self, docids, data):
Expand All @@ -17,7 +25,11 @@ def render_csv(self, docids, data):
if report_model is None:
raise UserError(_("%s model was not found" % report_model_name))
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)

@api.model
Expand Down
9 changes: 9 additions & 0 deletions report_csv/readme/CONFIGURE.rst
Original file line number Diff line number Diff line change
@@ -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.
3 changes: 3 additions & 0 deletions report_csv/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
* Enric Tobella <etobella@creublanca.es>
* Jaime Arroyo <jaime.arroyo@creublanca.es>
* Rattapong Chokmasermkul <rattapongc@ecosoft.co.th>
* `Quartile <https://www.quartile.co>`__:

* Aung Ko Ko Lin
2 changes: 2 additions & 0 deletions report_csv/readme/USAGE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@ A report XML record ::
file="res_partner"
attachment_use="False"
/>

Update encoding with an appropriate value (e.g. cp932) as necessary.
16 changes: 14 additions & 2 deletions report_csv/report/report_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import logging
from io import StringIO

from odoo import models
from odoo import _, models
from odoo.exceptions import UserError

_logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -46,7 +47,18 @@ def create_csv_report(self, docids, data):
file = csv.DictWriter(file_data, **self.csv_report_options())
self.generate_csv_report(file, data, objs)
file_data.seek(0)
return file_data.read(), "csv"
encoding = self._context.get("encoding")
if not encoding:
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"

Check warning on line 55 in report_csv/report/report_csv.py

View check run for this annotation

Codecov / codecov/patch

report_csv/report/report_csv.py#L55

Added line #L55 was not covered by tests
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):
"""
Expand Down
46 changes: 33 additions & 13 deletions report_csv/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<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.15.1: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils: http://docutils.sourceforge.net/" />
<title>Base report csv</title>
<style type="text/css">

Expand Down Expand Up @@ -372,18 +372,33 @@ <h1 class="title">Base report csv</h1>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#usage" id="id1">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id2">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id3">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id4">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id5">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id6">Maintainers</a></li>
<li><a class="reference internal" href="#configuration" id="id1">Configuration</a></li>
<li><a class="reference internal" href="#usage" id="id2">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id3">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id4">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id5">Authors</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>
</li>
</ul>
</div>
<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>A python class</p>
<pre class="literal-block">
Expand Down Expand Up @@ -421,33 +436,38 @@ <h1><a class="toc-backref" href="#id1">Usage</a></h1>
attachment_use=&quot;False&quot;
/&gt;
</pre>
<p>Update encoding with an appropriate value (e.g. cp932) as necessary.</p>
</div>
<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>.
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_csv%0Aversion:%2013.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="#id3">Credits</a></h1>
<h1><a class="toc-backref" href="#id4">Credits</a></h1>
<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">
<li>Creu Blanca</li>
</ul>
</div>
<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">
<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>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>
</div>
<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>
<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
Expand Down
13 changes: 13 additions & 0 deletions report_csv/tests/test_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import logging
from io import StringIO

from odoo.exceptions import UserError
from odoo.tests import common

_logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -56,3 +57,15 @@ def test_id_retrieval(self):
# Typical call from render
objs = self.csv_report._get_objs_for_report(self.docs.ids, {})
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, {})
20 changes: 20 additions & 0 deletions report_csv/views/ir_actions_views.xml
Original file line number Diff line number Diff line change
@@ -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>

0 comments on commit 9bf1b70

Please sign in to comment.