From 66d6741ba3634b3543e4c21cc8b7569779920929 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 | 18 ++++++++++ report_csv/__manifest__.py | 1 + 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, 126 insertions(+), 16 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 9b62e2c386..90f9c65e9e 100644 --- a/report_csv/README.rst +++ b/report_csv/README.rst @@ -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 ===== @@ -74,6 +87,8 @@ A report XML record :: attachment_use="False" /> +Update encoding with an appropriate value (e.g. cp932) as necessary. + Bug Tracker =========== @@ -98,6 +113,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 d6a1c3e0b2..eb5a8a9211 100644 --- a/report_csv/__manifest__.py +++ b/report_csv/__manifest__.py @@ -10,6 +10,7 @@ "license": "AGPL-3", "depends": ["base", "web"], "demo": ["demo/report.xml"], + "data": ["views/ir_actions_views.xml"], "assets": { "web.assets_backend": [ "report_csv/static/src/js/report/qwebactionmanager.esm.js" diff --git a/report_csv/models/ir_report.py b/report_csv/models/ir_report.py index 4a5ad6adf0..01982668be 100644 --- a/report_csv/models/ir_report.py +++ b/report_csv/models/ir_report.py @@ -10,6 +10,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, report_ref, docids, data): @@ -17,7 +25,11 @@ def _render_csv(self, report_ref, docids, data): report_model_name = "report.%s" % report_sudo.report_name report_model = self.env[report_model_name] return report_model.with_context( - active_model=report_sudo.model + **{ + "active_model": report_sudo.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 0000000000..a0859d07d1 --- /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 1ee404f733..922a3262e8 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 e5d9964cb8..e6d22e3821 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 0d9aeffdd8..82fff52494 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 @@ 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" + try: + return file_data.read().encode(encoding), "csv" + except Exception as e: + raise UserError( + _("Failed to encode the data with the encoding set in the report.") + ) from e def csv_report_options(self): """ diff --git a/report_csv/static/description/index.html b/report_csv/static/description/index.html index 20d8da8b8d..d5583b2e4c 100644 --- a/report_csv/static/description/index.html +++ b/report_csv/static/description/index.html @@ -3,7 +3,7 @@ - + Base report csv