mirror of
https://github.com/OCA/report-print-send.git
synced 2025-02-16 07:11:31 +02:00
[WIP] Commit before rebase on latest #109 for user and view updates
Migration of printer_tray to v11 and integration with base_report_to_printer
This commit is contained in:
committed by
David Montull
parent
f61b1cc5c6
commit
7b0c679f33
@@ -6,4 +6,5 @@ from . import printing_job
|
||||
from . import printing_printer
|
||||
from . import printing_server
|
||||
from . import printing_report_xml_action
|
||||
from . import printing_tray
|
||||
from . import res_users
|
||||
|
||||
@@ -21,6 +21,11 @@ class IrActionsReport(models.Model):
|
||||
comodel_name='printing.printer',
|
||||
string='Default Printer'
|
||||
)
|
||||
printer_tray_id = fields.Many2one(
|
||||
comodel_name='printing.tray',
|
||||
string='Paper Source',
|
||||
domain="[('printer_id', '=', printing_printer_id)]",
|
||||
)
|
||||
printing_action_ids = fields.One2many(
|
||||
comodel_name='printing.report.xml.action',
|
||||
inverse_name='report_id',
|
||||
@@ -29,6 +34,11 @@ class IrActionsReport(models.Model):
|
||||
'user basis'
|
||||
)
|
||||
|
||||
@api.onchange('printing_printer_id')
|
||||
def onchange_printing_printer_id(self):
|
||||
""" Reset the tray when the printer is changed """
|
||||
self.printer_tray_id = False
|
||||
|
||||
@api.model
|
||||
def print_action_for_report_name(self, report_name):
|
||||
""" Returns if the action is a direct print or pdf
|
||||
@@ -38,7 +48,7 @@ class IrActionsReport(models.Model):
|
||||
report = self._get_report_from_name(report_name)
|
||||
if not report:
|
||||
return {}
|
||||
result = report.behaviour()[report]
|
||||
result = report.behaviour()
|
||||
serializable_result = {
|
||||
'action': result['action'],
|
||||
'printer_name': result['printer'].name,
|
||||
@@ -46,64 +56,66 @@ class IrActionsReport(models.Model):
|
||||
return serializable_result
|
||||
|
||||
@api.multi
|
||||
def behaviour(self):
|
||||
result = {}
|
||||
def _get_user_default_print_behaviour(self):
|
||||
printer_obj = self.env['printing.printer']
|
||||
printing_act_obj = self.env['printing.report.xml.action']
|
||||
# Set hardcoded default action
|
||||
default_action = 'client'
|
||||
# Retrieve system wide printer
|
||||
default_printer = printer_obj.get_default()
|
||||
|
||||
# Retrieve user default values
|
||||
user = self.env.user
|
||||
if user.printing_action:
|
||||
default_action = user.printing_action
|
||||
if user.printing_printer_id:
|
||||
default_printer = user.printing_printer_id
|
||||
return dict(
|
||||
action=user.printing_action or 'client',
|
||||
printer=user.printing_printer_id or printer_obj.get_default(),
|
||||
tray=str(user.printer_tray_id.system_name) if
|
||||
user.printer_tray_id else False
|
||||
)
|
||||
|
||||
for report in self:
|
||||
action = default_action
|
||||
printer = default_printer
|
||||
@api.multi
|
||||
def _get_report_default_print_behaviour(self):
|
||||
result = {}
|
||||
report_action = self.property_printing_action_id
|
||||
if report_action and report_action.action_type != 'user_default':
|
||||
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
|
||||
return result
|
||||
|
||||
# Retrieve report default values
|
||||
report_action = report.property_printing_action_id
|
||||
if report_action and report_action.action_type != 'user_default':
|
||||
action = report_action.action_type
|
||||
if report.printing_printer_id:
|
||||
printer = report.printing_printer_id
|
||||
@api.multi
|
||||
def behaviour(self):
|
||||
self.ensure_one()
|
||||
printing_act_obj = self.env['printing.report.xml.action']
|
||||
|
||||
# Retrieve report-user specific values
|
||||
print_action = printing_act_obj.search([
|
||||
('report_id', '=', report.id),
|
||||
('user_id', '=', self.env.uid),
|
||||
('action', '!=', 'user_default'),
|
||||
], limit=1)
|
||||
if print_action:
|
||||
user_action = print_action.behaviour()
|
||||
action = user_action['action']
|
||||
if user_action['printer']:
|
||||
printer = user_action['printer']
|
||||
result = self._get_user_default_print_behaviour()
|
||||
result.update(self._get_report_default_print_behaviour())
|
||||
|
||||
result[report] = {
|
||||
'action': action,
|
||||
'printer': printer,
|
||||
}
|
||||
# Retrieve report-user specific values
|
||||
print_action = printing_act_obj.search([
|
||||
('report_id', '=', self.id),
|
||||
('user_id', '=', self.env.uid),
|
||||
('action', '!=', 'user_default'),
|
||||
], limit=1)
|
||||
if print_action:
|
||||
# For some reason design takes report defaults over
|
||||
# False action entries so we must allow for that here
|
||||
result.update({k: v for k, v in
|
||||
print_action.behaviour().items() if v})
|
||||
return result
|
||||
|
||||
@api.multi
|
||||
def print_document(self, record_ids, data=None):
|
||||
""" Print a document, do not return the document file """
|
||||
document = self.with_context(
|
||||
document, doc_format = self.with_context(
|
||||
must_skip_send_to_printer=True).render_qweb_pdf(
|
||||
record_ids, data=data)
|
||||
behaviour = self.behaviour()[self]
|
||||
printer = behaviour['printer']
|
||||
behaviour = self.behaviour()
|
||||
printer = behaviour.pop('printer', None)
|
||||
|
||||
if not printer:
|
||||
raise exceptions.Warning(
|
||||
_('No printer configured to print this report.')
|
||||
)
|
||||
return printer.print_document(self, document, self.report_type)
|
||||
# TODO should we use doc_format instead of report_type
|
||||
return printer.print_document(self, document,
|
||||
doc_format=self.report_type,
|
||||
**behaviour)
|
||||
|
||||
@api.multi
|
||||
def _can_print_report(self, behaviour, printer, document):
|
||||
@@ -128,11 +140,12 @@ class IrActionsReport(models.Model):
|
||||
document, doc_format = super(IrActionsReport, self).render_qweb_pdf(
|
||||
docids, data=data)
|
||||
|
||||
behaviour = self.behaviour()[self]
|
||||
printer = behaviour['printer']
|
||||
behaviour = self.behaviour()
|
||||
printer = behaviour.pop('printer', None)
|
||||
can_print_report = self._can_print_report(behaviour, printer, document)
|
||||
|
||||
if can_print_report:
|
||||
printer.print_document(self, document, self.report_type)
|
||||
printer.print_document(self, document, doc_format=self.report_type,
|
||||
**behaviour)
|
||||
|
||||
return document, doc_format
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
# Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
import errno
|
||||
import logging
|
||||
|
||||
import os
|
||||
from tempfile import mkstemp
|
||||
|
||||
@@ -17,6 +17,11 @@ from odoo import models, fields, api
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
import cups
|
||||
except ImportError:
|
||||
_logger.debug('Cannot `import cups`.')
|
||||
|
||||
|
||||
class PrintingPrinter(models.Model):
|
||||
"""
|
||||
@@ -52,6 +57,55 @@ 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')
|
||||
|
||||
@api.multi
|
||||
def _prepare_update_from_cups(self, cups_connection, cups_printer):
|
||||
vals = super(PrintingPrinter, self)._prepare_update_from_cups(
|
||||
cups_connection, cups_printer)
|
||||
|
||||
printer_uri = cups_printer['printer-uri-supported']
|
||||
printer_system_name = printer_uri[printer_uri.rfind('/') + 1:]
|
||||
ppd_info = cups_connection.getPPD3(printer_system_name)
|
||||
ppd_path = ppd_info[2]
|
||||
if not ppd_path:
|
||||
return vals
|
||||
|
||||
ppd = cups.PPD(ppd_path)
|
||||
option = ppd.findOption('InputSlot')
|
||||
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
|
||||
|
||||
vals['tray_ids'] = []
|
||||
cups_trays = {
|
||||
tray_option['choice']: tray_option['text']
|
||||
for tray_option in option.choices
|
||||
}
|
||||
|
||||
# Add new trays
|
||||
vals['tray_ids'].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')
|
||||
])
|
||||
|
||||
# Remove deleted trays
|
||||
vals['tray_ids'].extend([
|
||||
(2, tray.id)
|
||||
for tray in self.tray_ids.filtered(
|
||||
lambda record: record.system_name not in cups_trays.keys())
|
||||
])
|
||||
|
||||
return vals
|
||||
|
||||
@api.multi
|
||||
def _prepare_update_from_cups(self, cups_connection, cups_printer):
|
||||
@@ -72,17 +126,7 @@ class PrintingPrinter(models.Model):
|
||||
return vals
|
||||
|
||||
@api.multi
|
||||
def print_options(self, report=None, format=None, copies=1):
|
||||
""" Hook to set print options """
|
||||
options = {}
|
||||
if format == 'raw':
|
||||
options['raw'] = 'True'
|
||||
if copies > 1:
|
||||
options['copies'] = str(copies)
|
||||
return options
|
||||
|
||||
@api.multi
|
||||
def print_document(self, report, content, format, copies=1):
|
||||
def print_document(self, report, content, **print_opts):
|
||||
""" Print a file
|
||||
|
||||
Format could be pdf, qweb-pdf, raw, ...
|
||||
@@ -96,16 +140,48 @@ class PrintingPrinter(models.Model):
|
||||
os.close(fd)
|
||||
|
||||
return self.print_file(
|
||||
file_name, report=report, copies=copies, format=format)
|
||||
file_name, report=report, **print_opts)
|
||||
|
||||
@staticmethod
|
||||
def _set_option_doc_format(report, value):
|
||||
return {'raw': 'True'} if value == 'raw' else {}
|
||||
|
||||
# Backwards compatibility of builtin used as kwarg
|
||||
_set_option_format = _set_option_doc_format
|
||||
|
||||
@api.multi
|
||||
def print_file(self, file_name, report=None, copies=1, format=None):
|
||||
def _set_option_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 {}
|
||||
|
||||
@staticmethod
|
||||
def _set_option_noop(report, value):
|
||||
return {}
|
||||
|
||||
_set_option_action = _set_option_noop
|
||||
_set_option_printer = _set_option_noop
|
||||
|
||||
@api.multi
|
||||
def print_options(self, report=None, **print_opts):
|
||||
options = {}
|
||||
if not report:
|
||||
return options
|
||||
|
||||
for option, value in print_opts.items():
|
||||
try:
|
||||
options.update(getattr(
|
||||
self, '_set_option_%s' % option)(report, value))
|
||||
except AttributeError:
|
||||
options[option] = str(value)
|
||||
return options
|
||||
|
||||
@api.multi
|
||||
def print_file(self, file_name, report=None, **print_opts):
|
||||
""" Print a file """
|
||||
self.ensure_one()
|
||||
|
||||
connection = self.server_id._open_connection(raise_on_error=True)
|
||||
options = self.print_options(
|
||||
report=report, format=format, copies=copies)
|
||||
options = self.print_options(report=report, **print_opts)
|
||||
|
||||
_logger.debug(
|
||||
'Sending job to CUPS printer %s on %s'
|
||||
|
||||
@@ -28,6 +28,17 @@ class PrintingReportXmlAction(models.Model):
|
||||
printer_id = fields.Many2one(comodel_name='printing.printer',
|
||||
string='Printer')
|
||||
|
||||
printer_tray_id = fields.Many2one(
|
||||
comodel_name='printing.tray',
|
||||
string='Paper Source',
|
||||
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
|
||||
|
||||
@api.multi
|
||||
def behaviour(self):
|
||||
if not self:
|
||||
@@ -35,4 +46,5 @@ class PrintingReportXmlAction(models.Model):
|
||||
return {
|
||||
'action': self.action,
|
||||
'printer': self.printer_id,
|
||||
'tray': self.printer_tray_id.system_name
|
||||
}
|
||||
|
||||
22
base_report_to_printer/models/printing_tray.py
Normal file
22
base_report_to_printer/models/printing_tray.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class PrinterTray(models.Model):
|
||||
_name = 'printing.tray'
|
||||
_description = 'Printer Tray'
|
||||
|
||||
_order = 'name asc'
|
||||
|
||||
name = fields.Char(required=True)
|
||||
system_name = fields.Char(required=True, readonly=True)
|
||||
printer_id = fields.Many2one(
|
||||
comodel_name='printing.printer',
|
||||
string='Printer',
|
||||
required=True,
|
||||
readonly=True,
|
||||
ondelete='cascade',
|
||||
)
|
||||
@@ -37,3 +37,15 @@ class ResUsers(models.Model):
|
||||
'printing_action',
|
||||
'printing_printer_id',
|
||||
])
|
||||
|
||||
printer_tray_id = fields.Many2one(
|
||||
comodel_name='printing.tray',
|
||||
string='Default Printer Paper Source',
|
||||
domain="[('printer_id', '=', printing_printer_id)]",
|
||||
)
|
||||
|
||||
@api.onchange('printing_printer_id')
|
||||
def onchange_printing_printer_id(self):
|
||||
""" Reset the tray when the printer is changed """
|
||||
self.printer_tray_id = False
|
||||
|
||||
|
||||
Reference in New Issue
Block a user