Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16.0] base_report_to_printer: forward ports #379

Merged
merged 4 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .oca/oca-port/blacklist/base_report_to_printer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"pull_requests": {
"OCA/report-print-send#275": "It's the migration PR..."
}
}
12 changes: 12 additions & 0 deletions base_report_to_printer/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,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
=========

Expand Down Expand Up @@ -163,6 +170,11 @@ Contributors
* Akim Juillerat <[email protected]>
* Jacques-Etienne Baudoux (BCIM) <[email protected]>

* `Tecnativa <https://www.tecnativa.com>`_:

* Sergio Teruel
* David Vidal

Maintainers
~~~~~~~~~~~

Expand Down
1 change: 1 addition & 0 deletions base_report_to_printer/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
33 changes: 32 additions & 1 deletion base_report_to_printer/models/ir_actions_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
# 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"}
Expand Down Expand Up @@ -57,6 +59,8 @@
"skip_printer_exception"
):
serializable_result["printer_exception"] = True
if self.env.context.get("force_print_to_client"):
serializable_result["action"] = "client"

Check warning on line 63 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#L63

Added line #L63 was not covered by tests
return serializable_result

def _get_user_default_print_behaviour(self):
Expand Down Expand Up @@ -118,6 +122,32 @@
result["printer_exception"] = True
return result

def print_document_client_action(self, record_ids, data=None):
behaviour = self.behaviour()
printer = behaviour.pop("printer", None)

Check warning on line 127 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#L126-L127

Added lines #L126 - L127 were not covered by tests
if printer.multi_thread:

@self.env.cr.postcommit.add
def _launch_print_thread():
threaded_calculation = threading.Thread(

Check warning on line 132 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#L130-L132

Added lines #L130 - L132 were not covered by tests
target=self.print_document_threaded,
args=(self.id, record_ids, data),
)
threaded_calculation.start()

Check warning on line 136 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#L136

Added line #L136 was not covered by tests

return True

Check warning on line 138 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#L138

Added line #L138 was not covered by tests
else:
try:
return self.print_document(record_ids, data=data)
except Exception:
return

Check warning on line 143 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#L140-L143

Added lines #L140 - L143 were not covered by tests

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)

Check warning on line 149 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#L147-L149

Added lines #L147 - L149 were not covered by tests

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)
Expand Down Expand Up @@ -146,6 +176,7 @@
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
Expand Down
12 changes: 10 additions & 2 deletions base_report_to_printer/models/printing_printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import os
from tempfile import mkstemp

from odoo import fields, models
from odoo import api, fields, models

_logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -67,11 +67,19 @@ 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"}
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),
Expand Down
6 changes: 6 additions & 0 deletions base_report_to_printer/models/printing_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
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()
Expand Down Expand Up @@ -121,6 +122,11 @@
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

Check warning on line 129 in base_report_to_printer/models/printing_server.py

View check run for this annotation

Codecov / codecov/patch

base_report_to_printer/models/printing_server.py#L129

Added line #L129 was not covered by tests
if not printer:
printer_values["system_name"] = name
printer.create(printer_values)
Expand Down
5 changes: 5 additions & 0 deletions base_report_to_printer/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,8 @@
* Hughes Damry <[email protected]>
* Akim Juillerat <[email protected]>
* Jacques-Etienne Baudoux (BCIM) <[email protected]>

* `Tecnativa <https://www.tecnativa.com>`_:

* Sergio Teruel
* David Vidal
3 changes: 3 additions & 0 deletions base_report_to_printer/readme/ROADMAP.rst
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 2 additions & 0 deletions base_report_to_printer/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -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
46 changes: 30 additions & 16 deletions base_report_to_printer/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -396,16 +396,17 @@ <h1 class="title">Report to printer</h1>
<li><a class="reference internal" href="#installation" id="toc-entry-1">Installation</a></li>
<li><a class="reference internal" href="#configuration" id="toc-entry-2">Configuration</a></li>
<li><a class="reference internal" href="#usage" id="toc-entry-3">Usage</a></li>
<li><a class="reference internal" href="#changelog" id="toc-entry-4">Changelog</a><ul>
<li><a class="reference internal" href="#section-1" id="toc-entry-5">13.0.1.0.0 (2019-09-30)</a></li>
<li><a class="reference internal" href="#section-2" id="toc-entry-6">12.0.1.0.0 (2018-02-04)</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-4">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#changelog" id="toc-entry-5">Changelog</a><ul>
<li><a class="reference internal" href="#section-1" id="toc-entry-6">13.0.1.0.0 (2019-09-30)</a></li>
<li><a class="reference internal" href="#section-2" id="toc-entry-7">12.0.1.0.0 (2018-02-04)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-7">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-8">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-9">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-10">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-11">Maintainers</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-8">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-9">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-10">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-11">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-12">Maintainers</a></li>
</ul>
</li>
</ul>
Expand Down Expand Up @@ -456,33 +457,41 @@ <h1><a class="toc-backref" href="#toc-entry-3">Usage</a></h1>
<p>When no tray is configured for a report and a user, the
default tray setup on the CUPS server is used.</p>
</div>
<div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#toc-entry-4">Known issues / Roadmap</a></h1>
<ul class="simple">
<li>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.</li>
</ul>
</div>
<div class="section" id="changelog">
<h1><a class="toc-backref" href="#toc-entry-4">Changelog</a></h1>
<h1><a class="toc-backref" href="#toc-entry-5">Changelog</a></h1>
<div class="section" id="section-1">
<h2><a class="toc-backref" href="#toc-entry-5">13.0.1.0.0 (2019-09-30)</a></h2>
<h2><a class="toc-backref" href="#toc-entry-6">13.0.1.0.0 (2019-09-30)</a></h2>
<ul class="simple">
<li>[RELEASE] Port from V12.</li>
</ul>
</div>
<div class="section" id="section-2">
<h2><a class="toc-backref" href="#toc-entry-6">12.0.1.0.0 (2018-02-04)</a></h2>
<h2><a class="toc-backref" href="#toc-entry-7">12.0.1.0.0 (2018-02-04)</a></h2>
<ul class="simple">
<li>[RELEASE] Port from V11.</li>
</ul>
</div>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-7">Bug Tracker</a></h1>
<h1><a class="toc-backref" href="#toc-entry-8">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/report-print-send/issues">GitHub Issues</a>.
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
<a class="reference external" href="https://github.com/OCA/report-print-send/issues/new?body=module:%20base_report_to_printer%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-8">Credits</a></h1>
<h1><a class="toc-backref" href="#toc-entry-9">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-9">Authors</a></h2>
<h2><a class="toc-backref" href="#toc-entry-10">Authors</a></h2>
<ul class="simple">
<li>Agile Business Group &amp; Domsense</li>
<li>Pegueroles SCP</li>
Expand All @@ -493,7 +502,7 @@ <h2><a class="toc-backref" href="#toc-entry-9">Authors</a></h2>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-10">Contributors</a></h2>
<h2><a class="toc-backref" href="#toc-entry-11">Contributors</a></h2>
<ul class="simple">
<li>Ferran Pegueroles &lt;<a class="reference external" href="mailto:ferran&#64;pegueroles.com">ferran&#64;pegueroles.com</a>&gt;</li>
<li>Albert Cervera i Areny &lt;<a class="reference external" href="mailto:albert&#64;nan-tic.com">albert&#64;nan-tic.com</a>&gt;</li>
Expand All @@ -512,10 +521,15 @@ <h2><a class="toc-backref" href="#toc-entry-10">Contributors</a></h2>
<li>Hughes Damry &lt;<a class="reference external" href="mailto:hughes.damry&#64;acsone.eu">hughes.damry&#64;acsone.eu</a>&gt;</li>
<li>Akim Juillerat &lt;<a class="reference external" href="mailto:akim.juillerat&#64;camptocamp.com">akim.juillerat&#64;camptocamp.com</a>&gt;</li>
<li>Jacques-Etienne Baudoux (BCIM) &lt;<a class="reference external" href="mailto:je&#64;bcim.be">je&#64;bcim.be</a>&gt;</li>
<li><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a>:<ul>
<li>Sergio Teruel</li>
<li>David Vidal</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-11">Maintainers</a></h2>
<h2><a class="toc-backref" href="#toc-entry-12">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
Expand Down
76 changes: 57 additions & 19 deletions base_report_to_printer/static/src/js/qweb_action_manager.esm.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/** @odoo-module */
import {Markup} from "web.utils";
import {registry} from "@web/core/registry";

async function cupsReportActionHandler(action, options, env) {
Expand All @@ -8,36 +9,73 @@ 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
) {
const result = await orm.call("ir.actions.report", "print_document", [
action.id,
action.context.active_ids,
action.data,
]);
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",
[action.id, action.context.active_ids, action.data]
);
if (result) {
env.services.notification.add(env._t("Successfully sent to printer!"), {
type: "success",
});
} else {
env.services.notification.add(env._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(env._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(
`<p>${terms.the_report} <strong>${action.name}</strong> ${terms.couldnt_be_printed}</p>`
),
{
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;
}
}
}
Expand Down
17 changes: 17 additions & 0 deletions base_report_to_printer/tests/test_ir_actions_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,20 @@ def test_onchange_printer_tray_id_not_empty(self):
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,
},
)
Loading
Loading