From 72c38a77c20ff40c96036499e039535c2654b13f Mon Sep 17 00:00:00 2001 From: Quentin Mondot Date: Tue, 21 Apr 2026 18:17:32 +0200 Subject: [PATCH] [IMP] report_carbone : upload template from IHM --- .../models/base/ir_actions_report.py | 40 ++++++++++++++++++- .../views/base/ir_actions_report.xml | 11 +++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/report_carbone/models/base/ir_actions_report.py b/report_carbone/models/base/ir_actions_report.py index 4834e41..361b354 100644 --- a/report_carbone/models/base/ir_actions_report.py +++ b/report_carbone/models/base/ir_actions_report.py @@ -129,6 +129,8 @@ class IrActionsReportCarbone(models.Model): "supported by Carbone. You must provide a production API key and must not " "be in test mode.", ) + template_file = fields.Binary(string="Template file", attachment=True) + template_filename = fields.Char(string="Template filename") @api.model def _setup_template_id_and_extension(self, vals): @@ -849,6 +851,42 @@ class IrActionsReportCarbone(models.Model): response = self.call_carbone_endpoint("template", method="POST", files=files, data=data) return {"template_id": response["data"]["id"], "file_extension": file_extension} + def action_upload_template_to_carbone(self): + self.ensure_one() + if not self.template_file: + raise exceptions.UserError(_("Please select a template file to upload.")) + filename = self.template_filename or "template.docx" + file_content = base64.b64decode(self.template_file) + file_extension = os.path.splitext(filename)[1].lstrip(".") + import tempfile + with tempfile.NamedTemporaryFile(suffix=f".{file_extension}", delete=False) as tmp: + tmp.write(file_content) + tmp_path = tmp.name + try: + csdk = self.get_carbone_sdk() + response = csdk.add_template(tmp_path) + finally: + os.unlink(tmp_path) + if not response.get("success") or not response.get("data", {}).get("templateId"): + raise exceptions.UserError(_("Carbone did not return a valid template ID. Response: %s") % response) + template_id = response["data"]["templateId"] + self.write({ + "template_id": template_id, + "file_extension": file_extension or "docx", + "template_file": False, + "template_filename": False, + }) + return { + "type": "ir.actions.client", + "tag": "display_notification", + "params": { + "title": _("Template uploaded"), + "message": _("Template ID: %s") % template_id, + "type": "success", + "sticky": False, + }, + } + def get_extension_file_from_api(self, template_id: str, raise_error=True) -> str | bool: # If we are in install mode, for unit test for example, and we have to init a ir.actions.report from an XML # file, we don't wan't to call Carbone's API to retrieve extension. @@ -886,7 +924,7 @@ class IrActionsReportCarbone(models.Model): # We have to specified carbone-version 5 headers = {"Authorization": "Bearer " + api_token, "carbone-version": "5"} - url = f"{api_endpoint}/{endpoint}" + url = f"{api_endpoint.rstrip('/')}/{endpoint}" if params: url = urljoin(url, "?" + urls.url_encode(params)) if method == "GET": diff --git a/report_carbone/views/base/ir_actions_report.xml b/report_carbone/views/base/ir_actions_report.xml index 0496855..ae9dbfb 100644 --- a/report_carbone/views/base/ir_actions_report.xml +++ b/report_carbone/views/base/ir_actions_report.xml @@ -49,6 +49,17 @@ /> + + + +