=== modified file 'bin/report/interface.py' --- old/bin/report/interface.py 2009-12-01 11:01:49 +0000 +++ new/bin/report/interface.py 2010-01-16 15:46:00 +0000 @@ -35,6 +35,10 @@ import render import urllib +import time +import base64 +import cStringIO + # # encode a value to a string in utf8 and converts XML entities # @@ -69,6 +73,66 @@ -> HTML using a XSL:RML transformation """ +class _format(object): + def set_value(self, cr, uid, name, object, field, lang_obj): + self.object = object + self._field = field + self.name = name + self.lang_obj = lang_obj + +class _float_format(float, _format): + def __init__(self,value): + super(_float_format, self).__init__() + self.val = value + + def __str__(self): + digits = 2 + if hasattr(self,'_field') and hasattr(self._field, 'digits') and self._field.digits: + digits = self._field.digits[1] + if hasattr(self, 'lang_obj'): + return self.lang_obj.format('%.' + str(digits) + 'f', self.name, True) + return self.val + +class _int_format(int, _format): + def __init__(self,value): + super(_int_format, self).__init__() + self.val = value and str(value) or str(0) + + def __str__(self): + if hasattr(self,'lang_obj'): + return self.lang_obj.format('%.d', self.name, True) + return self.val + +class _date_format(str, _format): + def __init__(self,value): + super(_date_format, self).__init__() + self.val = value and str(value) or '' + + def __str__(self): + if self.val: + if hasattr(self,'name') and (self.name): + date = mx.DateTime.strptime(self.name,DT_FORMAT) + return date.strftime(self.lang_obj.date_format) + return self.val + +class _dttime_format(str, _format): + def __init__(self,value): + super(_dttime_format, self).__init__() + self.val = value and str(value) or '' + + def __str__(self): + if self.val: + if hasattr(self,'name') and self.name: + datetime = mx.DateTime.strptime(self.name,DHM_FORMAT) + return datetime.strftime(self.lang_obj.date_format+ " " + self.lang_obj.time_format) + return self.val +_fields_process = { + 'float': _float_format, + 'date': _date_format, + 'integer': _int_format, + 'datetime' : _dttime_format +} + class report_rml(report_int): def __init__(self, name, table, tmpl, xsl): super(report_rml, self).__init__(name) @@ -85,7 +149,14 @@ 'html2html' : self.create_html2html, } - def create(self, cr, uid, ids, datas, context): + def getObjects(self, cr, uid, ids, context): + table_obj = pooler.get_pool(cr.dbname).get(self.table) + from report_sxw import browse_record_list + return table_obj.browse(cr, uid, ids, list_class=browse_record_list, context=context, fields_process=_fields_process) + + def create(self, cr, uid, ids, datas, context=None): + if not context: + context = {} xml = self.create_xml(cr, uid, ids, datas, context) xml = tools.ustr(xml).encode('utf8') report_type = datas.get('report_type', 'pdf') @@ -95,11 +166,86 @@ 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, [('report_name', '=', self.name[7:])], context=context) - self.title = report_xml_ids and ir_actions_report_xml_obj.browse(cr,uid,report_xml_ids)[0].name or 'OpenERP Report' + if report_xml_ids: + report_xml = ir_actions_report_xml_obj.browse(cr, uid, report_xml_ids[0], context=context) + ir_actions_report_xml_obj_id = ir_actions_report_xml_obj.browse(cr,uid,report_xml_ids)[0] + self.title = report_xml_ids and ir_actions_report_xml_obj_id.name or 'OpenERP Report' create_doc = self.generators[report_type] pdf = create_doc(rml, title=self.title) + if report_type == 'pdf': + fnct = self.create_source_pdf + fnct(cr, uid, ids, datas, report_xml, context) return (pdf, report_type) + def create_source_pdf(self, cr, uid, ids, data, report_xml, context=None): + if not context: + context={} + pool = pooler.get_pool(cr.dbname) + attach = report_xml.attachment + if attach: + objs = self.getObjects(cr, uid, ids, context) + results = [] + for obj in objs: + aname = eval(attach, {'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: + brow_rec = pool.get('ir.attachment').browse(cr, uid, aids[0]) + if not brow_rec.datas: + continue + d = base64.decodestring(brow_rec.datas) + results.append((d,'pdf')) + continue + result = self.create_single_pdf(cr, uid, [obj.id], data, report_xml, context) + try: + 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() + except Exception,e: + import traceback, sys + tb_s = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) + netsvc.Logger().notifyChannel('report', netsvc.LOG_ERROR,str(e)) + results.append(result) + if results: + if results[0][1]=='pdf': + from pyPdf import PdfFileWriter, PdfFileReader + 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_pdf(cr, uid, ids, data, report_xml, context) + + + def create_single_pdf(self, cr, uid, ids, data, report_xml, context=None): + if not context: + context={} + xml = self.create_xml(cr, uid, ids, data, context) + xml = tools.ustr(xml).encode('utf8') + report_type = data.get('report_type', 'pdf') + rml = self.create_rml(cr, xml, uid, context) + 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, [('report_name', '=', self.name[7:])], context=context) + ir_actions_report_xml_obj_id = ir_actions_report_xml_obj.browse(cr,uid,report_xml_ids)[0] + self.title = report_xml_ids and ir_actions_report_xml_obj_id.name or 'OpenERP Report' + create_doc = self.generators[report_type] + pdf = create_doc(rml, title=self.title) + return (pdf, report_xml.report_type) + + def create_xml(self, cr, uid, ids, datas, context=None): if not context: context={}