diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index a542ae6fd1a..7abefe589a2 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -327,7 +327,7 @@ def register_class(m): def log(e): mt = isinstance(e, zipimport.ZipImportError) and 'zip ' or '' - msg = "Couldn't load%s module %s" % (mt, m) + msg = "Couldn't load %smodule %s" % (mt, m) logger.notifyChannel('init', netsvc.LOG_CRITICAL, msg) logger.notifyChannel('init', netsvc.LOG_CRITICAL, e) @@ -336,6 +336,7 @@ def register_class(m): return logger.notifyChannel('init', netsvc.LOG_INFO, 'module %s: registering objects' % m) mod_path = get_module_path(m) + try: zip_mod_path = mod_path + '.zip' if not os.path.isfile(zip_mod_path): diff --git a/bin/addons/base/ir/ir.xml b/bin/addons/base/ir/ir.xml index e598fd9cc54..4cc2774959e 100644 --- a/bin/addons/base/ir/ir.xml +++ b/bin/addons/base/ir/ir.xml @@ -272,6 +272,7 @@ + diff --git a/bin/addons/base/ir/ir_actions.py b/bin/addons/base/ir/ir_actions.py index 55057825b32..02b4fa6da6e 100644 --- a/bin/addons/base/ir/ir_actions.py +++ b/bin/addons/base/ir/ir_actions.py @@ -121,7 +121,8 @@ class report_xml(osv.osv): ('odt', 'odt'), ], string='Type', required=True), 'groups_id': fields.many2many('res.groups', 'res_groups_report_rel', 'uid', 'gid', 'Groups'), - 'attachment': fields.char('Save As Attachment Prefix', size=32, help='This is the prefix of the file name the print will be saved as attachement. Keep empty to not save the printed reports') + 'attachment': fields.char('Save As Attachment Prefix', size=128, help='This is the filename of the attachment to store the printing result. Keep empty to not save the printed reports. You can use python expression using the object and time variables.'), + 'attachment_use': fields.boolean('Reload from Attachment', help='If you check this, the second time the user print with same attachment name, it returns the previour report.') } _defaults = { 'type': lambda *a: 'ir.actions.report.xml', diff --git a/bin/addons/base/res/partner/partner.py b/bin/addons/base/res/partner/partner.py index 3d74c0f6b92..30b12950e4e 100644 --- a/bin/addons/base/res/partner/partner.py +++ b/bin/addons/base/res/partner/partner.py @@ -104,7 +104,7 @@ def _contact_title_get(self, cr, uid, context={}): obj = self.pool.get('res.partner.title') ids = obj.search(cr, uid, [('domain', '=', 'contact')]) res = obj.read(cr, uid, ids, ['shortcut','name'], context) - return [(r['shortcut'], r['name']) for r in res] + return [(r['shortcut'], r['name']) for r in res] + [('','')] def _partner_title_get(self, cr, uid, context={}): obj = self.pool.get('res.partner.title') @@ -116,7 +116,7 @@ def _lang_get(self, cr, uid, context={}): obj = self.pool.get('res.lang') ids = obj.search(cr, uid, [], context=context) res = obj.read(cr, uid, ids, ['code', 'name'], context) - return [(r['code'], r['name']) for r in res] + return [(r['code'], r['name']) for r in res] + [('','')] class res_partner(osv.osv): diff --git a/bin/import_xml.rng b/bin/import_xml.rng index 0b88766f472..3ad2f2feff0 100644 --- a/bin/import_xml.rng +++ b/bin/import_xml.rng @@ -105,6 +105,7 @@ + diff --git a/bin/netsvc.py b/bin/netsvc.py index 745921023e3..e4df96a2b0d 100644 --- a/bin/netsvc.py +++ b/bin/netsvc.py @@ -303,7 +303,7 @@ class HttpDaemon(threading.Thread): Logger().notifyChannel('xml-rpc-ssl', LOG_CRITICAL, "Can not load the certificate and/or the private key files") sys.exit(1) except Exception, e: - Logger().notifyChannel('xml-rpc', LOG_CRITICAL, "Error occur when strarting the server daemon: %s" % (e,)) + Logger().notifyChannel('xml-rpc', LOG_CRITICAL, "Error occur when starting the server daemon: %s" % (e,)) sys.exit(1) diff --git a/bin/report/report_sxw.py b/bin/report/report_sxw.py index 314c41e05cf..45c93458d24 100644 --- a/bin/report/report_sxw.py +++ b/bin/report/report_sxw.py @@ -635,40 +635,66 @@ class report_sxw(report_rml): fields_process=_fields_process) def create(self, cr, uid, ids, data, context=None): - logo = None if not context: context={} - context = context.copy() - pool = pooler.get_pool(cr.dbname) - ir_actions_report_xml_obj = pool.get('ir.actions.report.xml') - report_xml_ids = ir_actions_report_xml_obj.search(cr, uid, + ir_obj = pool.get('ir.actions.report.xml') + report_xml_ids = ir_obj.search(cr, uid, [('report_name', '=', self.name[7:])], context=context) - report_type = 'pdf' - report_xml = None - title='' - attach = False - want_header = self.header - if report_xml_ids: - report_xml = ir_actions_report_xml_obj.browse(cr, uid, report_xml_ids[0], - context=context) - title = report_xml.name - attach = report_xml.attachment - rml = report_xml.report_rml_content - report_type = report_xml.report_type - want_header = report_xml.header - else: - ir_menu_report_obj = pool.get('ir.ui.menu') - report_menu_ids = ir_menu_report_obj.search(cr, uid, - [('id', 'in', ids)], context=context) - if report_menu_ids: - report_name = ir_menu_report_obj.browse(cr, uid, report_menu_ids[0], - context=context) - title = report_name.name - rml = tools.file_open(self.tmpl, subdir=None).read() - report_type= data.get('report_type', report_type) + report_xml = ir_obj.browse(cr, uid, report_xml_ids[0], context=context) - if report_type in ['sxw','odt'] and report_xml: + if report_xml.attachment: + objs = self.getObjects(cr, uid, ids, context) + results = [] + for obj in objs: + aname = eval(report_xml.attachment, {'object':obj, 'time':time}) + result = False + if report_xml.attachment_use and aname and context.get('attachment_use', True): + aids = pool.get('ir.attachment').search(cr, uid, [('datas_fname','=',aname+'.pdf'),('res_model','=',self.table),('res_id','=',obj.id)]) + if aids: + d = base64.decodestring(pool.get('ir.attachment').browse(cr, uid, aids[0]).datas) + results.append((d,'pdf')) + continue + + result = self.create_single(cr, uid, [obj.id], data, report_xml, context) + if aname: + name = aname+'.'+result[1] + pool.get('ir.attachment').create(cr, uid, { + 'name': aname, + 'datas': base64.encodestring(result[0]), + 'datas_fname': name, + 'res_model': self.table, + 'res_id': obj.id, + }, context=context + ) + cr.commit() + results.append(result) + + if results[0][1]=='pdf': + from pyPdf import PdfFileWriter, PdfFileReader + import cStringIO + output = PdfFileWriter() + for r in results: + reader = PdfFileReader(cStringIO.StringIO(r[0])) + for page in range(reader.getNumPages()): + output.addPage(reader.getPage(page)) + s = cStringIO.StringIO() + output.write(s) + return s.getvalue(), results[0][1] + return self.create_single(cr, uid, ids, data, report_xml, context) + + def create_single(self, cr, uid, ids, data, report_xml, context={}): + logo = None + context = context.copy() + pool = pooler.get_pool(cr.dbname) + want_header = self.header + title = report_xml.name + attach = report_xml.attachment + rml = report_xml.report_rml_content + report_type = report_xml.report_type + want_header = report_xml.header + + if report_type in ['sxw','odt']: context['parents'] = sxw_parents sxw_io = StringIO.StringIO(report_xml.report_sxw_content) sxw_z = zipfile.ZipFile(sxw_io, mode='r') @@ -695,8 +721,6 @@ class report_sxw(report_rml): pe.appendChild(cnd) pp.removeChild(de) - - # Add Information : Resource ID and Model rml_dom_meta = xml.dom.minidom.parseString(meta) node = rml_dom_meta.documentElement @@ -749,20 +773,5 @@ class report_sxw(report_rml): create_doc = self.generators[report_type] pdf = create_doc(rml2, logo, title.encode('utf8')) - if attach: - # TODO: save multiple print with symbolic links in attach - pool.get('ir.attachment').create(cr, uid, { - 'name': (title or _('print'))+':'+time.strftime('%Y-%m-%d %H:%M:%S'), - 'datas': base64.encodestring(pdf), - 'datas_fname': attach+time.strftime('%Y-%m-%d')+'.'+report_type, - 'res_model': self.table, - 'res_id': ids[0] - }, context=context - ) - cr.commit() return (pdf, report_type) - - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/bin/tools/convert.py b/bin/tools/convert.py index 7c4ad731b5c..f7f8c596c84 100644 --- a/bin/tools/convert.py +++ b/bin/tools/convert.py @@ -258,7 +258,7 @@ form: module.record_id""" % (xml_id,) for dest,f in (('name','string'),('model','model'),('report_name','name')): res[dest] = rec.getAttribute(f).encode('utf8') assert res[dest], "Attribute %s of report is empty !" % (f,) - for field,dest in (('rml','report_rml'),('xml','report_xml'),('xsl','report_xsl'),('attachment','attachment')): + for field,dest in (('rml','report_rml'),('xml','report_xml'),('xsl','report_xsl'),('attachment','attachment'),('attachment_use','attachment_use')): if rec.hasAttribute(field): res[dest] = rec.getAttribute(field).encode('utf8') if rec.hasAttribute('auto'):