[IMP] base_report_to_printer: Add printer option to launch reports in new thread

This commit is contained in:
sergio-teruel
2024-10-26 23:32:27 +02:00
parent 8a02cdf523
commit ef9de46896
11 changed files with 87 additions and 14 deletions

View File

@@ -161,6 +161,11 @@ Contributors
* Matias Peralta <mnp@adhoc.com.ar> * Matias Peralta <mnp@adhoc.com.ar>
* Akim Juillerat <akim.juillerat@camptocamp.com> * Akim Juillerat <akim.juillerat@camptocamp.com>
* `Tecnativa <https://www.tecnativa.com>`_:
* Sergio Teruel
* David Vidal
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~

View File

@@ -6,6 +6,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 15.0\n" "Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-28 09:59+0000\n"
"PO-Revision-Date: 2024-10-28 09:59+0000\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -464,6 +466,12 @@ msgstr ""
msgid "Model" msgid "Model"
msgstr "" msgstr ""
#. module: base_report_to_printer
#: model:ir.model.fields,field_description:base_report_to_printer.field_printing_printer__multi_thread
#: model:ir.model.fields,field_description:base_report_to_printer.field_printing_server__multi_thread
msgid "Multi Thread"
msgstr ""
#. module: base_report_to_printer #. module: base_report_to_printer
#: model:ir.model.fields,field_description:base_report_to_printer.field_printing_action__name #: model:ir.model.fields,field_description:base_report_to_printer.field_printing_action__name
#: model:ir.model.fields,field_description:base_report_to_printer.field_printing_job__name #: model:ir.model.fields,field_description:base_report_to_printer.field_printing_job__name

View File

@@ -3,9 +3,11 @@
# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>) # Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>) # Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.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). # 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 from odoo.tools.safe_eval import safe_eval, time
REPORT_TYPES = {"qweb-pdf": "pdf", "qweb-text": "text"} REPORT_TYPES = {"qweb-pdf": "pdf", "qweb-text": "text"}
@@ -118,6 +120,29 @@ class IrActionsReport(models.Model):
result["printer_exception"] = True result["printer_exception"] = True
return result 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): def print_document(self, record_ids, data=None):
"""Print a document, do not return the document file""" """Print a document, do not return the document file"""
report_type = REPORT_TYPES.get(self.report_type) report_type = REPORT_TYPES.get(self.report_type)

View File

@@ -11,7 +11,7 @@ import logging
import os import os
from tempfile import mkstemp from tempfile import mkstemp
from odoo import fields, models from odoo import api, fields, models
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@@ -66,6 +66,14 @@ class PrintingPrinter(models.Model):
tray_ids = fields.One2many( tray_ids = fields.One2many(
comodel_name="printing.tray", inverse_name="printer_id", string="Paper Sources" 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): def _prepare_update_from_cups(self, cups_connection, cups_printer):
mapping = {3: "available", 4: "printing", 5: "error"} mapping = {3: "available", 4: "printing", 5: "error"}

View File

@@ -42,6 +42,7 @@ class PrintingServer(models.Model):
string="Printers List", string="Printers List",
help="List of printers available on this server.", help="List of printers available on this server.",
) )
multi_thread = fields.Boolean()
def _open_connection(self, raise_on_error=False): def _open_connection(self, raise_on_error=False):
self.ensure_one() self.ensure_one()

View File

@@ -13,3 +13,8 @@
* Alexandre Fayolle <alexandre.fayolle@camptocamp.com> * Alexandre Fayolle <alexandre.fayolle@camptocamp.com>
* Matias Peralta <mnp@adhoc.com.ar> * Matias Peralta <mnp@adhoc.com.ar>
* Akim Juillerat <akim.juillerat@camptocamp.com> * Akim Juillerat <akim.juillerat@camptocamp.com>
* `Tecnativa <https://www.tecnativa.com>`_:
* Sergio Teruel
* David Vidal

View File

@@ -8,11 +8,10 @@
/* /*
:Author: David Goodger (goodger@python.org) :Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $ :Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Copyright: This stylesheet has been placed in the public domain. :Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils. 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 See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet. customize this style sheet.
@@ -275,7 +274,7 @@ pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ; margin-left: 2em ;
margin-right: 2em } margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */ pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee } pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 } pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
@@ -301,7 +300,7 @@ span.option {
span.pre { span.pre {
white-space: pre } white-space: pre }
span.problematic, pre.problematic { span.problematic {
color: red } color: red }
span.section-subtitle { span.section-subtitle {
@@ -510,14 +509,17 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
<li>Alexandre Fayolle &lt;<a class="reference external" href="mailto:alexandre.fayolle&#64;camptocamp.com">alexandre.fayolle&#64;camptocamp.com</a>&gt;</li> <li>Alexandre Fayolle &lt;<a class="reference external" href="mailto:alexandre.fayolle&#64;camptocamp.com">alexandre.fayolle&#64;camptocamp.com</a>&gt;</li>
<li>Matias Peralta &lt;<a class="reference external" href="mailto:mnp&#64;adhoc.com.ar">mnp&#64;adhoc.com.ar</a>&gt;</li> <li>Matias Peralta &lt;<a class="reference external" href="mailto:mnp&#64;adhoc.com.ar">mnp&#64;adhoc.com.ar</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>Akim Juillerat &lt;<a class="reference external" href="mailto:akim.juillerat&#64;camptocamp.com">akim.juillerat&#64;camptocamp.com</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> </ul>
</div> </div>
<div class="section" id="maintainers"> <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-11">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p> <p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"> <a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose <p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and mission is to support the collaborative development of Odoo features and
promote its widespread use.</p> promote its widespread use.</p>

View File

@@ -15,11 +15,11 @@ async function cupsReportActionHandler(action, options, env) {
print_action.action === "server" && print_action.action === "server" &&
!print_action.printer_exception !print_action.printer_exception
) { ) {
const result = await orm.call("ir.actions.report", "print_document", [ const result = await orm.call(
action.id, "ir.actions.report",
action.context.active_ids, "print_document_client_action",
action.data, [action.id, action.context.active_ids, action.data]
]); );
if (result) { if (result) {
env.services.notification.add(env._t("Successfully sent to printer!"), { env.services.notification.add(env._t("Successfully sent to printer!"), {
type: "success", type: "success",

View File

@@ -295,3 +295,20 @@ class TestIrActionsReportXml(TransactionCase):
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)
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,
},
)

View File

@@ -76,6 +76,7 @@
<field name="location" /> <field name="location" />
<field name="status" /> <field name="status" />
<field name="status_message" /> <field name="status_message" />
<field name="multi_thread" />
</group> </group>
<group string="Trays" name="trays"> <group string="Trays" name="trays">
<field name="tray_ids" nolabel="1"> <field name="tray_ids" nolabel="1">

View File

@@ -31,6 +31,7 @@
<field name="user" /> <field name="user" />
<field name="password" /> <field name="password" />
<field name="encryption_policy" /> <field name="encryption_policy" />
<field name="multi_thread" />
</group> </group>
<group> <group>
<separator string="Printers" colspan="2" /> <separator string="Printers" colspan="2" />