mirror of
https://github.com/OCA/report-print-send.git
synced 2025-02-16 07:11:31 +02:00
[MIG] base_report_to_printer: Upgrade to v9
This commit is contained in:
8
base_report_to_printer/models/__init__.py
Normal file
8
base_report_to_printer/models/__init__.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import ir_actions_report_xml
|
||||
from . import printing_action
|
||||
from . import printing_printer
|
||||
from . import printing_report_xml_action
|
||||
from . import report
|
||||
from . import res_users
|
||||
96
base_report_to_printer/models/ir_actions_report_xml.py
Normal file
96
base_report_to_printer/models/ir_actions_report_xml.py
Normal file
@@ -0,0 +1,96 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2007 Ferran Pegueroles <ferran@pegueroles.com>
|
||||
# Copyright (c) 2009 Albert Cervera i Areny <albert@nan-tic.com>
|
||||
# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
|
||||
# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
|
||||
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields, api
|
||||
|
||||
|
||||
class IrActionsReportXml(models.Model):
|
||||
"""
|
||||
Reports
|
||||
"""
|
||||
|
||||
_inherit = 'ir.actions.report.xml'
|
||||
|
||||
property_printing_action_id = fields.Many2one(
|
||||
comodel_name='printing.action',
|
||||
string='Action',
|
||||
company_dependent=True,
|
||||
)
|
||||
printing_printer_id = fields.Many2one(
|
||||
comodel_name='printing.printer',
|
||||
string='Printer'
|
||||
)
|
||||
printing_action_ids = fields.One2many(
|
||||
comodel_name='printing.report.xml.action',
|
||||
inverse_name='report_id',
|
||||
string='Actions',
|
||||
help='This field allows configuring action and printer on a per '
|
||||
'user basis'
|
||||
)
|
||||
|
||||
@api.model
|
||||
def print_action_for_report_name(self, report_name):
|
||||
""" Returns if the action is a direct print or pdf
|
||||
|
||||
Called from js
|
||||
"""
|
||||
report_obj = self.env['report']
|
||||
report = report_obj._get_report_from_name(report_name)
|
||||
if not report:
|
||||
return {}
|
||||
result = report.behaviour()[report.id]
|
||||
serializable_result = {
|
||||
'action': result['action'],
|
||||
'printer_name': result['printer'].name,
|
||||
}
|
||||
return serializable_result
|
||||
|
||||
@api.multi
|
||||
def behaviour(self):
|
||||
result = {}
|
||||
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
|
||||
|
||||
for report in self:
|
||||
action = default_action
|
||||
printer = default_printer
|
||||
|
||||
# Retrieve report default values
|
||||
report_action = report.property_printing_action_id
|
||||
if report_action and report_action.type != 'user_default':
|
||||
action = report_action.type
|
||||
if report.printing_printer_id:
|
||||
printer = report.printing_printer_id
|
||||
|
||||
# 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[report.id] = {'action': action,
|
||||
'printer': printer,
|
||||
}
|
||||
return result
|
||||
28
base_report_to_printer/models/printing_action.py
Normal file
28
base_report_to_printer/models/printing_action.py
Normal file
@@ -0,0 +1,28 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2007 Ferran Pegueroles <ferran@pegueroles.com>
|
||||
# Copyright (c) 2009 Albert Cervera i Areny <albert@nan-tic.com>
|
||||
# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
|
||||
# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
|
||||
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields, api
|
||||
|
||||
|
||||
@api.model
|
||||
def _available_action_types(self):
|
||||
return [('server', 'Send to Printer'),
|
||||
('client', 'Send to Client'),
|
||||
('user_default', "Use user's defaults"),
|
||||
]
|
||||
|
||||
|
||||
class PrintingAction(models.Model):
|
||||
_name = 'printing.action'
|
||||
_description = 'Print Job Action'
|
||||
|
||||
name = fields.Char(required=True)
|
||||
type = fields.Selection(
|
||||
lambda s: _available_action_types(s),
|
||||
required=True,
|
||||
)
|
||||
168
base_report_to_printer/models/printing_printer.py
Normal file
168
base_report_to_printer/models/printing_printer.py
Normal file
@@ -0,0 +1,168 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2007 Ferran Pegueroles <ferran@pegueroles.com>
|
||||
# Copyright (c) 2009 Albert Cervera i Areny <albert@nan-tic.com>
|
||||
# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
|
||||
# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
|
||||
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
import logging
|
||||
|
||||
import os
|
||||
from tempfile import mkstemp
|
||||
|
||||
from openerp import models, fields, api, _
|
||||
from openerp.exceptions import UserError
|
||||
from openerp.tools.config import config
|
||||
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
try:
|
||||
import cups
|
||||
except ImportError:
|
||||
_logger.debug('Cannot `import cups`.')
|
||||
|
||||
|
||||
CUPS_HOST = config.get('cups_host', 'localhost')
|
||||
CUPS_PORT = int(config.get('cups_port', 631)) # config.get returns a string
|
||||
|
||||
|
||||
class PrintingPrinter(models.Model):
|
||||
"""
|
||||
Printers
|
||||
"""
|
||||
|
||||
_name = 'printing.printer'
|
||||
_description = 'Printer'
|
||||
_order = 'name'
|
||||
|
||||
name = fields.Char(required=True, select=True)
|
||||
system_name = fields.Char(required=True, select=True)
|
||||
default = fields.Boolean(readonly=True)
|
||||
status = fields.Selection([('unavailable', 'Unavailable'),
|
||||
('printing', 'Printing'),
|
||||
('unknown', 'Unknown'),
|
||||
('available', 'Available'),
|
||||
('error', 'Error'),
|
||||
('server-error', 'Server Error')],
|
||||
required=True,
|
||||
readonly=True,
|
||||
default='unknown')
|
||||
status_message = fields.Char(readonly=True)
|
||||
model = fields.Char(readonly=True)
|
||||
location = fields.Char(readonly=True)
|
||||
uri = fields.Char(string='URI', readonly=True)
|
||||
|
||||
@api.model
|
||||
def update_printers_status(self, domain=None):
|
||||
if domain is None:
|
||||
domain = []
|
||||
printer_recs = self.search(domain)
|
||||
try:
|
||||
connection = cups.Connection(CUPS_HOST, CUPS_PORT)
|
||||
printers = connection.getPrinters()
|
||||
except:
|
||||
printer_recs.write({'status': 'server-error'})
|
||||
else:
|
||||
for printer in printer_recs:
|
||||
cups_printer = printers.get(printer.system_name)
|
||||
if cups_printer:
|
||||
printer.update_from_cups(connection, cups_printer)
|
||||
else:
|
||||
# not in cups list
|
||||
printer.status = 'unavailable'
|
||||
return True
|
||||
|
||||
@api.multi
|
||||
def _prepare_update_from_cups(self, cups_connection, cups_printer):
|
||||
mapping = {
|
||||
3: 'available',
|
||||
4: 'printing',
|
||||
5: 'error'
|
||||
}
|
||||
vals = {
|
||||
'model': cups_printer.get('printer-make-and-model', False),
|
||||
'location': cups_printer.get('printer-location', False),
|
||||
'uri': cups_printer.get('device-uri', False),
|
||||
'status': mapping.get(cups_printer['printer-state'], 'unknown'),
|
||||
}
|
||||
return vals
|
||||
|
||||
@api.multi
|
||||
def update_from_cups(self, cups_connection, cups_printer):
|
||||
""" Update a printer from the information returned by cups.
|
||||
|
||||
:param cups_connection: connection to CUPS, may be used when the
|
||||
method is overriden (e.g. in printer_tray)
|
||||
:param cups_printer: dict of information returned by CUPS for the
|
||||
current printer
|
||||
"""
|
||||
self.ensure_one()
|
||||
vals = self._prepare_update_from_cups(cups_connection, cups_printer)
|
||||
if any(self[name] != value for name, value in vals.iteritems()):
|
||||
self.write(vals)
|
||||
|
||||
@api.multi
|
||||
def print_options(self, report, format, 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):
|
||||
""" Print a file
|
||||
|
||||
Format could be pdf, qweb-pdf, raw, ...
|
||||
|
||||
"""
|
||||
self.ensure_one()
|
||||
fd, file_name = mkstemp()
|
||||
try:
|
||||
os.write(fd, content)
|
||||
finally:
|
||||
os.close(fd)
|
||||
|
||||
try:
|
||||
_logger.debug(
|
||||
'Starting to connect to CUPS on %s:%s'
|
||||
% (CUPS_HOST, CUPS_PORT))
|
||||
connection = cups.Connection(CUPS_HOST, CUPS_PORT)
|
||||
_logger.debug('Connection to CUPS successfull')
|
||||
except:
|
||||
raise UserError(
|
||||
_("Failed to connect to the CUPS server on %s:%s. "
|
||||
"Check that the CUPS server is running and that "
|
||||
"you can reach it from the Odoo server.")
|
||||
% (CUPS_HOST, CUPS_PORT))
|
||||
|
||||
options = self.print_options(report, format, copies)
|
||||
|
||||
_logger.debug(
|
||||
'Sending job to CUPS printer %s on %s'
|
||||
% (self.system_name, CUPS_HOST))
|
||||
connection.printFile(self.system_name,
|
||||
file_name,
|
||||
file_name,
|
||||
options=options)
|
||||
_logger.info("Printing job: '%s' on %s" % (file_name, CUPS_HOST))
|
||||
return True
|
||||
|
||||
@api.multi
|
||||
def set_default(self):
|
||||
if not self:
|
||||
return
|
||||
self.ensure_one()
|
||||
default_printers = self.search([('default', '=', True)])
|
||||
default_printers.write({'default': False})
|
||||
self.write({'default': True})
|
||||
return True
|
||||
|
||||
@api.multi
|
||||
def get_default(self):
|
||||
return self.search([('default', '=', True)], limit=1)
|
||||
39
base_report_to_printer/models/printing_report_xml_action.py
Normal file
39
base_report_to_printer/models/printing_report_xml_action.py
Normal file
@@ -0,0 +1,39 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2007 Ferran Pegueroles <ferran@pegueroles.com>
|
||||
# Copyright (c) 2009 Albert Cervera i Areny <albert@nan-tic.com>
|
||||
# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
|
||||
# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
|
||||
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields, api
|
||||
|
||||
from .printing_action import _available_action_types
|
||||
|
||||
|
||||
class PrintingReportXmlAction(models.Model):
|
||||
_name = 'printing.report.xml.action'
|
||||
_description = 'Printing Report Printing Actions'
|
||||
|
||||
report_id = fields.Many2one(comodel_name='ir.actions.report.xml',
|
||||
string='Report',
|
||||
required=True,
|
||||
ondelete='cascade')
|
||||
user_id = fields.Many2one(comodel_name='res.users',
|
||||
string='User',
|
||||
required=True,
|
||||
ondelete='cascade')
|
||||
action = fields.Selection(
|
||||
lambda s: _available_action_types(s),
|
||||
required=True,
|
||||
)
|
||||
printer_id = fields.Many2one(comodel_name='printing.printer',
|
||||
string='Printer')
|
||||
|
||||
@api.multi
|
||||
def behaviour(self):
|
||||
if not self:
|
||||
return {}
|
||||
return {'action': self.action,
|
||||
'printer': self.printer_id,
|
||||
}
|
||||
72
base_report_to_printer/models/report.py
Normal file
72
base_report_to_printer/models/report.py
Normal file
@@ -0,0 +1,72 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2014 Camptocamp SA
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, exceptions, _, api
|
||||
|
||||
|
||||
class Report(models.Model):
|
||||
_inherit = 'report'
|
||||
|
||||
@api.multi
|
||||
def print_document(self, report_name, html=None, data=None):
|
||||
""" Print a document, do not return the document file """
|
||||
res = []
|
||||
context = self.env.context
|
||||
if context is None:
|
||||
context = self.env['res.users'].context_get()
|
||||
local_context = context.copy()
|
||||
local_context['must_skip_send_to_printer'] = True
|
||||
for rec_id in self.with_context(local_context):
|
||||
document = rec_id.get_pdf(report_name, html=html, data=data)
|
||||
report = self._get_report_from_name(report_name)
|
||||
behaviour = report.behaviour()[report.id]
|
||||
printer = behaviour['printer']
|
||||
if not printer:
|
||||
raise exceptions.Warning(
|
||||
_('No printer configured to print this report.')
|
||||
)
|
||||
res.append(
|
||||
printer.print_document(report, document, report.report_type)
|
||||
)
|
||||
return all(res)
|
||||
|
||||
@api.multi
|
||||
def _can_print_report(self, behaviour, printer, document):
|
||||
"""Predicate that decide if report can be sent to printer
|
||||
|
||||
If you want to prevent `get_pdf` to send report you can set
|
||||
the `must_skip_send_to_printer` key to True in the context
|
||||
"""
|
||||
if self.env.context.get('must_skip_send_to_printer'):
|
||||
return False
|
||||
if behaviour['action'] == 'server' and printer and document:
|
||||
return True
|
||||
return False
|
||||
|
||||
@api.v7
|
||||
def get_pdf(self, cr, uid, ids, report_name, html=None,
|
||||
data=None, context=None):
|
||||
""" Generate a PDF and returns it.
|
||||
|
||||
If the action configured on the report is server, it prints the
|
||||
generated document as well.
|
||||
"""
|
||||
document = super(Report, self).get_pdf(cr, uid, ids, report_name,
|
||||
html=html, data=data,
|
||||
context=context)
|
||||
report = self._get_report_from_name(cr, uid, report_name)
|
||||
behaviour = report.behaviour()[report.id]
|
||||
printer = behaviour['printer']
|
||||
can_print_report = self._can_print_report(cr, uid, ids,
|
||||
behaviour, printer, document,
|
||||
context=context)
|
||||
if can_print_report:
|
||||
printer.print_document(report, document, report.report_type)
|
||||
return document
|
||||
|
||||
@api.v8
|
||||
def get_pdf(self, records, report_name, html=None, data=None):
|
||||
return self._model.get_pdf(self._cr, self._uid,
|
||||
records.ids, report_name,
|
||||
html=html, data=data, context=self._context)
|
||||
31
base_report_to_printer/models/res_users.py
Normal file
31
base_report_to_printer/models/res_users.py
Normal file
@@ -0,0 +1,31 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2007 Ferran Pegueroles <ferran@pegueroles.com>
|
||||
# Copyright (c) 2009 Albert Cervera i Areny <albert@nan-tic.com>
|
||||
# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
|
||||
# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
|
||||
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields, api
|
||||
|
||||
from .printing_action import _available_action_types
|
||||
|
||||
|
||||
class ResUsers(models.Model):
|
||||
_inherit = 'res.users'
|
||||
|
||||
printing_action = fields.Selection(
|
||||
lambda s: s._user_available_action_types(),
|
||||
)
|
||||
printing_printer_id = fields.Many2one(comodel_name='printing.printer',
|
||||
string='Default Printer')
|
||||
|
||||
@api.model
|
||||
def _available_action_types(self):
|
||||
return _available_action_types(self)
|
||||
|
||||
@api.model
|
||||
def _user_available_action_types(self):
|
||||
return [(code, string) for code, string
|
||||
in self._available_action_types()
|
||||
if code != 'user_default']
|
||||
Reference in New Issue
Block a user