From e733e9f89a104a9929448b4916fb9ffe9d083fe7 Mon Sep 17 00:00:00 2001
From: Alexis de Lattre
Date: Fri, 3 Nov 2023 20:11:24 +0100
Subject: [PATCH 1/7] base_report_to_printer: fix string
---
base_report_to_printer/models/printing_job.py | 12 ++++++++----
.../static/src/js/qweb_action_manager.esm.js | 2 +-
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/base_report_to_printer/models/printing_job.py b/base_report_to_printer/models/printing_job.py
index 6d9a347..d38fc2c 100644
--- a/base_report_to_printer/models/printing_job.py
+++ b/base_report_to_printer/models/printing_job.py
@@ -15,7 +15,7 @@ class PrintingJob(models.Model):
name = fields.Char(help="Job name.")
active = fields.Boolean(
- default=True, help="Unchecked if the job is purged from cups."
+ default=True, help="Unchecked if the job is purged from CUPS."
)
job_id_cups = fields.Integer(
string="Job ID", required=True, help="CUPS id for this job."
@@ -40,11 +40,15 @@ class PrintingJob(models.Model):
help="Percentage of progress for this job.",
)
time_at_creation = fields.Datetime(
- required=True, help="Date and time of creation for this job."
+ string="Creation Date",
+ required=True,
+ help="Date and time of creation of this job.",
+ )
+ time_at_processing = fields.Datetime(
+ string="Processing Date", help="Date and time of process for this job."
)
- time_at_processing = fields.Datetime(help="Date and time of process for this job.")
time_at_completed = fields.Datetime(
- help="Date and time of completion for this job."
+ string="Completion Date", help="Date and time of completion for this job."
)
job_state = fields.Selection(
selection=[
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 d9f9769..f9cfd9c 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
@@ -20,7 +20,7 @@ async function cupsReportActionHandler(action, options, env) {
if (result) {
env.services.notification.add(_t("Successfully sent to printer!"));
} else {
- env.services.notification.add(_t("Could not sent to printer!"));
+ env.services.notification.add(_t("Could not send to printer!"));
}
return true;
}
From 540e5269d2a4bc99569abbf7ec278eb6fb840ffa Mon Sep 17 00:00:00 2001
From: dtec-landoo
Date: Wed, 27 Mar 2024 14:20:53 +0100
Subject: [PATCH 2/7] [16.0][FIX] base_report_to_printer: Allow create option
---
base_report_to_printer/security/security.xml | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/base_report_to_printer/security/security.xml b/base_report_to_printer/security/security.xml
index 8f68e12..e0c9e22 100644
--- a/base_report_to_printer/security/security.xml
+++ b/base_report_to_printer/security/security.xml
@@ -125,9 +125,10 @@
Update printer wizard
-
-
-
+
+
+
+
Print Attachment User
From 41847575ec22254c50228607db12af92d284a620 Mon Sep 17 00:00:00 2001
From: David
Date: Wed, 31 Jan 2024 13:02:02 +0100
Subject: [PATCH 3/7] [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 bff6897..0547709 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 f9cfd9c..7b95ed0 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
@@ -11,19 +11,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(_t("Successfully sent to printer!"));
+ env.services.notification.add(_t("Successfully sent to printer!"), {
+ type: "success",
+ });
} 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;
}
+ 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 0ba5a87..5b5578b 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().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 e93d0a0..e821962 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().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",
From 6f027e2f8cae361beb2299f4d7ffe748d4b2b0a4 Mon Sep 17 00:00:00 2001
From: David
Date: Wed, 20 Sep 2023 11:19:15 +0200
Subject: [PATCH 4/7] [FIX] base_report_to_printer: update printers wizard
- Add access rules to the wizard
- Set a fallback name for the printers and respect the user custom ones
TT45159
---
base_report_to_printer/__manifest__.py | 1 +
base_report_to_printer/models/printing_printer.py | 2 +-
base_report_to_printer/models/printing_server.py | 5 +++++
base_report_to_printer/security/ir.model.access.csv | 2 ++
base_report_to_printer/tests/test_printing_printer_tray.py | 7 ++++---
5 files changed, 13 insertions(+), 4 deletions(-)
create mode 100644 base_report_to_printer/security/ir.model.access.csv
diff --git a/base_report_to_printer/__manifest__.py b/base_report_to_printer/__manifest__.py
index 2105161..8ba8600 100644
--- a/base_report_to_printer/__manifest__.py
+++ b/base_report_to_printer/__manifest__.py
@@ -18,6 +18,7 @@
"data": [
"data/printing_data.xml",
"security/security.xml",
+ "security/ir.model.access.csv",
"views/printing_printer.xml",
"views/printing_server.xml",
"views/printing_job.xml",
diff --git a/base_report_to_printer/models/printing_printer.py b/base_report_to_printer/models/printing_printer.py
index 8d2811e..67fc590 100644
--- a/base_report_to_printer/models/printing_printer.py
+++ b/base_report_to_printer/models/printing_printer.py
@@ -71,7 +71,7 @@ class PrintingPrinter(models.Model):
def _prepare_update_from_cups(self, cups_connection, cups_printer):
mapping = {3: "available", 4: "printing", 5: "error"}
cups_vals = {
- "name": cups_printer["printer-info"],
+ "name": self.name or cups_printer["printer-info"],
"model": cups_printer.get("printer-make-and-model", False),
"location": cups_printer.get("printer-location", False),
"uri": cups_printer.get("device-uri", False),
diff --git a/base_report_to_printer/models/printing_server.py b/base_report_to_printer/models/printing_server.py
index d5958f7..a072567 100644
--- a/base_report_to_printer/models/printing_server.py
+++ b/base_report_to_printer/models/printing_server.py
@@ -121,6 +121,11 @@ class PrintingServer(models.Model):
printer_values["server_id"] = server.id
updated_printers.append(name)
+ # We want to keep any existing customized name over existing printer
+ # We want also to rely in the system name as a fallback to avoid
+ # empty names.
+ if not printer_values.get("name") and not printer.name:
+ printer_values["name"] = name
if not printer:
printer_values["system_name"] = name
printer.create(printer_values)
diff --git a/base_report_to_printer/security/ir.model.access.csv b/base_report_to_printer/security/ir.model.access.csv
new file mode 100644
index 0000000..b97fc91
--- /dev/null
+++ b/base_report_to_printer/security/ir.model.access.csv
@@ -0,0 +1,2 @@
+id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
+access_printing_printer_update_wizard,printers update,model_printing_printer_update_wizard,base.group_system,1,1,1,1
diff --git a/base_report_to_printer/tests/test_printing_printer_tray.py b/base_report_to_printer/tests/test_printing_printer_tray.py
index 1588643..c0168ff 100644
--- a/base_report_to_printer/tests/test_printing_printer_tray.py
+++ b/base_report_to_printer/tests/test_printing_printer_tray.py
@@ -40,7 +40,7 @@ class TestPrintingPrinter(TransactionCase):
self.server = self.env["printing.server"].create({})
self.printer = self.env["printing.printer"].create(
{
- "name": "Printer",
+ "name": "",
"server_id": self.server.id,
"system_name": "Sys Name",
"default": True,
@@ -105,10 +105,11 @@ class TestPrintingPrinter(TransactionCase):
Check that the update_printers method calls _prepare_update_from_cups
"""
self.mock_cups_ppd(cups, file_name=False)
-
- self.assertEqual(self.printer.name, "Printer")
self.ServerModel.update_printers()
self.assertEqual(self.printer.name, "info")
+ self.printer.name = "My custom name"
+ self.ServerModel.update_printers()
+ self.assertEqual(self.printer.name, "My custom name")
@mock.patch("%s.cups" % server_model)
def test_prepare_update_from_cups_no_ppd(self, cups):
From f097b37767f333d4a98729a1b91bf67102d5e820 Mon Sep 17 00:00:00 2001
From: sergio-teruel
Date: Sat, 26 Oct 2024 23:32:27 +0200
Subject: [PATCH 5/7] [IMP] base_report_to_printer: Add printer option to
launch reports in new thread
---
base_report_to_printer/README.rst | 5 ++--
.../models/ir_actions_report.py | 27 ++++++++++++++++++-
.../models/printing_printer.py | 10 ++++++-
.../models/printing_server.py | 1 +
.../static/description/index.html | 16 ++++++-----
.../static/src/js/qweb_action_manager.esm.js | 10 +++----
.../tests/test_ir_actions_report.py | 18 +++++++++++++
.../views/printing_printer.xml | 1 +
.../views/printing_server.xml | 1 +
9 files changed, 72 insertions(+), 17 deletions(-)
diff --git a/base_report_to_printer/README.rst b/base_report_to_printer/README.rst
index 009291b..1613e83 100644
--- a/base_report_to_printer/README.rst
+++ b/base_report_to_printer/README.rst
@@ -89,9 +89,8 @@ this will not be displayed by CUPS web interface or in Odoo. To see this
information, you need to change the configuration of your CUPS server
and set the JobPrivateValue directive to "none" (or some other list of
values which does not include "job-name") , and reload the server. See
-cupsd.conf(5)
-<`https://www.cups.org/doc/man-cupsd.conf.html\\> >`__
-for details.
+cupsd.conf(5) for
+details.
Usage
=====
diff --git a/base_report_to_printer/models/ir_actions_report.py b/base_report_to_printer/models/ir_actions_report.py
index 0547709..395837f 100644
--- a/base_report_to_printer/models/ir_actions_report.py
+++ b/base_report_to_printer/models/ir_actions_report.py
@@ -3,9 +3,11 @@
# Copyright (C) 2011 Agile Business Group sagl ()
# Copyright (C) 2011 Domsense srl ()
# Copyright (C) 2013-2014 Camptocamp ()
+# Copyright 2024 Tecnativa - Sergio Teruel
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+import threading
-from odoo import _, api, exceptions, fields, models
+from odoo import _, api, exceptions, fields, models, registry
from odoo.tools.safe_eval import safe_eval, time
REPORT_TYPES = {"qweb-pdf": "pdf", "qweb-text": "text"}
@@ -118,6 +120,29 @@ class IrActionsReport(models.Model):
result["printer_exception"] = True
return result
+ def print_document_client_action(self, record_ids, data=None):
+ behaviour = self.behaviour()
+ printer = behaviour.pop("printer", None)
+ if printer.multi_thread:
+
+ @self.env.cr.postcommit.add
+ def _launch_print_thread():
+ threaded_calculation = threading.Thread(
+ target=self.print_document_threaded,
+ args=(self.id, record_ids, data),
+ )
+ threaded_calculation.start()
+
+ return True
+ else:
+ return self.print_document(record_ids, data=data)
+
+ def print_document_threaded(self, report_id, record_ids, data):
+ with registry(self._cr.dbname).cursor() as cr:
+ self = self.with_env(self.env(cr=cr))
+ report = self.env["ir.actions.report"].browse(report_id)
+ report.print_document(record_ids, data)
+
def print_document(self, record_ids, data=None):
"""Print a document, do not return the document file"""
report_type = REPORT_TYPES.get(self.report_type)
diff --git a/base_report_to_printer/models/printing_printer.py b/base_report_to_printer/models/printing_printer.py
index 67fc590..a7e2587 100644
--- a/base_report_to_printer/models/printing_printer.py
+++ b/base_report_to_printer/models/printing_printer.py
@@ -12,7 +12,7 @@ import logging
import os
from tempfile import mkstemp
-from odoo import fields, models
+from odoo import api, fields, models
_logger = logging.getLogger(__name__)
@@ -67,6 +67,14 @@ class PrintingPrinter(models.Model):
tray_ids = fields.One2many(
comodel_name="printing.tray", inverse_name="printer_id", string="Paper Sources"
)
+ multi_thread = fields.Boolean(
+ compute="_compute_multi_thread", readonly=False, store=True
+ )
+
+ @api.depends("server_id.multi_thread")
+ def _compute_multi_thread(self):
+ for printer in self:
+ printer.multi_thread = printer.server_id.multi_thread
def _prepare_update_from_cups(self, cups_connection, cups_printer):
mapping = {3: "available", 4: "printing", 5: "error"}
diff --git a/base_report_to_printer/models/printing_server.py b/base_report_to_printer/models/printing_server.py
index a072567..6d64088 100644
--- a/base_report_to_printer/models/printing_server.py
+++ b/base_report_to_printer/models/printing_server.py
@@ -41,6 +41,7 @@ class PrintingServer(models.Model):
string="Printers List",
help="List of printers available on this server.",
)
+ multi_thread = fields.Boolean()
def _open_connection(self, raise_on_error=False):
self.ensure_one()
diff --git a/base_report_to_printer/static/description/index.html b/base_report_to_printer/static/description/index.html
index 6aec188..5b5360f 100644
--- a/base_report_to_printer/static/description/index.html
+++ b/base_report_to_printer/static/description/index.html
@@ -8,10 +8,11 @@
/*
:Author: David Goodger (goodger@python.org)
-:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
+:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
+Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
@@ -274,7 +275,7 @@ pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
-pre.code .ln { color: grey; } /* line numbers */
+pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
@@ -300,7 +301,7 @@ span.option {
span.pre {
white-space: pre }
-span.problematic {
+span.problematic, pre.problematic {
color: red }
span.section-subtitle {
@@ -438,9 +439,8 @@ this will not be displayed by CUPS web interface or in Odoo. To see this
information, you need to change the configuration of your CUPS server
and set the JobPrivateValue directive to “none” (or some other list of
values which does not include “job-name”) , and reload the server. See
-cupsd.conf(5)
-<https://www.cups.org/doc/man-cupsd.conf.html\>
-for details.
+cupsd.conf(5) <https://www.cups.org/doc/man-cupsd.conf.html> for
+details.
@@ -523,7 +523,9 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
This module is maintained by the OCA.
-

+
+
+
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
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 7b95ed0..3c3a90f 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
@@ -16,11 +16,11 @@ async function cupsReportActionHandler(action, options, env) {
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,
- ]);
+ const result = await orm.call(
+ "ir.actions.report",
+ "print_document_client_action",
+ [action.id, action.context.active_ids, action.data]
+ );
if (result) {
env.services.notification.add(_t("Successfully sent to printer!"), {
type: "success",
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 5b5578b..4e1e77d 100644
--- a/base_report_to_printer/tests/test_ir_actions_report.py
+++ b/base_report_to_printer/tests/test_ir_actions_report.py
@@ -295,3 +295,21 @@ class TestIrActionsReportXml(TransactionCase):
self.assertEqual(action.printer_tray_id, tray)
action.onchange_printing_printer_id()
self.assertFalse(action.printer_tray_id)
+
+ def test_print_in_new_thread(self):
+ """It should return the action and printer from printing action in other
+ thread"""
+ report = self.Model.search([], limit=1)
+ self.env.user.printing_action = "server"
+ printing_action = self.new_printing_action()
+ printing_action.user_id = self.env.user
+ printing_action.printer_id = self.new_printer()
+ printing_action.printer_id.multi_thread = True
+ self.assertEqual(
+ report.behaviour(),
+ {
+ "action": printing_action.action,
+ "printer": printing_action.printer_id,
+ "tray": False,
+ },
+ )
diff --git a/base_report_to_printer/views/printing_printer.xml b/base_report_to_printer/views/printing_printer.xml
index 4424c84..0c7f0f4 100644
--- a/base_report_to_printer/views/printing_printer.xml
+++ b/base_report_to_printer/views/printing_printer.xml
@@ -78,6 +78,7 @@
+
diff --git a/base_report_to_printer/views/printing_server.xml b/base_report_to_printer/views/printing_server.xml
index de9a04b..259ec1a 100644
--- a/base_report_to_printer/views/printing_server.xml
+++ b/base_report_to_printer/views/printing_server.xml
@@ -32,6 +32,7 @@
+
From b9e968510c25a23070bf290c166f1bef3491784d Mon Sep 17 00:00:00 2001
From: David
Date: Mon, 11 Nov 2024 13:31:15 +0100
Subject: [PATCH 6/7] [IMP] base_report_to_printer: exceptions notifications
Better handling of exceptions feedback. A notification will show up with
the issued printer and report and a button for the user to download the
report as a fallback to the failure.
TT51628
---
base_report_to_printer/README.rst | 7 ++
.../models/ir_actions_report.py | 8 ++-
base_report_to_printer/readme/ROADMAP.md | 3 +
.../static/description/index.html | 41 +++++++-----
.../static/src/js/qweb_action_manager.esm.js | 66 +++++++++++++++----
5 files changed, 94 insertions(+), 31 deletions(-)
create mode 100644 base_report_to_printer/readme/ROADMAP.md
diff --git a/base_report_to_printer/README.rst b/base_report_to_printer/README.rst
index 1613e83..526f4d4 100644
--- a/base_report_to_printer/README.rst
+++ b/base_report_to_printer/README.rst
@@ -111,6 +111,13 @@ Guidelines for use:
When no tray is configured for a report and a user, the default tray
setup on the CUPS server is used.
+Known issues / Roadmap
+======================
+
+- With threaded printing there's no download fallback when the issue
+ isn't detected by the CUPS Odoo backend. To able to do it, we would
+ need to notify the bus or use web_notify for it.
+
Changelog
=========
diff --git a/base_report_to_printer/models/ir_actions_report.py b/base_report_to_printer/models/ir_actions_report.py
index 395837f..8af5143 100644
--- a/base_report_to_printer/models/ir_actions_report.py
+++ b/base_report_to_printer/models/ir_actions_report.py
@@ -59,6 +59,8 @@ class IrActionsReport(models.Model):
"skip_printer_exception"
):
serializable_result["printer_exception"] = True
+ if self.env.context.get("force_print_to_client"):
+ serializable_result["action"] = "client"
return serializable_result
def _get_user_default_print_behaviour(self):
@@ -135,7 +137,10 @@ class IrActionsReport(models.Model):
return True
else:
- return self.print_document(record_ids, data=data)
+ try:
+ return self.print_document(record_ids, data=data)
+ except Exception:
+ return
def print_document_threaded(self, report_id, record_ids, data):
with registry(self._cr.dbname).cursor() as cr:
@@ -171,6 +176,7 @@ class IrActionsReport(models.Model):
else:
title = self.report_name
behaviour["title"] = title
+ behaviour["res_ids"] = record_ids
# TODO should we use doc_format instead of report_type
return printer.print_document(
self, document, doc_format=self.report_type, **behaviour
diff --git a/base_report_to_printer/readme/ROADMAP.md b/base_report_to_printer/readme/ROADMAP.md
new file mode 100644
index 0000000..f35d11c
--- /dev/null
+++ b/base_report_to_printer/readme/ROADMAP.md
@@ -0,0 +1,3 @@
+- With threaded printing there's no download fallback when the issue
+ isn't detected by the CUPS Odoo backend. To able to do it, we would
+ need to notify the bus or use web_notify for it.
diff --git a/base_report_to_printer/static/description/index.html b/base_report_to_printer/static/description/index.html
index 5b5360f..7732f22 100644
--- a/base_report_to_printer/static/description/index.html
+++ b/base_report_to_printer/static/description/index.html
@@ -399,16 +399,17 @@ preprinted paper such as payment slip.
Installation
Configuration
Usage
-Changelog
+
+
+
+- With threaded printing there’s no download fallback when the issue
+isn’t detected by the CUPS Odoo backend. To able to do it, we would
+need to notify the bus or use web_notify for it.
+
+
-
+
Bugs are tracked on GitHub Issues.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
@@ -486,9 +495,9 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
Do not contact contributors directly about support or help with technical issues.
-
+
-
+
- Agile Business Group & Domsense
- Pegueroles SCP
@@ -499,7 +508,7 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
-
+
This module is maintained by the OCA.
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 3c3a90f..2d110dc 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
@@ -1,4 +1,5 @@
/** @odoo-module */
+import {Markup} from "web.utils";
import {_t} from "@web/core/l10n/translation";
import {registry} from "@web/core/registry";
@@ -9,13 +10,12 @@ async function cupsReportActionHandler(action, options, env) {
const print_action = await orm.call(
"ir.actions.report",
"print_action_for_report_name",
- [action.report_name]
+ [action.report_name],
+ {context: {force_print_to_client: action.context.force_print_to_client}}
);
- if (
- print_action &&
- print_action.action === "server" &&
- !print_action.printer_exception
- ) {
+ var printer_exception = print_action.printer_exception;
+ if (print_action && print_action.action === "server" && !printer_exception) {
+ // The Odoo CUPS backend is ok. We try to print into the printer
const result = await orm.call(
"ir.actions.report",
"print_document_client_action",
@@ -25,20 +25,58 @@ async function cupsReportActionHandler(action, options, env) {
env.services.notification.add(_t("Successfully sent to printer!"), {
type: "success",
});
- } else {
- env.services.notification.add(_t("Could not send to printer!"), {
- type: "danger",
- });
+ return true;
+ // In case of exception during the job, we won't get any response. So we
+ // should flag the exception and notify the user
}
- return true;
+ env.services.notification.add(_t("Could not sent to printer!"), {
+ type: "danger",
+ });
+ printer_exception = true;
}
- if (print_action.printer_exception) {
- env.services.notification.add(
- env._t("The printer couldn't be reached. Downloading document instead"),
+ if (print_action && print_action.action === "server" && printer_exception) {
+ // Just so the translation engine detects them as it doesn't do it inside
+ // template strings
+ const terms = {
+ the_report: env._t("The report"),
+ couldnt_be_printed: env._t(
+ "couldn't be printed. Click on the button below to download it"
+ ),
+ issue_on: env._t("Issue on"),
+ };
+ const notificationRemove = env.services.notification.add(
+ Markup(
+ `${terms.the_report} ${action.name} ${terms.couldnt_be_printed}
`
+ ),
{
+ title: `${terms.issue_on} ${print_action.printer_name}`,
type: "warning",
+ sticky: true,
+ messageIsHtml: true,
+ buttons: [
+ {
+ name: env._t("Print"),
+ primary: true,
+ icon: "fa-print",
+ onClick: async () => {
+ const context = {
+ force_print_to_client: true,
+ must_skip_send_to_printer: true,
+ };
+ env.services.user.updateContext(context);
+ await env.services.action.doAction(
+ {type: "ir.actions.report", ...action},
+ {
+ additionalContext: context,
+ }
+ );
+ notificationRemove();
+ },
+ },
+ ],
}
);
+ return true;
}
}
}
From 5b5444fd7e66c1238b1b7b7f1fefbbcedfd60498 Mon Sep 17 00:00:00 2001
From: David
Date: Fri, 15 Nov 2024 17:20:54 +0100
Subject: [PATCH 7/7] [FIX] base_report_to_printer: wrong translation
---
base_report_to_printer/i18n/sv.po | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/base_report_to_printer/i18n/sv.po b/base_report_to_printer/i18n/sv.po
index 6c84e31..3f0f419 100644
--- a/base_report_to_printer/i18n/sv.po
+++ b/base_report_to_printer/i18n/sv.po
@@ -921,7 +921,7 @@ msgstr "Guide"
#: code:addons/base_report_to_printer/wizards/print_attachment_report.py:0
#, python-format
msgid "{name} ({copies} copies)"
-msgstr "{namn} ({kopior} kopior)"
+msgstr "{name} ({copies} kopior)"
#~ msgid "Job"
#~ msgstr "Jobb"