mirror of
https://github.com/OCA/report-print-send.git
synced 2025-02-16 07:11:31 +02:00
[IMP] base_report_to_printer: Add printer option to launch reports in new thread
This commit is contained in:
@@ -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
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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"}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 <<a class="reference external" href="mailto:alexandre.fayolle@camptocamp.com">alexandre.fayolle@camptocamp.com</a>></li>
|
<li>Alexandre Fayolle <<a class="reference external" href="mailto:alexandre.fayolle@camptocamp.com">alexandre.fayolle@camptocamp.com</a>></li>
|
||||||
<li>Matias Peralta <<a class="reference external" href="mailto:mnp@adhoc.com.ar">mnp@adhoc.com.ar</a>></li>
|
<li>Matias Peralta <<a class="reference external" href="mailto:mnp@adhoc.com.ar">mnp@adhoc.com.ar</a>></li>
|
||||||
<li>Akim Juillerat <<a class="reference external" href="mailto:akim.juillerat@camptocamp.com">akim.juillerat@camptocamp.com</a>></li>
|
<li>Akim Juillerat <<a class="reference external" href="mailto:akim.juillerat@camptocamp.com">akim.juillerat@camptocamp.com</a>></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>
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
Reference in New Issue
Block a user