Skip to content
Open
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
86 changes: 41 additions & 45 deletions base_report_to_printer/README.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

=================
Report to printer
=================
Expand All @@ -17,7 +13,7 @@ Report to printer
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Freport--print--send-lightgray.png?logo=github
Expand All @@ -38,9 +34,9 @@ server.
It adds an optional behaviour on reports to send it directly to a
printer.

- Send to Client is the default behaviour providing you a downloadable
PDF
- Send to Printer prints the report on selected printer
- Send to Client is the default behaviour providing you a downloadable
PDF
- Send to Printer prints the report on selected printer

It detects trays on printers installation plus permits to select the
paper source on which you want to print directly.
Expand All @@ -55,10 +51,10 @@ preprinted paper such as payment slip.

Settings can be configured:

- globally
- per user
- per report
- per user and report
- globally
- per user
- per report
- per user and report

**Table of contents**

Expand Down Expand Up @@ -102,39 +98,39 @@ Usage

Guidelines for use:

- To update the CUPS printers in *Settings > Printing > Update
Printers from CUPS*
- To print a report on a specific printer or tray, you can change
these in *Settings > Printing > Reports* to define default
behaviour.
- To print a report on a specific printer and/or tray for a user, you
can change these in *Settings > Printing > Reports* in *Specific
actions per user*
- Users may also select a default action, printer or tray in their
preferences.
- To update the CUPS printers in *Settings > Printing > Update
Printers from CUPS*
- To print a report on a specific printer or tray, you can change
these in *Settings > Printing > Reports* to define default
behaviour.
- To print a report on a specific printer and/or tray for a user,
you can change these in *Settings > Printing > Reports* in
*Specific actions per user*
- Users may also select a default action, printer or tray in their
preferences.

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

13.0.1.0.0 (2019-09-30)
-----------------------

- [RELEASE] Port from V12.
- [RELEASE] Port from V12.

12.0.1.0.0 (2018-02-04)
-----------------------

- [RELEASE] Port from V11.
- [RELEASE] Port from V11.

Bug Tracker
===========
Expand Down Expand Up @@ -162,24 +158,24 @@ Authors
Contributors
------------

- Ferran Pegueroles <ferran@pegueroles.com>
- Albert Cervera i Areny <albert@nan-tic.com>
- Davide Corio <davide.corio@agilebg.com>
- Lorenzo Battistini <lorenzo.battistini@agilebg.com>
- Yannick Vaucher <yannick.vaucher@camptocamp.com>
- Lionel Sausin <ls@numerigraphe.com>
- Guewen Baconnier <guewen.baconnier@camptocamp.com>
- Dave Lasley <dave@laslabs.com>
- Sylvain Garancher <sylvain.garancher@syleam.fr>
- Jairo Llopis <jairo.llopis@tecnativa.com>
- Graeme Gellatly <graeme@o4sb.com>
- Rod Schouteden <rod@schout-it.be>
- Alexandre Fayolle <alexandre.fayolle@camptocamp.com>
- Matias Peralta <mnp@adhoc.com.ar>
- Hughes Damry <hughes.damry@acsone.eu>
- Akim Juillerat <akim.juillerat@camptocamp.com>
- Jacques-Etienne Baudoux (BCIM) <je@bcim.be>
- Tris Doan <tridm@trobz.com>
- Ferran Pegueroles <ferran@pegueroles.com>
- Albert Cervera i Areny <albert@nan-tic.com>
- Davide Corio <davide.corio@agilebg.com>
- Lorenzo Battistini <lorenzo.battistini@agilebg.com>
- Yannick Vaucher <yannick.vaucher@camptocamp.com>
- Lionel Sausin <ls@numerigraphe.com>
- Guewen Baconnier <guewen.baconnier@camptocamp.com>
- Dave Lasley <dave@laslabs.com>
- Sylvain Garancher <sylvain.garancher@syleam.fr>
- Jairo Llopis <jairo.llopis@tecnativa.com>
- Graeme Gellatly <graeme@o4sb.com>
- Rod Schouteden <rod@schout-it.be>
- Alexandre Fayolle <alexandre.fayolle@camptocamp.com>
- Matias Peralta <mnp@adhoc.com.ar>
- Hughes Damry <hughes.damry@acsone.eu>
- Akim Juillerat <akim.juillerat@camptocamp.com>
- Jacques-Etienne Baudoux (BCIM) <je@bcim.be>
- Tris Doan <tridm@trobz.com>

Other credits
-------------
Expand Down
2 changes: 1 addition & 1 deletion base_report_to_printer/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

{
"name": "Report to printer",
"version": "18.0.1.1.4",
"version": "18.0.1.1.5",
"category": "Generic Modules/Base",
"author": "Agile Business Group & Domsense, Pegueroles SCP, NaN,"
" LasLabs, Camptocamp, Odoo Community Association (OCA),"
Expand Down
30 changes: 30 additions & 0 deletions base_report_to_printer/migrations/18.0.1.1.5/pre-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from openupgradelib import openupgrade


@openupgrade.migrate()
def migrate(env, version):
openupgrade.rename_models(env.cr, [("printing.tray", "printing.tray.input")])
openupgrade.rename_tables(env.cr, [("printing_tray", "printing_tray_input")])
openupgrade.rename_fields(
env,
[
(
"ir.actions.report",
"ir_actions_report",
"printer_tray_id",
"printer_input_tray_id",
),
(
"printing.report.xml.action",
"printing_report_xml_action",
"printer_tray_id",
"printer_input_tray_id",
),
(
"res.users",
"res_users",
"printer_tray_id",
"printer_input_tray_id",
),
],
)
27 changes: 20 additions & 7 deletions base_report_to_printer/models/ir_actions_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,16 @@ class IrActionsReport(models.Model):
printing_printer_id = fields.Many2one(
comodel_name="printing.printer", string="Default Printer"
)
printer_tray_id = fields.Many2one(
comodel_name="printing.tray",
printer_input_tray_id = fields.Many2one(
comodel_name="printing.tray.input",
string="Paper Source",
domain="[('printer_id', '=', printing_printer_id)]",
)
printer_output_tray_id = fields.Many2one(
comodel_name="printing.tray.output",
string="Output Bin",
domain="[('printer_id', '=', printing_printer_id)]",
)
printing_action_ids = fields.One2many(
comodel_name="printing.report.xml.action",
inverse_name="report_id",
Expand All @@ -40,7 +45,8 @@ class IrActionsReport(models.Model):
@api.onchange("printing_printer_id")
def onchange_printing_printer_id(self):
"""Reset the tray when the printer is changed"""
self.printer_tray_id = False
self.printer_input_tray_id = False
self.printer_output_tray_id = False

@api.model
def print_action_for_report_name(self, report_name):
Expand Down Expand Up @@ -74,8 +80,13 @@ def _get_user_default_print_behaviour(self):
return dict(
action=user.printing_action or "client",
printer=printer or printer_obj.get_default(),
tray=(
str(user.printer_tray_id.system_name) if user.printer_tray_id else False
input_tray=str(user.printer_input_tray_id.system_name)
if user.printer_input_tray_id
else False,
output_tray=(
str(user.printer_output_tray_id.system_name)
if user.printer_output_tray_id
else False
),
)

Expand All @@ -86,8 +97,10 @@ def _get_report_default_print_behaviour(self):
result["action"] = report_action.action_type
if self.printing_printer_id:
result["printer"] = self.printing_printer_id
if self.printer_tray_id:
result["tray"] = self.printer_tray_id.system_name
if self.printer_input_tray_id:
result["input_tray"] = self.printer_input_tray_id.system_name
if self.printer_output_tray_id:
result["output_tray"] = self.printer_output_tray_id.system_name
return result

def behaviour(self):
Expand Down
72 changes: 42 additions & 30 deletions base_report_to_printer/models/printing_printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,15 @@ class PrintingPrinter(models.Model):
model = fields.Char(readonly=True)
location = fields.Char(readonly=True)
uri = fields.Char(string="URI", readonly=True)
tray_ids = fields.One2many(
comodel_name="printing.tray", inverse_name="printer_id", string="Paper Sources"
input_tray_ids = fields.One2many(
comodel_name="printing.tray.input",
inverse_name="printer_id",
string="Paper Sources",
)
output_tray_ids = fields.One2many(
comodel_name="printing.tray.output",
inverse_name="printer_id",
string="Output trays",
)
multi_thread = fields.Boolean(
compute="_compute_multi_thread", readonly=False, store=True
Expand Down Expand Up @@ -102,42 +109,44 @@ def _prepare_update_from_cups(self, cups_connection, cups_printer):
return vals

ppd = cups.PPD(ppd_path)
option = ppd.findOption("InputSlot")
input_options = ppd.findOption("InputSlot")
output_options = ppd.findOption("OutputBin")
try:
os.unlink(ppd_path)
except OSError as err:
# ENOENT means No such file or directory
# The file has already been deleted, we can continue the update
if err.errno != errno.ENOENT:
raise
if not option:
return vals

tray_commands = []
cups_trays = {
tray_option["choice"]: tray_option["text"] for tray_option in option.choices
}

# Add new trays
tray_commands.extend(
[
(0, 0, {"name": text, "system_name": choice})
for choice, text in cups_trays.items()
if choice not in self.tray_ids.mapped("system_name")
if input_options:
vals["input_tray_ids"] = [
(0, 0, {"name": opt["text"], "system_name": opt["choice"]})
for opt in input_options.choices
if opt["choice"] not in self.input_tray_ids.mapped("system_name")
]
)

# Remove deleted trays
tray_commands.extend(
[
(2, tray.id)
for tray in self.tray_ids.filtered(
lambda record: record.system_name not in cups_trays.keys()
)
trays = [opt["choice"] for opt in input_options.choices]
vals["input_tray_ids"].extend(
[
(2, tray.id)
for tray in self.input_tray_ids
if tray.system_name not in trays
]
)

if output_options:
vals["output_tray_ids"] = [
(0, 0, {"name": opt["text"], "system_name": opt["choice"]})
for opt in output_options.choices
if opt["choice"] not in self.output_tray_ids.mapped("system_name")
]
)
if tray_commands:
vals["tray_ids"] = tray_commands
trays = [opt["choice"] for opt in output_options.choices]
vals["output_tray_ids"].extend(
[
(2, tray.id)
for tray in self.output_tray_ids
if tray.system_name not in trays
]
)
return vals

def print_document(self, report, content, **print_opts):
Expand All @@ -162,11 +171,14 @@ def _set_option_doc_format(report, value):
# Backwards compatibility of builtin used as kwarg
_set_option_format = _set_option_doc_format

def _set_option_tray(self, report, value):
def _set_option_input_tray(self, report, value):
"""Note we use self here as some older PPD use tray
rather than InputSlot so we may need to query printer in override"""
return {"InputSlot": str(value)} if value else {}

def _set_option_output_tray(self, report, value):
return {"OutputBin": str(value)} if value else {}

@staticmethod
def _set_option_noop(report, value):
return {}
Expand Down
15 changes: 11 additions & 4 deletions base_report_to_printer/models/printing_report_xml_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,29 @@ class PrintingReportXmlAction(models.Model):
)
printer_id = fields.Many2one(comodel_name="printing.printer", string="Printer")

printer_tray_id = fields.Many2one(
comodel_name="printing.tray",
printer_input_tray_id = fields.Many2one(
comodel_name="printing.tray.input",
string="Paper Source",
domain="[('printer_id', '=', printer_id)]",
)
printer_output_tray_id = fields.Many2one(
comodel_name="printing.tray.output",
string="Output Bin",
domain="[('printer_id', '=', printer_id)]",
)

@api.onchange("printer_id")
def onchange_printer_id(self):
"""Reset the tray when the printer is changed"""
self.printer_tray_id = False
self.printer_input_tray_id = False
self.printer_output_tray_id = False

def behaviour(self):
if not self:
return {}
return {
"action": self.action,
"printer": self.printer_id,
"tray": self.printer_tray_id.system_name,
"input_tray": self.printer_input_tray_id.system_name,
"output_tray": self.printer_output_tray_id.system_name,
}
Loading
Loading