[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
This commit is contained in:
David
2024-01-31 13:02:02 +01:00
committed by trisdoan
parent 64f778e599
commit 43eab67b60
4 changed files with 55 additions and 11 deletions

View File

@@ -54,6 +54,10 @@ class IrActionsReport(models.Model):
"action": result["action"], "action": result["action"],
"printer_name": result["printer"].name, "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 return serializable_result
def _get_user_default_print_behaviour(self): def _get_user_default_print_behaviour(self):
@@ -98,6 +102,21 @@ class IrActionsReport(models.Model):
# For some reason design takes report defaults over # For some reason design takes report defaults over
# False action entries so we must allow for that here # False action entries so we must allow for that here
result.update({k: v for k, v in print_action.behaviour().items() if v}) 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 return result
def print_document(self, record_ids, data=None): def print_document(self, record_ids, data=None):
@@ -141,7 +160,12 @@ class IrActionsReport(models.Model):
""" """
if self.env.context.get("must_skip_send_to_printer"): if self.env.context.get("must_skip_send_to_printer"):
return False 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 True
return False return False

View File

@@ -11,19 +11,35 @@ async function cupsReportActionHandler(action, options, env) {
"print_action_for_report_name", "print_action_for_report_name",
[action.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", [ const result = await orm.call("ir.actions.report", "print_document", [
action.id, action.id,
action.context.active_ids, action.context.active_ids,
action.data, action.data,
]); ]);
if (result) { if (result) {
env.services.notification.add(_t("Successfully sent to printer!")); env.services.notification.add(_t("Successfully sent to printer!"), {
type: "success",
});
} else { } else {
env.services.notification.add(_t("Could not send to printer!")); env.services.notification.add(_t("Could not send to printer!"), {
type: "danger",
});
} }
return true; return true;
} }
if (print_action.printer_exception) {
env.services.notification.add(
env._t("The printer couldn't be reached. Downloading document instead"),
{
type: "warning",
}
);
}
} }
} }

View File

@@ -12,10 +12,12 @@ model = "odoo.addons.base.models.ir_actions_report.IrActionsReport"
class TestIrActionsReportXml(TransactionCase): class TestIrActionsReportXml(TransactionCase):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.Model = self.env["ir.actions.report"] self.Model = self.env["ir.actions.report"].with_context(
skip_printer_exception=True
)
self.vals = {} 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({}) self.server = self.env["printing.server"].create({})
def new_action(self): def new_action(self):
@@ -153,7 +155,7 @@ class TestIrActionsReportXml(TransactionCase):
self.env.user.printing_action = "client" self.env.user.printing_action = "client"
printing_action = self.new_printing_action() printing_action = self.new_printing_action()
printing_action.user_id = self.env.user 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 [("id", "!=", report.id)], limit=1
) )
self.assertEqual( self.assertEqual(
@@ -213,7 +215,7 @@ class TestIrActionsReportXml(TransactionCase):
""" """
It should return the correct tray 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( action = self.env["printing.report.xml.action"].create(
{"user_id": self.env.user.id, "report_id": report.id, "action": "server"} {"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"]) self.assertEqual("Action tray", report.behaviour()["tray"])
def test_onchange_printer_tray_id_empty(self): 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() action.onchange_printing_printer_id()
self.assertFalse(action.printer_tray_id) self.assertFalse(action.printer_tray_id)
@@ -289,7 +291,7 @@ class TestIrActionsReportXml(TransactionCase):
{"name": "Tray", "system_name": "TrayName", "printer_id": printer.id} {"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) self.assertEqual(action.printer_tray_id, tray)
action.onchange_printing_printer_id() action.onchange_printing_printer_id()
self.assertFalse(action.printer_tray_id) self.assertFalse(action.printer_tray_id)

View File

@@ -11,7 +11,9 @@ from odoo.tests import common
class TestReport(common.HttpCase): class TestReport(common.HttpCase):
def setUp(self): def setUp(self):
super().setUp() super().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.server = self.env["printing.server"].create({})
self.report_vals = { self.report_vals = {
"name": "Test Report", "name": "Test Report",