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 10d30b1d71e..0c458372815 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 @@ def print_action_for_report_name(self, report_name): "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 @@ def behaviour(self): # 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 @@ def _can_print_report(self, behaviour, printer, document): """ 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 f3216cbf84e..79ea69f24fb 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 64332f9c694..e010dd883c5 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 @@ 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 @@ def test_behaviour_printing_action_on_wrong_report(self): 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 @@ def test_print_tray_behaviour(self): """ 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 @@ def test_print_tray_behaviour(self): 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 @@ def test_onchange_printer_tray_id_not_empty(self): {"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 cc6a0ea09ce..570ad522815 100644 --- a/base_report_to_printer/tests/test_report.py +++ b/base_report_to_printer/tests/test_report.py @@ -11,7 +11,9 @@ 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",