From cb493cd5963d7ba94ee63a72dc7d000940a0e7f2 Mon Sep 17 00:00:00 2001 From: David Date: Wed, 31 Jan 2024 13:02:02 +0100 Subject: [PATCH] [IMP] base_report_to_printer: out of connection fallback to client If the CUPS server isn't available the user won't be able to do anything to print the report they need. At last we can give them the chance to have a fallback behavior downloading the document. TT47134 --- .../models/ir_actions_report.py | 26 ++++++++++++++++++- .../static/src/js/qweb_action_manager.esm.js | 22 +++++++++++++--- .../tests/test_ir_actions_report.py | 14 +++++----- base_report_to_printer/tests/test_report.py | 4 ++- 4 files changed, 55 insertions(+), 11 deletions(-) diff --git a/base_report_to_printer/models/ir_actions_report.py b/base_report_to_printer/models/ir_actions_report.py index 10d30b1..0c45837 100644 --- a/base_report_to_printer/models/ir_actions_report.py +++ b/base_report_to_printer/models/ir_actions_report.py @@ -53,6 +53,10 @@ class IrActionsReport(models.Model): "action": result["action"], "printer_name": result["printer"].name, } + if result.get("printer_exception") and not self.env.context.get( + "skip_printer_exception" + ): + serializable_result["printer_exception"] = True return serializable_result def _get_user_default_print_behaviour(self): @@ -97,6 +101,21 @@ class IrActionsReport(models.Model): # For some reason design takes report defaults over # False action entries so we must allow for that here result.update({k: v for k, v in print_action.behaviour().items() if v}) + printer = result.get("printer") + if printer: + # When no printer is available we can fallback to the default behavior + # letting the user to manually print the reports. + try: + printer.server_id._open_connection(raise_on_error=True) + printer_exception = printer.status in [ + "error", + "server-error", + "unavailable", + ] + except Exception: + printer_exception = True + if printer_exception and not self.env.context.get("skip_printer_exception"): + result["printer_exception"] = True return result def print_document(self, record_ids, data=None): @@ -140,7 +159,12 @@ class IrActionsReport(models.Model): """ if self.env.context.get("must_skip_send_to_printer"): return False - if behaviour["action"] == "server" and printer and document: + if ( + behaviour["action"] == "server" + and printer + and document + and not behaviour.get("printer_exception") + ): return True return False diff --git a/base_report_to_printer/static/src/js/qweb_action_manager.esm.js b/base_report_to_printer/static/src/js/qweb_action_manager.esm.js index f3216cb..79ea69f 100644 --- a/base_report_to_printer/static/src/js/qweb_action_manager.esm.js +++ b/base_report_to_printer/static/src/js/qweb_action_manager.esm.js @@ -10,19 +10,35 @@ async function cupsReportActionHandler(action, options, env) { "print_action_for_report_name", [action.report_name] ); - if (print_action && print_action.action === "server") { + if ( + print_action && + print_action.action === "server" && + !print_action.printer_exception + ) { const result = await orm.call("ir.actions.report", "print_document", [ action.id, action.context.active_ids, action.data, ]); if (result) { - env.services.notification.add(env._t("Successfully sent to printer!")); + env.services.notification.add(env._t("Successfully sent to printer!"), { + type: "success", + }); } else { - env.services.notification.add(env._t("Could not sent to printer!")); + env.services.notification.add(env._t("Could not sent to printer!"), { + type: "danger", + }); } return true; } + if (print_action.printer_exception) { + env.services.notification.add( + env._t("The printer couldn't be reached. Downloading document instead"), + { + type: "warning", + } + ); + } } } diff --git a/base_report_to_printer/tests/test_ir_actions_report.py b/base_report_to_printer/tests/test_ir_actions_report.py index 64332f9..e010dd8 100644 --- a/base_report_to_printer/tests/test_ir_actions_report.py +++ b/base_report_to_printer/tests/test_ir_actions_report.py @@ -12,10 +12,12 @@ model = "odoo.addons.base.models.ir_actions_report.IrActionsReport" class TestIrActionsReportXml(TransactionCase): def setUp(self): super(TestIrActionsReportXml, self).setUp() - self.Model = self.env["ir.actions.report"] + self.Model = self.env["ir.actions.report"].with_context( + skip_printer_exception=True + ) self.vals = {} - self.report = self.env["ir.actions.report"].search([], limit=1) + self.report = self.Model.search([], limit=1) self.server = self.env["printing.server"].create({}) def new_action(self): @@ -153,7 +155,7 @@ class TestIrActionsReportXml(TransactionCase): self.env.user.printing_action = "client" printing_action = self.new_printing_action() printing_action.user_id = self.env.user - printing_action.report_id = self.env["ir.actions.report"].search( + printing_action.report_id = self.Model.search( [("id", "!=", report.id)], limit=1 ) self.assertEqual( @@ -213,7 +215,7 @@ class TestIrActionsReportXml(TransactionCase): """ It should return the correct tray """ - report = self.env["ir.actions.report"].search([], limit=1) + report = self.Model.search([], limit=1) action = self.env["printing.report.xml.action"].create( {"user_id": self.env.user.id, "report_id": report.id, "action": "server"} ) @@ -266,7 +268,7 @@ class TestIrActionsReportXml(TransactionCase): self.assertEqual("Action tray", report.behaviour()["tray"]) def test_onchange_printer_tray_id_empty(self): - action = self.env["ir.actions.report"].new({"printer_tray_id": False}) + action = self.Model.new({"printer_tray_id": False}) action.onchange_printing_printer_id() self.assertFalse(action.printer_tray_id) @@ -289,7 +291,7 @@ class TestIrActionsReportXml(TransactionCase): {"name": "Tray", "system_name": "TrayName", "printer_id": printer.id} ) - action = self.env["ir.actions.report"].new({"printer_tray_id": tray.id}) + action = self.Model.new({"printer_tray_id": tray.id}) self.assertEqual(action.printer_tray_id, tray) action.onchange_printing_printer_id() self.assertFalse(action.printer_tray_id) diff --git a/base_report_to_printer/tests/test_report.py b/base_report_to_printer/tests/test_report.py index cc6a0ea..570ad52 100644 --- a/base_report_to_printer/tests/test_report.py +++ b/base_report_to_printer/tests/test_report.py @@ -11,7 +11,9 @@ from odoo.tests import common class TestReport(common.HttpCase): def setUp(self): super(TestReport, self).setUp() - self.Model = self.env["ir.actions.report"] + self.Model = self.env["ir.actions.report"].with_context( + skip_printer_exception=True + ) self.server = self.env["printing.server"].create({}) self.report_vals = { "name": "Test Report",