From f26fb5ec4011d734c5416880b8d64fe477ce963c Mon Sep 17 00:00:00 2001 From: Yannick Vaucher Date: Wed, 2 Oct 2013 14:08:48 +0200 Subject: [PATCH] [IMP] base_report_to_printer - split code in multiple files --- base_report_to_printer/AUTHORS.txt | 1 + base_report_to_printer/__init__.py | 7 +- base_report_to_printer/ir_report.py | 130 ++++++++++++++ base_report_to_printer/printing.py | 186 +------------------- base_report_to_printer/report_service.py | 72 ++++++++ base_report_to_printer/report_xml_action.py | 50 ++++++ base_report_to_printer/users.py | 46 +++++ 7 files changed, 306 insertions(+), 186 deletions(-) create mode 100644 base_report_to_printer/ir_report.py create mode 100644 base_report_to_printer/report_service.py create mode 100644 base_report_to_printer/report_xml_action.py create mode 100644 base_report_to_printer/users.py diff --git a/base_report_to_printer/AUTHORS.txt b/base_report_to_printer/AUTHORS.txt index 6cc912b..308efdf 100644 --- a/base_report_to_printer/AUTHORS.txt +++ b/base_report_to_printer/AUTHORS.txt @@ -2,3 +2,4 @@ Ferran Pegueroles Albert Cervera i Areny Davide Corio Lorenzo Battistini +Yannick Vaucher diff --git a/base_report_to_printer/__init__.py b/base_report_to_printer/__init__.py index f97883c..9f6441d 100644 --- a/base_report_to_printer/__init__.py +++ b/base_report_to_printer/__init__.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- ############################################################################## -# +# # Copyright (c) 2007 Ferran Pegueroles # Copyright (c) 2009 Albert Cervera i Areny # Copyright (C) 2011 Agile Business Group sagl () # Copyright (C) 2011 Domsense srl () +# Copyright (C) 2013 Camptocamp () # All Rights Reserved # # This program is free software: you can redistribute it and/or modify @@ -22,4 +23,8 @@ # ############################################################################## from . import printing +from . import report_xml_action +from . import report_service +from . import users +from . import ir_report from . import wizard diff --git a/base_report_to_printer/ir_report.py b/base_report_to_printer/ir_report.py new file mode 100644 index 0000000..4c7dddf --- /dev/null +++ b/base_report_to_printer/ir_report.py @@ -0,0 +1,130 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2007 Ferran Pegueroles +# Copyright (c) 2009 Albert Cervera i Areny +# Copyright (C) 2011 Agile Business Group sagl () +# Copyright (C) 2011 Domsense srl () +# Copyright (C) 2013 Camptocamp () +# All Rights Reserved +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +import os +import base64 +from tempfile import mkstemp +import logging +import cups + +from openerp.osv import orm, fields + +# +# Reports +# + +class report_xml(orm.Model): + + + def set_print_options(self, cr, uid, report_id, format, context=None): + """ + Hook to set print options + """ + options = {} + if format == 'raw': + options['raw'] = True + return options + + def print_direct(self, cr, uid, report_id, result, format, printer, context=None): + user_obj = self.pool.get('res.users') + fd, file_name = mkstemp() + try: + os.write(fd, base64.decodestring(result)) + finally: + os.close(fd) + printer_system_name = '' + if printer: + if isinstance(printer, (basestring)): + printer_system_name = printer + else: + printer_system_name = printer.system_name + connection = cups.Connection() + + options = self.set_print_options(cr, uid, report_id, format, context=context) + + connection.printFile(printer_system_name, file_name, file_name, options=options) + logger = logging.getLogger('base_report_to_printer') + logger.info("Printing job : '%s'" % file_name) + return True + + _inherit = 'ir.actions.report.xml' + _columns = { + 'property_printing_action': fields.property( + #'ir.actions.report.xml', + 'printing.action', + type='many2one', + relation='printing.action', + string='Action', + view_load=True, + method=True, + ), + 'printing_printer_id': fields.many2one('printing.printer', 'Printer'), + 'printing_action_ids': fields.one2many('printing.report.xml.action', 'report_id', 'Actions', help='This field allows configuring action and printer on a per user basis'), + } + + def behaviour(self, cr, uid, ids, context=None): + result = {} + printer_obj = self.pool.get('printing.printer') + printing_act_obj = self.pool.get('printing.report.xml.action') + # Set hardcoded default action + default_action = 'client' + # Retrieve system wide printer + default_printer = printer_obj.get_default(cr, uid, context=context) + if default_printer: + default_printer = printer_obj.browse(cr, uid, default_printer, context=context) + + + # Retrieve user default values + user = self.pool.get('res.users').browse(cr, uid, context) + if user.printing_action: + default_action = user.printing_action + if user.printing_printer_id: + default_printer = user.printing_printer_id + + for report in self.browse(cr, uid, ids, context): + action = default_action + printer = default_printer + + # Retrieve report default values + if report.property_printing_action and report.property_printing_action.type != 'user_default': + action = report.property_printing_action.type + if report.printing_printer_id: + printer = report.printing_printer_id + + # Retrieve report-user specific values + act_ids = printing_act_obj.search(cr, uid, + [('report_id', '=', report.id), + ('user_id', '=', uid), + ('action', '!=', 'user_default')], context=context) + if act_ids: + user_action = printing_act_obj.behaviour(cr, uid, act_ids[0], context) + action = user_action['action'] + if user_action['printer']: + printer = user_action['printer'] + + result[report.id] = { + 'action': action, + 'printer': printer, + } + return result diff --git a/base_report_to_printer/printing.py b/base_report_to_printer/printing.py index e5dbf7a..004fcba 100644 --- a/base_report_to_printer/printing.py +++ b/base_report_to_printer/printing.py @@ -5,6 +5,7 @@ # Copyright (c) 2009 Albert Cervera i Areny # Copyright (C) 2011 Agile Business Group sagl () # Copyright (C) 2011 Domsense srl () +# Copyright (C) 2013 Camptocamp () # All Rights Reserved # # This program is free software: you can redistribute it and/or modify @@ -21,12 +22,8 @@ # along with this program. If not, see . # ############################################################################## - -import os import time import base64 -from tempfile import mkstemp -import logging import cups from threading import Thread @@ -199,185 +196,4 @@ class printing_action(orm.Model): 'type': fields.selection(_available_action_types, 'Type', required=True), } -# -# Users -# - -class res_users(orm.Model): - _name = "res.users" - _inherit = "res.users" - - def _user_available_action_types(self, cr, uid, context=None): - if context is None: - context={} - return [x for x in _available_action_types(self, cr, uid, context) if x[0] != 'user_default'] - - _columns = { - 'printing_action': fields.selection(_user_available_action_types, 'Printing Action'), - 'printing_printer_id': fields.many2one('printing.printer', 'Default Printer'), - } - -# -# Reports -# - -class report_xml(orm.Model): - - - def set_print_options(self, cr, uid, report_id, format, context=None): - """ - Hook to set print options - """ - options = {} - if format == 'raw': - options['raw'] = True - return options - - def print_direct(self, cr, uid, report_id, result, format, printer, context=None): - user_obj = self.pool.get('res.users') - fd, file_name = mkstemp() - try: - os.write(fd, base64.decodestring(result)) - finally: - os.close(fd) - printer_system_name = '' - if printer: - if isinstance(printer, (basestring)): - printer_system_name = printer - else: - printer_system_name = printer.system_name - connection = cups.Connection() - - options = self.set_print_options(cr, uid, report_id, format, context=context) - - connection.printFile(printer_system_name, file_name, file_name, options=options) - logger = logging.getLogger('base_report_to_printer') - logger.info("Printing job : '%s'" % file_name) - return True - - _inherit = 'ir.actions.report.xml' - _columns = { - 'property_printing_action': fields.property( - #'ir.actions.report.xml', - 'printing.action', - type='many2one', - relation='printing.action', - string='Action', - view_load=True, - method=True, - ), - 'printing_printer_id': fields.many2one('printing.printer', 'Printer'), - 'printing_action_ids': fields.one2many('printing.report.xml.action', 'report_id', 'Actions', help='This field allows configuring action and printer on a per user basis'), - } - - def behaviour(self, cr, uid, ids, context=None): - result = {} - printer_obj = self.pool.get('printing.printer') - printing_act_obj = self.pool.get('printing.report.xml.action') - # Set hardcoded default action - default_action = 'client' - # Retrieve system wide printer - default_printer = printer_obj.get_default(cr, uid, context=context) - if default_printer: - default_printer = printer_obj.browse(cr, uid, default_printer, context=context) - - - # Retrieve user default values - user = self.pool.get('res.users').browse(cr, uid, context) - if user.printing_action: - default_action = user.printing_action - if user.printing_printer_id: - default_printer = user.printing_printer_id - - for report in self.browse(cr, uid, ids, context): - action = default_action - printer = default_printer - - # Retrieve report default values - if report.property_printing_action and report.property_printing_action.type != 'user_default': - action = report.property_printing_action.type - if report.printing_printer_id: - printer = report.printing_printer_id - - # Retrieve report-user specific values - act_ids = printing_act_obj.search(cr, uid, - [('report_id', '=', report.id), - ('user_id', '=', uid), - ('action', '!=', 'user_default')], context=context) - if act_ids: - user_action = printing_act_obj.behaviour(cr, uid, act_ids[0], context) - action = user_action['action'] - if user_action['printer']: - printer = user_action['printer'] - - result[report.id] = { - 'action': action, - 'printer': printer, - } - return result - - -class report_xml_action(orm.Model): - _name = 'printing.report.xml.action' - _description = 'Report Printing Actions' - _columns = { - 'report_id': fields.many2one('ir.actions.report.xml', 'Report', required=True, ondelete='cascade'), - 'user_id': fields.many2one('res.users', 'User', required=True, ondelete='cascade'), - 'action': fields.selection(_available_action_types, 'Action', required=True), - 'printer_id': fields.many2one('printing.printer', 'Printer'), - } - - - def behaviour(self, cr, uid, act_id, context=None): - result = {} - if not act_id: - return False - action = self.browse(cr, uid, act_id, context=context) - return { - 'action': action.action, - 'printer': action.printer_id, - } - -class virtual_report_spool(base_calendar.virtual_report_spool): - - def exp_report(self, db, uid, object, ids, datas=None, context=None): - res = super(virtual_report_spool, self).exp_report(db, uid, object, ids, datas, context) - self._reports[res]['report_name'] = object - return res - - def exp_report_get(self, db, uid, report_id): - - cr = pooler.get_db(db).cursor() - try: - pool = pooler.get_pool(cr.dbname) - # First of all load report defaults: name, action and printer - report_obj = pool.get('ir.actions.report.xml') - report = report_obj.search(cr,uid,[('report_name','=',self._reports[report_id]['report_name'])]) - if report: - report = report_obj.browse(cr,uid,report[0]) - name = report.name - data = report.behaviour()[report.id] - action = data['action'] - printer = data['printer'] - if action != 'client': - if (self._reports and self._reports.get(report_id, False) and self._reports[report_id].get('result', False) - and self._reports[report_id].get('format', False)): - report_obj.print_direct(cr, uid, report.id, base64.encodestring(self._reports[report_id]['result']), - self._reports[report_id]['format'], printer) - # XXX "Warning" removed as it breaks the workflow - # it would be interesting to have a dialog box to confirm if we really want to print - # in this case it must be with a by pass parameter to allow massive impression - #raise osv.except_osv(_('Printing...'), _('Document sent to printer %s') % (printer,)) - - except: - cr.rollback() - raise - finally: - cr.close() - - res = super(virtual_report_spool, self).exp_report_get(db, uid, report_id) - return res - -virtual_report_spool() - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/base_report_to_printer/report_service.py b/base_report_to_printer/report_service.py new file mode 100644 index 0000000..6dfa956 --- /dev/null +++ b/base_report_to_printer/report_service.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2007 Ferran Pegueroles +# Copyright (c) 2009 Albert Cervera i Areny +# Copyright (C) 2011 Agile Business Group sagl () +# Copyright (C) 2011 Domsense srl () +# Copyright (C) 2013 Camptocamp () +# All Rights Reserved +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +import base64 + +from openerp import pooler +from openerp.addons.base_calendar import base_calendar + +class virtual_report_spool(base_calendar.virtual_report_spool): + + def exp_report(self, db, uid, object, ids, datas=None, context=None): + res = super(virtual_report_spool, self).exp_report(db, uid, object, ids, datas, context) + self._reports[res]['report_name'] = object + return res + + def exp_report_get(self, db, uid, report_id): + + cr = pooler.get_db(db).cursor() + try: + pool = pooler.get_pool(cr.dbname) + # First of all load report defaults: name, action and printer + report_obj = pool.get('ir.actions.report.xml') + report = report_obj.search(cr,uid,[('report_name','=',self._reports[report_id]['report_name'])]) + if report: + report = report_obj.browse(cr,uid,report[0]) + name = report.name + data = report.behaviour()[report.id] + action = data['action'] + printer = data['printer'] + if action != 'client': + if (self._reports and self._reports.get(report_id, False) and self._reports[report_id].get('result', False) + and self._reports[report_id].get('format', False)): + report_obj.print_direct(cr, uid, report.id, base64.encodestring(self._reports[report_id]['result']), + self._reports[report_id]['format'], printer) + # XXX "Warning" removed as it breaks the workflow + # it would be interesting to have a dialog box to confirm if we really want to print + # in this case it must be with a by pass parameter to allow massive impression + #raise osv.except_osv(_('Printing...'), _('Document sent to printer %s') % (printer,)) + + except: + cr.rollback() + raise + finally: + cr.close() + + res = super(virtual_report_spool, self).exp_report_get(db, uid, report_id) + return res + +virtual_report_spool() + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/base_report_to_printer/report_xml_action.py b/base_report_to_printer/report_xml_action.py new file mode 100644 index 0000000..d1ca02b --- /dev/null +++ b/base_report_to_printer/report_xml_action.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2007 Ferran Pegueroles +# Copyright (c) 2009 Albert Cervera i Areny +# Copyright (C) 2011 Agile Business Group sagl () +# Copyright (C) 2011 Domsense srl () +# Copyright (C) 2013 Camptocamp () +# All Rights Reserved +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from openerp.osv import orm, fields + +from printing import _available_action_types + +class report_xml_action(orm.Model): + _name = 'printing.report.xml.action' + _description = 'Report Printing Actions' + _columns = { + 'report_id': fields.many2one('ir.actions.report.xml', 'Report', required=True, ondelete='cascade'), + 'user_id': fields.many2one('res.users', 'User', required=True, ondelete='cascade'), + 'action': fields.selection(_available_action_types, 'Action', required=True), + 'printer_id': fields.many2one('printing.printer', 'Printer'), + } + + + def behaviour(self, cr, uid, act_id, context=None): + result = {} + if not act_id: + return False + action = self.browse(cr, uid, act_id, context=context) + return { + 'action': action.action, + 'printer': action.printer_id, + } + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/base_report_to_printer/users.py b/base_report_to_printer/users.py new file mode 100644 index 0000000..f277904 --- /dev/null +++ b/base_report_to_printer/users.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2007 Ferran Pegueroles +# Copyright (c) 2009 Albert Cervera i Areny +# Copyright (C) 2011 Agile Business Group sagl () +# Copyright (C) 2011 Domsense srl () +# Copyright (C) 2013 Camptocamp () +# All Rights Reserved +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from openerp.osv import orm, fields + +from printing import _available_action_types + +# +# Users +# +class res_users(orm.Model): + _name = "res.users" + _inherit = "res.users" + + def _user_available_action_types(self, cr, uid, context=None): + if context is None: + context={} + return [x for x in _available_action_types(self, cr, uid, context) if x[0] != 'user_default'] + + _columns = { + 'printing_action': fields.selection(_user_available_action_types, 'Printing Action'), + 'printing_printer_id': fields.many2one('printing.printer', 'Default Printer'), + } + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: