From 5d89b44e4754ecb98d224092586c032d25a67a38 Mon Sep 17 00:00:00 2001 From: Aungkokolin1997 Date: Wed, 18 Jan 2023 08:49:07 +0630 Subject: [PATCH] [IMP] report_csv: add encoding option --- report_csv/README.rst | 20 ++++++++++- report_csv/__manifest__.py | 2 +- report_csv/models/ir_report.py | 14 +++++++- report_csv/readme/CONFIGURE.rst | 9 +++++ report_csv/readme/CONTRIBUTORS.rst | 3 ++ report_csv/readme/USAGE.rst | 2 ++ report_csv/report/report_csv.py | 16 +++++++-- report_csv/static/description/index.html | 46 +++++++++++++++++------- report_csv/tests/test_report.py | 13 +++++++ report_csv/views/ir_actions_views.xml | 20 +++++++++++ 10 files changed, 127 insertions(+), 18 deletions(-) create mode 100644 report_csv/readme/CONFIGURE.rst create mode 100644 report_csv/views/ir_actions_views.xml diff --git a/report_csv/README.rst b/report_csv/README.rst index 05e1fe5f0..aa39cc3e0 100644 --- a/report_csv/README.rst +++ b/report_csv/README.rst @@ -7,7 +7,7 @@ Base report csv !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:ec79b69b51f6950f27d658111240cf9c35f2f74f3431fb23369106bdbd3ca9ab + !! source digest: sha256:f2082a65edddcb957a5a22e07ffcd761bf2038fd8fe93322bab2be04b8102557 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -35,6 +35,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 ===== @@ -77,6 +90,8 @@ A report XML record :: attachment_use="False" /> +Update encoding with an appropriate value (e.g. cp932) as necessary. + Bug Tracker =========== @@ -101,6 +116,9 @@ Contributors * Enric Tobella * Jaime Arroyo * Rattapong Chokmasermkul +* `Quartile `__: + + * Aung Ko Ko Lin Maintainers ~~~~~~~~~~~ diff --git a/report_csv/__manifest__.py b/report_csv/__manifest__.py index 6adf30c28..0e28b3ffa 100644 --- a/report_csv/__manifest__.py +++ b/report_csv/__manifest__.py @@ -9,7 +9,7 @@ "version": "14.0.1.0.0", "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, } diff --git a/report_csv/models/ir_report.py b/report_csv/models/ir_report.py index 97e8f3a8e..90b654d01 100644 --- a/report_csv/models/ir_report.py +++ b/report_csv/models/ir_report.py @@ -11,6 +11,14 @@ class ReportAction(models.Model): report_type = fields.Selection( selection_add=[("csv", "csv")], ondelete={"csv": "set default"} ) + 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): @@ -19,7 +27,11 @@ class ReportAction(models.Model): 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 diff --git a/report_csv/readme/CONFIGURE.rst b/report_csv/readme/CONFIGURE.rst new file mode 100644 index 000000000..a0859d07d --- /dev/null +++ b/report_csv/readme/CONFIGURE.rst @@ -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. diff --git a/report_csv/readme/CONTRIBUTORS.rst b/report_csv/readme/CONTRIBUTORS.rst index 1ee404f73..922a3262e 100644 --- a/report_csv/readme/CONTRIBUTORS.rst +++ b/report_csv/readme/CONTRIBUTORS.rst @@ -1,3 +1,6 @@ * Enric Tobella * Jaime Arroyo * Rattapong Chokmasermkul +* `Quartile `__: + + * Aung Ko Ko Lin diff --git a/report_csv/readme/USAGE.rst b/report_csv/readme/USAGE.rst index e5d9964cb..e6d22e382 100644 --- a/report_csv/readme/USAGE.rst +++ b/report_csv/readme/USAGE.rst @@ -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. diff --git a/report_csv/report/report_csv.py b/report_csv/report/report_csv.py index 0d9aeffdd..6d7bd19f2 100644 --- a/report_csv/report/report_csv.py +++ b/report_csv/report/report_csv.py @@ -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__) @@ -46,7 +47,18 @@ class ReportCSVAbstract(models.AbstractModel): 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" + 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): """ diff --git a/report_csv/static/description/index.html b/report_csv/static/description/index.html index 8c1ee4f4b..c3d963ced 100644 --- a/report_csv/static/description/index.html +++ b/report_csv/static/description/index.html @@ -367,25 +367,40 @@ ul.auto-toc { !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:ec79b69b51f6950f27d658111240cf9c35f2f74f3431fb23369106bdbd3ca9ab +!! source digest: sha256:f2082a65edddcb957a5a22e07ffcd761bf2038fd8fe93322bab2be04b8102557 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/reporting-engine Translate me on Weblate Try me on Runboat

This module provides a basic report class to generate csv report.

Table of contents

+
+

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

An example of CSV report for partners on a module called module_name:

A python class

@@ -423,9 +438,10 @@ class PartnerCSV(models.AbstractModel):
     attachment_use="False"
 />
 
+

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

-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub 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 @@ -433,23 +449,27 @@ If you spotted it first, help us to smash it by providing a detailed and welcome

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Creu Blanca
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association

OCA, or the Odoo Community Association, is a nonprofit organization whose diff --git a/report_csv/tests/test_report.py b/report_csv/tests/test_report.py index cfaccc4ea..7d8cf02b3 100644 --- a/report_csv/tests/test_report.py +++ b/report_csv/tests/test_report.py @@ -3,6 +3,7 @@ import logging from io import StringIO +from odoo.exceptions import UserError from odoo.tests import common _logger = logging.getLogger(__name__) @@ -55,3 +56,15 @@ class TestReport(common.TransactionCase): # Typical call from render objs = self.csv_report._get_objs_for_report(self.docs.ids, {}) self.assertEqual(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, {}) diff --git a/report_csv/views/ir_actions_views.xml b/report_csv/views/ir_actions_views.xml new file mode 100644 index 000000000..d76fbeaf9 --- /dev/null +++ b/report_csv/views/ir_actions_views.xml @@ -0,0 +1,20 @@ + + + + ir.actions.report + ir.actions.report + + + + + + + + +