Merge lp:~camptocamp/report-print-send/7.0-base_report_to_printer_port-imp-yvr-2 into lp:~report-print-send-core-editors/report-print-send/7.0

Proposed by Yannick Vaucher @ Camptocamp
Status: Merged
Merged at revision: 10
Proposed branch: lp:~camptocamp/report-print-send/7.0-base_report_to_printer_port-imp-yvr-2
Merge into: lp:~report-print-send-core-editors/report-print-send/7.0
Prerequisite: lp:~camptocamp/report-print-send/7.0-base_report_to_printer_port-imp-yvr
Diff against target: 563 lines (+306/-186)
7 files modified
base_report_to_printer/AUTHORS.txt (+1/-0)
base_report_to_printer/__init__.py (+6/-1)
base_report_to_printer/ir_report.py (+130/-0)
base_report_to_printer/printing.py (+1/-185)
base_report_to_printer/report_service.py (+72/-0)
base_report_to_printer/report_xml_action.py (+50/-0)
base_report_to_printer/users.py (+46/-0)
To merge this branch: bzr merge lp:~camptocamp/report-print-send/7.0-base_report_to_printer_port-imp-yvr-2
Reviewer Review Type Date Requested Status
Maxime Chambreuil (http://www.savoirfairelinux.com) code review Approve
Omar (Pexego) code review Approve
Guewen Baconnier @ Camptocamp code review Approve
Review via email: mp+188825@code.launchpad.net

Description of the change

Simple split of code which was in a single file

New proposal for conveniance for reviewers

To post a comment you must log in.
Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote :

As it is just a split of a python module, I'll grant it as: ok for the merge.

review: Approve (code review)
Revision history for this message
Omar (Pexego) (omar7r) wrote :

LGTM

review: Approve (code review)
Revision history for this message
Maxime Chambreuil (http://www.savoirfairelinux.com) (max3903) :
review: Approve (code review)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'base_report_to_printer/AUTHORS.txt'
--- base_report_to_printer/AUTHORS.txt 2012-11-22 21:22:52 +0000
+++ base_report_to_printer/AUTHORS.txt 2013-10-02 12:33:29 +0000
@@ -2,3 +2,4 @@
2Albert Cervera i Areny <albert@nan-tic.com>2Albert Cervera i Areny <albert@nan-tic.com>
3Davide Corio <davide.corio@agilebg.com>3Davide Corio <davide.corio@agilebg.com>
4Lorenzo Battistini <lorenzo.battistini@agilebg.com>4Lorenzo Battistini <lorenzo.battistini@agilebg.com>
5Yannick Vaucher <yannick.vaucher@camptocamp.com>
56
=== modified file 'base_report_to_printer/__init__.py'
--- base_report_to_printer/__init__.py 2013-10-02 12:33:29 +0000
+++ base_report_to_printer/__init__.py 2013-10-02 12:33:29 +0000
@@ -1,10 +1,11 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2##############################################################################2##############################################################################
3# 3#
4# Copyright (c) 2007 Ferran Pegueroles <ferran@pegueroles.com>4# Copyright (c) 2007 Ferran Pegueroles <ferran@pegueroles.com>
5# Copyright (c) 2009 Albert Cervera i Areny <albert@nan-tic.com>5# Copyright (c) 2009 Albert Cervera i Areny <albert@nan-tic.com>
6# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)6# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
7# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)7# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
8# Copyright (C) 2013 Camptocamp (<http://www.camptocamp.com>)
8# All Rights Reserved9# All Rights Reserved
9#10#
10# This program is free software: you can redistribute it and/or modify11# This program is free software: you can redistribute it and/or modify
@@ -22,4 +23,8 @@
22#23#
23##############################################################################24##############################################################################
24from . import printing25from . import printing
26from . import report_xml_action
27from . import report_service
28from . import users
29from . import ir_report
25from . import wizard30from . import wizard
2631
=== added file 'base_report_to_printer/ir_report.py'
--- base_report_to_printer/ir_report.py 1970-01-01 00:00:00 +0000
+++ base_report_to_printer/ir_report.py 2013-10-02 12:33:29 +0000
@@ -0,0 +1,130 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Copyright (c) 2007 Ferran Pegueroles <ferran@pegueroles.com>
5# Copyright (c) 2009 Albert Cervera i Areny <albert@nan-tic.com>
6# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
7# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
8# Copyright (C) 2013 Camptocamp (<http://www.camptocamp.com>)
9# All Rights Reserved
10#
11# This program is free software: you can redistribute it and/or modify
12# it under the terms of the GNU Affero General Public License as published
13# by the Free Software Foundation, either version 3 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU Affero General Public License
22# along with this program. If not, see <http://www.gnu.org/licenses/>.
23#
24##############################################################################
25import os
26import base64
27from tempfile import mkstemp
28import logging
29import cups
30
31from openerp.osv import orm, fields
32
33#
34# Reports
35#
36
37class report_xml(orm.Model):
38
39
40 def set_print_options(self, cr, uid, report_id, format, context=None):
41 """
42 Hook to set print options
43 """
44 options = {}
45 if format == 'raw':
46 options['raw'] = True
47 return options
48
49 def print_direct(self, cr, uid, report_id, result, format, printer, context=None):
50 user_obj = self.pool.get('res.users')
51 fd, file_name = mkstemp()
52 try:
53 os.write(fd, base64.decodestring(result))
54 finally:
55 os.close(fd)
56 printer_system_name = ''
57 if printer:
58 if isinstance(printer, (basestring)):
59 printer_system_name = printer
60 else:
61 printer_system_name = printer.system_name
62 connection = cups.Connection()
63
64 options = self.set_print_options(cr, uid, report_id, format, context=context)
65
66 connection.printFile(printer_system_name, file_name, file_name, options=options)
67 logger = logging.getLogger('base_report_to_printer')
68 logger.info("Printing job : '%s'" % file_name)
69 return True
70
71 _inherit = 'ir.actions.report.xml'
72 _columns = {
73 'property_printing_action': fields.property(
74 #'ir.actions.report.xml',
75 'printing.action',
76 type='many2one',
77 relation='printing.action',
78 string='Action',
79 view_load=True,
80 method=True,
81 ),
82 'printing_printer_id': fields.many2one('printing.printer', 'Printer'),
83 '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'),
84 }
85
86 def behaviour(self, cr, uid, ids, context=None):
87 result = {}
88 printer_obj = self.pool.get('printing.printer')
89 printing_act_obj = self.pool.get('printing.report.xml.action')
90 # Set hardcoded default action
91 default_action = 'client'
92 # Retrieve system wide printer
93 default_printer = printer_obj.get_default(cr, uid, context=context)
94 if default_printer:
95 default_printer = printer_obj.browse(cr, uid, default_printer, context=context)
96
97
98 # Retrieve user default values
99 user = self.pool.get('res.users').browse(cr, uid, context)
100 if user.printing_action:
101 default_action = user.printing_action
102 if user.printing_printer_id:
103 default_printer = user.printing_printer_id
104
105 for report in self.browse(cr, uid, ids, context):
106 action = default_action
107 printer = default_printer
108
109 # Retrieve report default values
110 if report.property_printing_action and report.property_printing_action.type != 'user_default':
111 action = report.property_printing_action.type
112 if report.printing_printer_id:
113 printer = report.printing_printer_id
114
115 # Retrieve report-user specific values
116 act_ids = printing_act_obj.search(cr, uid,
117 [('report_id', '=', report.id),
118 ('user_id', '=', uid),
119 ('action', '!=', 'user_default')], context=context)
120 if act_ids:
121 user_action = printing_act_obj.behaviour(cr, uid, act_ids[0], context)
122 action = user_action['action']
123 if user_action['printer']:
124 printer = user_action['printer']
125
126 result[report.id] = {
127 'action': action,
128 'printer': printer,
129 }
130 return result
0131
=== modified file 'base_report_to_printer/printing.py'
--- base_report_to_printer/printing.py 2013-10-02 12:33:29 +0000
+++ base_report_to_printer/printing.py 2013-10-02 12:33:29 +0000
@@ -5,6 +5,7 @@
5# Copyright (c) 2009 Albert Cervera i Areny <albert@nan-tic.com>5# Copyright (c) 2009 Albert Cervera i Areny <albert@nan-tic.com>
6# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)6# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
7# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)7# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
8# Copyright (C) 2013 Camptocamp (<http://www.camptocamp.com>)
8# All Rights Reserved9# All Rights Reserved
9#10#
10# This program is free software: you can redistribute it and/or modify11# This program is free software: you can redistribute it and/or modify
@@ -21,12 +22,8 @@
21# along with this program. If not, see <http://www.gnu.org/licenses/>.22# along with this program. If not, see <http://www.gnu.org/licenses/>.
22#23#
23##############################################################################24##############################################################################
24
25import os
26import time25import time
27import base6426import base64
28from tempfile import mkstemp
29import logging
3027
31import cups28import cups
32from threading import Thread29from threading import Thread
@@ -199,185 +196,4 @@
199 'type': fields.selection(_available_action_types, 'Type', required=True),196 'type': fields.selection(_available_action_types, 'Type', required=True),
200 }197 }
201198
202#
203# Users
204#
205
206class res_users(orm.Model):
207 _name = "res.users"
208 _inherit = "res.users"
209
210 def _user_available_action_types(self, cr, uid, context=None):
211 if context is None:
212 context={}
213 return [x for x in _available_action_types(self, cr, uid, context) if x[0] != 'user_default']
214
215 _columns = {
216 'printing_action': fields.selection(_user_available_action_types, 'Printing Action'),
217 'printing_printer_id': fields.many2one('printing.printer', 'Default Printer'),
218 }
219
220#
221# Reports
222#
223
224class report_xml(orm.Model):
225
226
227 def set_print_options(self, cr, uid, report_id, format, context=None):
228 """
229 Hook to set print options
230 """
231 options = {}
232 if format == 'raw':
233 options['raw'] = True
234 return options
235
236 def print_direct(self, cr, uid, report_id, result, format, printer, context=None):
237 user_obj = self.pool.get('res.users')
238 fd, file_name = mkstemp()
239 try:
240 os.write(fd, base64.decodestring(result))
241 finally:
242 os.close(fd)
243 printer_system_name = ''
244 if printer:
245 if isinstance(printer, (basestring)):
246 printer_system_name = printer
247 else:
248 printer_system_name = printer.system_name
249 connection = cups.Connection()
250
251 options = self.set_print_options(cr, uid, report_id, format, context=context)
252
253 connection.printFile(printer_system_name, file_name, file_name, options=options)
254 logger = logging.getLogger('base_report_to_printer')
255 logger.info("Printing job : '%s'" % file_name)
256 return True
257
258 _inherit = 'ir.actions.report.xml'
259 _columns = {
260 'property_printing_action': fields.property(
261 #'ir.actions.report.xml',
262 'printing.action',
263 type='many2one',
264 relation='printing.action',
265 string='Action',
266 view_load=True,
267 method=True,
268 ),
269 'printing_printer_id': fields.many2one('printing.printer', 'Printer'),
270 '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'),
271 }
272
273 def behaviour(self, cr, uid, ids, context=None):
274 result = {}
275 printer_obj = self.pool.get('printing.printer')
276 printing_act_obj = self.pool.get('printing.report.xml.action')
277 # Set hardcoded default action
278 default_action = 'client'
279 # Retrieve system wide printer
280 default_printer = printer_obj.get_default(cr, uid, context=context)
281 if default_printer:
282 default_printer = printer_obj.browse(cr, uid, default_printer, context=context)
283
284
285 # Retrieve user default values
286 user = self.pool.get('res.users').browse(cr, uid, context)
287 if user.printing_action:
288 default_action = user.printing_action
289 if user.printing_printer_id:
290 default_printer = user.printing_printer_id
291
292 for report in self.browse(cr, uid, ids, context):
293 action = default_action
294 printer = default_printer
295
296 # Retrieve report default values
297 if report.property_printing_action and report.property_printing_action.type != 'user_default':
298 action = report.property_printing_action.type
299 if report.printing_printer_id:
300 printer = report.printing_printer_id
301
302 # Retrieve report-user specific values
303 act_ids = printing_act_obj.search(cr, uid,
304 [('report_id', '=', report.id),
305 ('user_id', '=', uid),
306 ('action', '!=', 'user_default')], context=context)
307 if act_ids:
308 user_action = printing_act_obj.behaviour(cr, uid, act_ids[0], context)
309 action = user_action['action']
310 if user_action['printer']:
311 printer = user_action['printer']
312
313 result[report.id] = {
314 'action': action,
315 'printer': printer,
316 }
317 return result
318
319
320class report_xml_action(orm.Model):
321 _name = 'printing.report.xml.action'
322 _description = 'Report Printing Actions'
323 _columns = {
324 'report_id': fields.many2one('ir.actions.report.xml', 'Report', required=True, ondelete='cascade'),
325 'user_id': fields.many2one('res.users', 'User', required=True, ondelete='cascade'),
326 'action': fields.selection(_available_action_types, 'Action', required=True),
327 'printer_id': fields.many2one('printing.printer', 'Printer'),
328 }
329
330
331 def behaviour(self, cr, uid, act_id, context=None):
332 result = {}
333 if not act_id:
334 return False
335 action = self.browse(cr, uid, act_id, context=context)
336 return {
337 'action': action.action,
338 'printer': action.printer_id,
339 }
340
341class virtual_report_spool(base_calendar.virtual_report_spool):
342
343 def exp_report(self, db, uid, object, ids, datas=None, context=None):
344 res = super(virtual_report_spool, self).exp_report(db, uid, object, ids, datas, context)
345 self._reports[res]['report_name'] = object
346 return res
347
348 def exp_report_get(self, db, uid, report_id):
349
350 cr = pooler.get_db(db).cursor()
351 try:
352 pool = pooler.get_pool(cr.dbname)
353 # First of all load report defaults: name, action and printer
354 report_obj = pool.get('ir.actions.report.xml')
355 report = report_obj.search(cr,uid,[('report_name','=',self._reports[report_id]['report_name'])])
356 if report:
357 report = report_obj.browse(cr,uid,report[0])
358 name = report.name
359 data = report.behaviour()[report.id]
360 action = data['action']
361 printer = data['printer']
362 if action != 'client':
363 if (self._reports and self._reports.get(report_id, False) and self._reports[report_id].get('result', False)
364 and self._reports[report_id].get('format', False)):
365 report_obj.print_direct(cr, uid, report.id, base64.encodestring(self._reports[report_id]['result']),
366 self._reports[report_id]['format'], printer)
367 # XXX "Warning" removed as it breaks the workflow
368 # it would be interesting to have a dialog box to confirm if we really want to print
369 # in this case it must be with a by pass parameter to allow massive impression
370 #raise osv.except_osv(_('Printing...'), _('Document sent to printer %s') % (printer,))
371
372 except:
373 cr.rollback()
374 raise
375 finally:
376 cr.close()
377
378 res = super(virtual_report_spool, self).exp_report_get(db, uid, report_id)
379 return res
380
381virtual_report_spool()
382
383# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:199# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
384200
=== added file 'base_report_to_printer/report_service.py'
--- base_report_to_printer/report_service.py 1970-01-01 00:00:00 +0000
+++ base_report_to_printer/report_service.py 2013-10-02 12:33:29 +0000
@@ -0,0 +1,72 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Copyright (c) 2007 Ferran Pegueroles <ferran@pegueroles.com>
5# Copyright (c) 2009 Albert Cervera i Areny <albert@nan-tic.com>
6# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
7# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
8# Copyright (C) 2013 Camptocamp (<http://www.camptocamp.com>)
9# All Rights Reserved
10#
11# This program is free software: you can redistribute it and/or modify
12# it under the terms of the GNU Affero General Public License as published
13# by the Free Software Foundation, either version 3 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU Affero General Public License
22# along with this program. If not, see <http://www.gnu.org/licenses/>.
23#
24##############################################################################
25import base64
26
27from openerp import pooler
28from openerp.addons.base_calendar import base_calendar
29
30class virtual_report_spool(base_calendar.virtual_report_spool):
31
32 def exp_report(self, db, uid, object, ids, datas=None, context=None):
33 res = super(virtual_report_spool, self).exp_report(db, uid, object, ids, datas, context)
34 self._reports[res]['report_name'] = object
35 return res
36
37 def exp_report_get(self, db, uid, report_id):
38
39 cr = pooler.get_db(db).cursor()
40 try:
41 pool = pooler.get_pool(cr.dbname)
42 # First of all load report defaults: name, action and printer
43 report_obj = pool.get('ir.actions.report.xml')
44 report = report_obj.search(cr,uid,[('report_name','=',self._reports[report_id]['report_name'])])
45 if report:
46 report = report_obj.browse(cr,uid,report[0])
47 name = report.name
48 data = report.behaviour()[report.id]
49 action = data['action']
50 printer = data['printer']
51 if action != 'client':
52 if (self._reports and self._reports.get(report_id, False) and self._reports[report_id].get('result', False)
53 and self._reports[report_id].get('format', False)):
54 report_obj.print_direct(cr, uid, report.id, base64.encodestring(self._reports[report_id]['result']),
55 self._reports[report_id]['format'], printer)
56 # XXX "Warning" removed as it breaks the workflow
57 # it would be interesting to have a dialog box to confirm if we really want to print
58 # in this case it must be with a by pass parameter to allow massive impression
59 #raise osv.except_osv(_('Printing...'), _('Document sent to printer %s') % (printer,))
60
61 except:
62 cr.rollback()
63 raise
64 finally:
65 cr.close()
66
67 res = super(virtual_report_spool, self).exp_report_get(db, uid, report_id)
68 return res
69
70virtual_report_spool()
71
72# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
073
=== added file 'base_report_to_printer/report_xml_action.py'
--- base_report_to_printer/report_xml_action.py 1970-01-01 00:00:00 +0000
+++ base_report_to_printer/report_xml_action.py 2013-10-02 12:33:29 +0000
@@ -0,0 +1,50 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Copyright (c) 2007 Ferran Pegueroles <ferran@pegueroles.com>
5# Copyright (c) 2009 Albert Cervera i Areny <albert@nan-tic.com>
6# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
7# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
8# Copyright (C) 2013 Camptocamp (<http://www.camptocamp.com>)
9# All Rights Reserved
10#
11# This program is free software: you can redistribute it and/or modify
12# it under the terms of the GNU Affero General Public License as published
13# by the Free Software Foundation, either version 3 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU Affero General Public License
22# along with this program. If not, see <http://www.gnu.org/licenses/>.
23#
24##############################################################################
25from openerp.osv import orm, fields
26
27from printing import _available_action_types
28
29class report_xml_action(orm.Model):
30 _name = 'printing.report.xml.action'
31 _description = 'Report Printing Actions'
32 _columns = {
33 'report_id': fields.many2one('ir.actions.report.xml', 'Report', required=True, ondelete='cascade'),
34 'user_id': fields.many2one('res.users', 'User', required=True, ondelete='cascade'),
35 'action': fields.selection(_available_action_types, 'Action', required=True),
36 'printer_id': fields.many2one('printing.printer', 'Printer'),
37 }
38
39
40 def behaviour(self, cr, uid, act_id, context=None):
41 result = {}
42 if not act_id:
43 return False
44 action = self.browse(cr, uid, act_id, context=context)
45 return {
46 'action': action.action,
47 'printer': action.printer_id,
48 }
49
50# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
051
=== added file 'base_report_to_printer/users.py'
--- base_report_to_printer/users.py 1970-01-01 00:00:00 +0000
+++ base_report_to_printer/users.py 2013-10-02 12:33:29 +0000
@@ -0,0 +1,46 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Copyright (c) 2007 Ferran Pegueroles <ferran@pegueroles.com>
5# Copyright (c) 2009 Albert Cervera i Areny <albert@nan-tic.com>
6# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
7# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
8# Copyright (C) 2013 Camptocamp (<http://www.camptocamp.com>)
9# All Rights Reserved
10#
11# This program is free software: you can redistribute it and/or modify
12# it under the terms of the GNU Affero General Public License as published
13# by the Free Software Foundation, either version 3 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU Affero General Public License
22# along with this program. If not, see <http://www.gnu.org/licenses/>.
23#
24##############################################################################
25from openerp.osv import orm, fields
26
27from printing import _available_action_types
28
29#
30# Users
31#
32class res_users(orm.Model):
33 _name = "res.users"
34 _inherit = "res.users"
35
36 def _user_available_action_types(self, cr, uid, context=None):
37 if context is None:
38 context={}
39 return [x for x in _available_action_types(self, cr, uid, context) if x[0] != 'user_default']
40
41 _columns = {
42 'printing_action': fields.selection(_user_available_action_types, 'Printing Action'),
43 'printing_printer_id': fields.many2one('printing.printer', 'Default Printer'),
44 }
45
46# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: