From fd34b95bbd797e0c9c38d5ea3945a6a2f3bfaab0 Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Tue, 26 Sep 2023 22:36:00 +0200 Subject: [PATCH] [16.0][IMP] report_csv: support attachment use --- report_csv/models/ir_report.py | 48 ++++++++++++++++++++++++++++++++- report_csv/tests/test_report.py | 14 ++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/report_csv/models/ir_report.py b/report_csv/models/ir_report.py index 01982668be..6e31e4b3e1 100644 --- a/report_csv/models/ir_report.py +++ b/report_csv/models/ir_report.py @@ -1,7 +1,13 @@ # Copyright 2019 Creu Blanca # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +import logging + from odoo import api, fields, models +from odoo.exceptions import AccessError +from odoo.tools.safe_eval import safe_eval, time + +_logger = logging.getLogger(__name__) class ReportAction(models.Model): @@ -19,18 +25,58 @@ class ReportAction(models.Model): "there is a character that fail to be encoded.", ) + def _create_csv_attachment(self, record, data): + attachment_name = safe_eval(self.attachment, {"object": record, "time": time}) + # Unable to compute a name for the attachment. + if not attachment_name: + return + if record and data: + attachment = { + "name": attachment_name, + "raw": data, + "res_model": self.model, + "res_id": record.id, + "type": "binary", + } + try: + self.env["ir.attachment"].create(attachment) + except AccessError: + _logger.info( + "Cannot save csv report %r as attachment", attachment["name"] + ) + else: + _logger.info( + "The csv document %s is now saved in the database", + attachment["name"], + ) + @api.model def _render_csv(self, report_ref, docids, data): report_sudo = self._get_report(report_ref) report_model_name = "report.%s" % report_sudo.report_name report_model = self.env[report_model_name] - return report_model.with_context( + res_id = len(docids) == 1 and docids[0] + if not res_id or not report_sudo.attachment or not report_sudo.attachment_use: + return report_model.with_context( + **{ + "active_model": report_sudo.model, + "encoding": self.encoding, + "encode_error_handling": self.encode_error_handling, + } + ).create_csv_report(docids, data) + record = self.env[report_sudo.model].browse(res_id) + attachment = report_sudo.retrieve_attachment(record) + if attachment: + return attachment.raw.decode(), "csv" + data, ext = report_model.with_context( **{ "active_model": report_sudo.model, "encoding": self.encoding, "encode_error_handling": self.encode_error_handling, } ).create_csv_report(docids, data) + report_sudo._create_csv_attachment(record, data) + return data, ext @api.model def _get_report_from_name(self, report_name): diff --git a/report_csv/tests/test_report.py b/report_csv/tests/test_report.py index 67644cd953..81defff7b6 100644 --- a/report_csv/tests/test_report.py +++ b/report_csv/tests/test_report.py @@ -47,6 +47,20 @@ def test_report(self): dict_report = list(csv.DictReader(str_io, delimiter=";", quoting=csv.QUOTE_ALL)) self.assertEqual(self.docs.name, dict(dict_report[0])["name"]) + def test_attachment_use(self): + self.report.attachment = "object.name+'.csv'" + self.report.attachment_use = True + rep = self.report_object._render(self.report_name, self.docs.ids, {}) + attachment = self.env["ir.attachment"].search( + [("name", "=", self.docs.name + ".csv")] + ) + self.assertTrue(attachment) + self.assertEqual(attachment.raw.decode(), rep[0]) + rep_from_attachment = self.report_object._render( + self.report_name, self.docs.ids, {} + ) + self.assertTupleEqual(rep, rep_from_attachment) + def test_id_retrieval(self): # Typical call from WebUI with wizard