Skip to content

Commit

Permalink
[IMP] base_report_to_printer: out of connection fallback to client
Browse files Browse the repository at this point in the history
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
  • Loading branch information
chienandalu committed Mar 26, 2024
1 parent 6d5c1dd commit daff704
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 9 deletions.
29 changes: 28 additions & 1 deletion base_report_to_printer/models/ir_actions_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging

from odoo import _, api, exceptions, fields, models
from odoo.tools.safe_eval import safe_eval, time

_logger = logging.getLogger(__name__)

REPORT_TYPES = {"qweb-pdf": "pdf", "qweb-text": "text"}


Expand Down Expand Up @@ -53,6 +56,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

Check warning on line 62 in base_report_to_printer/models/ir_actions_report.py

View check run for this annotation

Codecov / codecov/patch

base_report_to_printer/models/ir_actions_report.py#L62

Added line #L62 was not covered by tests
return serializable_result

def _get_user_default_print_behaviour(self):
Expand Down Expand Up @@ -97,6 +104,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 [

Check warning on line 113 in base_report_to_printer/models/ir_actions_report.py

View check run for this annotation

Codecov / codecov/patch

base_report_to_printer/models/ir_actions_report.py#L113

Added line #L113 was not covered by tests
"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

Check warning on line 121 in base_report_to_printer/models/ir_actions_report.py

View check run for this annotation

Codecov / codecov/patch

base_report_to_printer/models/ir_actions_report.py#L121

Added line #L121 was not covered by tests
return result

def print_document(self, record_ids, data=None):
Expand Down Expand Up @@ -140,7 +162,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

Expand Down
15 changes: 14 additions & 1 deletion base_report_to_printer/static/src/js/qweb_action_manager.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ 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,
Expand All @@ -23,6 +27,15 @@ async function cupsReportActionHandler(action, options, env) {
}
return true;
}
if (print_action.printer_exception) {
env.services.notification.add(
env._t("The printer couldn't be reached. Downloading document instead"),
{
sticky: true,
type: "warning",
}
);
}
}
}

Expand Down
14 changes: 8 additions & 6 deletions base_report_to_printer/tests/test_ir_actions_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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"}
)
Expand Down Expand Up @@ -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)

Expand All @@ -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)
4 changes: 3 additions & 1 deletion base_report_to_printer/tests/test_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down

0 comments on commit daff704

Please sign in to comment.