Merge PR #381 into 17.0

Signed-off-by pedrobaeza
This commit is contained in:
OCA-git-bot
2024-11-18 08:53:23 +00:00
17 changed files with 234 additions and 58 deletions

View File

@@ -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 information, you need to change the configuration of your CUPS server
and set the JobPrivateValue directive to "none" (or some other list of and set the JobPrivateValue directive to "none" (or some other list of
values which does not include "job-name") , and reload the server. See values which does not include "job-name") , and reload the server. See
cupsd.conf(5) cupsd.conf(5) <https://www.cups.org/doc/man-cupsd.conf.html> for
<`https://www.cups.org/doc/man-cupsd.conf.html\\> <https://www.cups.org/doc/man-cupsd.conf.html\>>`__ details.
for details.
Usage Usage
===== =====
@@ -112,6 +111,13 @@ Guidelines for use:
When no tray is configured for a report and a user, the default tray When no tray is configured for a report and a user, the default tray
setup on the CUPS server is used. 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 Changelog
========= =========

View File

@@ -18,6 +18,7 @@
"data": [ "data": [
"data/printing_data.xml", "data/printing_data.xml",
"security/security.xml", "security/security.xml",
"security/ir.model.access.csv",
"views/printing_printer.xml", "views/printing_printer.xml",
"views/printing_server.xml", "views/printing_server.xml",
"views/printing_job.xml", "views/printing_job.xml",

View File

@@ -921,7 +921,7 @@ msgstr "Guide"
#: code:addons/base_report_to_printer/wizards/print_attachment_report.py:0 #: code:addons/base_report_to_printer/wizards/print_attachment_report.py:0
#, python-format #, python-format
msgid "{name} ({copies} copies)" msgid "{name} ({copies} copies)"
msgstr "{namn} ({kopior} kopior)" msgstr "{name} ({copies} kopior)"
#~ msgid "Job" #~ msgid "Job"
#~ msgstr "Jobb" #~ msgstr "Jobb"

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"}
@@ -53,6 +55,12 @@ class IrActionsReport(models.Model):
"action": result["action"], "action": result["action"],
"printer_name": result["printer"].name, "printer_name": result["printer"].name,
} }
if result.get("printer_exception") and not self.env.context.get(
"skip_printer_exception"
):
serializable_result["printer_exception"] = True
if self.env.context.get("force_print_to_client"):
serializable_result["action"] = "client"
return serializable_result return serializable_result
def _get_user_default_print_behaviour(self): def _get_user_default_print_behaviour(self):
@@ -97,8 +105,49 @@ class IrActionsReport(models.Model):
# For some reason design takes report defaults over # For some reason design takes report defaults over
# False action entries so we must allow for that here # False action entries so we must allow for that here
result.update({k: v for k, v in print_action.behaviour().items() if v}) 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 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:
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:
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)
@@ -127,6 +176,7 @@ class IrActionsReport(models.Model):
else: else:
title = self.report_name title = self.report_name
behaviour["title"] = title behaviour["title"] = title
behaviour["res_ids"] = record_ids
# TODO should we use doc_format instead of report_type # TODO should we use doc_format instead of report_type
return printer.print_document( return printer.print_document(
self, document, doc_format=self.report_type, **behaviour self, document, doc_format=self.report_type, **behaviour
@@ -140,7 +190,12 @@ class IrActionsReport(models.Model):
""" """
if self.env.context.get("must_skip_send_to_printer"): if self.env.context.get("must_skip_send_to_printer"):
return False 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 True
return False return False

View File

@@ -15,7 +15,7 @@ class PrintingJob(models.Model):
name = fields.Char(help="Job name.") name = fields.Char(help="Job name.")
active = fields.Boolean( 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( job_id_cups = fields.Integer(
string="Job ID", required=True, help="CUPS id for this job." 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.", help="Percentage of progress for this job.",
) )
time_at_creation = fields.Datetime( 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( 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( job_state = fields.Selection(
selection=[ selection=[

View File

@@ -12,7 +12,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__)
@@ -67,11 +67,19 @@ 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"}
cups_vals = { cups_vals = {
"name": cups_printer["printer-info"], "name": self.name or cups_printer["printer-info"],
"model": cups_printer.get("printer-make-and-model", False), "model": cups_printer.get("printer-make-and-model", False),
"location": cups_printer.get("printer-location", False), "location": cups_printer.get("printer-location", False),
"uri": cups_printer.get("device-uri", False), "uri": cups_printer.get("device-uri", False),

View File

@@ -41,6 +41,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()
@@ -121,6 +122,11 @@ class PrintingServer(models.Model):
printer_values["server_id"] = server.id printer_values["server_id"] = server.id
updated_printers.append(name) 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: if not printer:
printer_values["system_name"] = name printer_values["system_name"] = name
printer.create(printer_values) printer.create(printer_values)

View File

@@ -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.

View File

@@ -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
1 id name model_id/id group_id/id perm_read perm_write perm_create perm_unlink
2 access_printing_printer_update_wizard printers update model_printing_printer_update_wizard base.group_system 1 1 1 1

View File

@@ -125,9 +125,10 @@
<field name="name">Update printer wizard</field> <field name="name">Update printer wizard</field>
<field name="model_id" ref="model_printing_printer_update_wizard" /> <field name="model_id" ref="model_printing_printer_update_wizard" />
<field name="group_id" ref="printing_group_manager" /> <field name="group_id" ref="printing_group_manager" />
<field eval="1" name="perm_read" /> <field eval="1" name="perm_read" />
<field eval="1" name="perm_unlink" /> <field eval="1" name="perm_unlink" />
<field eval="1" name="perm_write" /> <field eval="1" name="perm_write" />
<field eval="1" name="perm_create" />
</record> </record>
<record id="access_wizard_print_attachment_user" model="ir.model.access"> <record id="access_wizard_print_attachment_user" model="ir.model.access">
<field name="name">Print Attachment User</field> <field name="name">Print Attachment User</field>

View File

@@ -8,10 +8,11 @@
/* /*
:Author: David Goodger (goodger@python.org) :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. :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.
@@ -274,7 +275,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: grey; } /* line numbers */ pre.code .ln { color: gray; } /* 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 }
@@ -300,7 +301,7 @@ span.option {
span.pre { span.pre {
white-space: pre } white-space: pre }
span.problematic { span.problematic, pre.problematic {
color: red } color: red }
span.section-subtitle { span.section-subtitle {
@@ -398,16 +399,17 @@ preprinted paper such as payment slip.</p>
<li><a class="reference internal" href="#installation" id="toc-entry-1">Installation</a></li> <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="#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="#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="#known-issues-roadmap" id="toc-entry-4">Known issues / Roadmap</a></li>
<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="#changelog" id="toc-entry-5">Changelog</a><ul>
<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="#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> </ul>
</li> </li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-7">Bug Tracker</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-8">Credits</a><ul> <li><a class="reference internal" href="#credits" id="toc-entry-9">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-9">Authors</a></li> <li><a class="reference internal" href="#authors" id="toc-entry-10">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-10">Contributors</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-11">Maintainers</a></li> <li><a class="reference internal" href="#maintainers" id="toc-entry-12">Maintainers</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
@@ -438,9 +440,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 information, you need to change the configuration of your CUPS server
and set the JobPrivateValue directive to “none” (or some other list of and set the JobPrivateValue directive to “none” (or some other list of
values which does not include “job-name”) , and reload the server. See values which does not include “job-name”) , and reload the server. See
cupsd.conf(5) cupsd.conf(5) &lt;<a class="reference external" href="https://www.cups.org/doc/man-cupsd.conf.html">https://www.cups.org/doc/man-cupsd.conf.html</a>&gt; for
&lt;<a class="reference external" href="https://www.cups.org/doc/man-cupsd.conf.html&gt;">https://www.cups.org/doc/man-cupsd.conf.html\&gt;</a> details.</p>
for details.</p>
</div> </div>
<div class="section" id="usage"> <div class="section" id="usage">
<h1><a class="toc-backref" href="#toc-entry-3">Usage</a></h1> <h1><a class="toc-backref" href="#toc-entry-3">Usage</a></h1>
@@ -462,23 +463,31 @@ preferences.</li>
<p>When no tray is configured for a report and a user, the default tray <p>When no tray is configured for a report and a user, the default tray
setup on the CUPS server is used.</p> setup on the CUPS server is used.</p>
</div> </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 theres no download fallback when the issue
isnt 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"> <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"> <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"> <ul class="simple">
<li>[RELEASE] Port from V12.</li> <li>[RELEASE] Port from V12.</li>
</ul> </ul>
</div> </div>
<div class="section" id="section-2"> <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"> <ul class="simple">
<li>[RELEASE] Port from V11.</li> <li>[RELEASE] Port from V11.</li>
</ul> </ul>
</div> </div>
</div> </div>
<div class="section" id="bug-tracker"> <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>. <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. 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 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
<p>Do not contact contributors directly about support or help with technical issues.</p> <p>Do not contact contributors directly about support or help with technical issues.</p>
</div> </div>
<div class="section" id="credits"> <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"> <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"> <ul class="simple">
<li>Agile Business Group &amp; Domsense</li> <li>Agile Business Group &amp; Domsense</li>
<li>Pegueroles SCP</li> <li>Pegueroles SCP</li>
@@ -499,7 +508,7 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
</ul> </ul>
</div> </div>
<div class="section" id="contributors"> <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"> <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>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> <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>
@@ -521,9 +530,11 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
</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-12">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"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a> <a class="reference external image-reference" href="https://odoo-community.org">
<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

@@ -1,4 +1,5 @@
/** @odoo-module */ /** @odoo-module */
import {Markup} from "web.utils";
import {_t} from "@web/core/l10n/translation"; import {_t} from "@web/core/l10n/translation";
import {registry} from "@web/core/registry"; import {registry} from "@web/core/registry";
@@ -9,19 +10,72 @@ async function cupsReportActionHandler(action, options, env) {
const print_action = await orm.call( const print_action = await orm.call(
"ir.actions.report", "ir.actions.report",
"print_action_for_report_name", "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") { var printer_exception = print_action.printer_exception;
const result = await orm.call("ir.actions.report", "print_document", [ if (print_action && print_action.action === "server" && !printer_exception) {
action.id, // The Odoo CUPS backend is ok. We try to print into the printer
action.context.active_ids, const result = await orm.call(
action.data, "ir.actions.report",
]); "print_document_client_action",
[action.id, action.context.active_ids, action.data]
);
if (result) { if (result) {
env.services.notification.add(_t("Successfully sent to printer!")); env.services.notification.add(_t("Successfully sent to printer!"), {
} else { type: "success",
env.services.notification.add(_t("Could not sent to printer!")); });
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
} }
env.services.notification.add(_t("Could not sent to printer!"), {
type: "danger",
});
printer_exception = true;
}
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; return true;
} }
} }

View File

@@ -12,10 +12,12 @@ model = "odoo.addons.base.models.ir_actions_report.IrActionsReport"
class TestIrActionsReportXml(TransactionCase): class TestIrActionsReportXml(TransactionCase):
def setUp(self): def setUp(self):
super().setUp() 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.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({}) self.server = self.env["printing.server"].create({})
def new_action(self): def new_action(self):
@@ -153,7 +155,7 @@ class TestIrActionsReportXml(TransactionCase):
self.env.user.printing_action = "client" self.env.user.printing_action = "client"
printing_action = self.new_printing_action() printing_action = self.new_printing_action()
printing_action.user_id = self.env.user 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 [("id", "!=", report.id)], limit=1
) )
self.assertEqual( self.assertEqual(
@@ -213,7 +215,7 @@ class TestIrActionsReportXml(TransactionCase):
""" """
It should return the correct tray 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( action = self.env["printing.report.xml.action"].create(
{"user_id": self.env.user.id, "report_id": report.id, "action": "server"} {"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"]) self.assertEqual("Action tray", report.behaviour()["tray"])
def test_onchange_printer_tray_id_empty(self): 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() action.onchange_printing_printer_id()
self.assertFalse(action.printer_tray_id) self.assertFalse(action.printer_tray_id)
@@ -289,7 +291,25 @@ class TestIrActionsReportXml(TransactionCase):
{"name": "Tray", "system_name": "TrayName", "printer_id": printer.id} {"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) 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

@@ -40,7 +40,7 @@ class TestPrintingPrinter(TransactionCase):
self.server = self.env["printing.server"].create({}) self.server = self.env["printing.server"].create({})
self.printer = self.env["printing.printer"].create( self.printer = self.env["printing.printer"].create(
{ {
"name": "Printer", "name": "",
"server_id": self.server.id, "server_id": self.server.id,
"system_name": "Sys Name", "system_name": "Sys Name",
"default": True, "default": True,
@@ -105,10 +105,11 @@ class TestPrintingPrinter(TransactionCase):
Check that the update_printers method calls _prepare_update_from_cups Check that the update_printers method calls _prepare_update_from_cups
""" """
self.mock_cups_ppd(cups, file_name=False) self.mock_cups_ppd(cups, file_name=False)
self.assertEqual(self.printer.name, "Printer")
self.ServerModel.update_printers() self.ServerModel.update_printers()
self.assertEqual(self.printer.name, "info") 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) @mock.patch("%s.cups" % server_model)
def test_prepare_update_from_cups_no_ppd(self, cups): def test_prepare_update_from_cups_no_ppd(self, cups):

View File

@@ -11,7 +11,9 @@ from odoo.tests import common
class TestReport(common.HttpCase): class TestReport(common.HttpCase):
def setUp(self): def setUp(self):
super().setUp() 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.server = self.env["printing.server"].create({})
self.report_vals = { self.report_vals = {
"name": "Test Report", "name": "Test Report",

View File

@@ -78,6 +78,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" colspan="2"> <field name="tray_ids" nolabel="1" colspan="2">

View File

@@ -32,6 +32,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 name="printers" string="Printers" /> <separator name="printers" string="Printers" />