import openerp.tools as tools
import zipfile
import common
-from openerp.osv.fields import float as float_class, function as function_class
-from openerp.osv.orm import browse_record
+from openerp.osv.fields import float as float_field, function as function_field, datetime as datetime_field
from openerp.tools.translate import _
+from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
-DT_FORMAT = '%Y-%m-%d'
-DHM_FORMAT = '%Y-%m-%d %H:%M:%S'
-HM_FORMAT = '%H:%M:%S'
+_logger = logging.getLogger(__name__)
rml_parents = {
'tr':1,
'para': 'p',
}
-def get_date_length(date_format=DT_FORMAT):
+def get_date_length(date_format=DEFAULT_SERVER_DATE_FORMAT):
return len((datetime.now()).strftime(date_format))
class _format(object):
class _float_format(float, _format):
def __init__(self,value):
super(_float_format, self).__init__()
- self.val = value
+ self.val = value or 0.0
def __str__(self):
digits = 2
digits = self._field.digits[1]
if hasattr(self, 'lang_obj'):
return self.lang_obj.format('%.' + str(digits) + 'f', self.name, True)
- return self.val
+ return str(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)
+ self.val = value or 0
def __str__(self):
if hasattr(self,'lang_obj'):
return self.lang_obj.format('%.d', self.name, True)
- return self.val
+ return str(self.val)
class _date_format(str, _format):
def __init__(self,value):
def __str__(self):
if self.val:
if getattr(self,'name', None):
- date = datetime.strptime(self.name[:get_date_length()], DT_FORMAT)
+ date = datetime.strptime(self.name[:get_date_length()], DEFAULT_SERVER_DATE_FORMAT)
return date.strftime(str(self.lang_obj.date_format))
return self.val
def __str__(self):
if self.val and getattr(self,'name', None):
- return datetime.strptime(self.name, DHM_FORMAT)\
+ return datetime.strptime(self.name, DEFAULT_SERVER_DATETIME_FORMAT)\
.strftime("%s %s"%(str(self.lang_obj.date_format),
str(self.lang_obj.time_format)))
return self.val
'setHtmlImage' : self.set_html_image,
'strip_name' : self._strip_name,
'time' : time,
+ 'display_address': self.display_address,
# more context members are setup in setCompany() below:
# - company_id
# - logo
else:
d = res_digits(self.cr)[1]
elif (hasattr(obj, '_field') and\
- isinstance(obj._field, (float_class, function_class)) and\
+ isinstance(obj._field, (float_field, function_field)) and\
obj._field.digits):
d = obj._field.digits[1] or DEFAULT_DIGITS
return d
- def formatLang(self, value, digits=None, date=False, date_time=False, grouping=True, monetary=False, dp=False):
+ def formatLang(self, value, digits=None, date=False, date_time=False, grouping=True, monetary=False, dp=False, currency_obj=False):
"""
Assuming 'Account' decimal.precision=3:
formatLang(value) -> digits=2 (default)
return ''
date_format = self.lang_dict['date_format']
- parse_format = DT_FORMAT
+ parse_format = DEFAULT_SERVER_DATE_FORMAT
if date_time:
- value=value.split('.')[0]
+ value = value.split('.')[0]
date_format = date_format + " " + self.lang_dict['time_format']
- parse_format = DHM_FORMAT
- if not isinstance(value, time.struct_time):
- return time.strftime(date_format, time.strptime(value[:get_date_length(parse_format)], parse_format))
-
+ parse_format = DEFAULT_SERVER_DATETIME_FORMAT
+ if isinstance(value, basestring):
+ # FIXME: the trimming is probably unreliable if format includes day/month names
+ # and those would need to be translated anyway.
+ date = datetime.strptime(value[:get_date_length(parse_format)], parse_format)
+ elif isinstance(value, time.struct_time):
+ date = datetime(*value[:6])
else:
date = datetime(*value.timetuple()[:6])
+ if date_time:
+ # Convert datetime values to the expected client/context timezone
+ date = datetime_field.context_timestamp(self.cr, self.uid,
+ timestamp=date,
+ context=self.localcontext)
return date.strftime(date_format)
- return self.lang_dict['lang_obj'].format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary)
+ res = self.lang_dict['lang_obj'].format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary)
+ if currency_obj:
+ if currency_obj.position == 'after':
+ res='%s %s'%(res,currency_obj.symbol)
+ elif currency_obj and currency_obj.position == 'before':
+ res='%s %s'%(currency_obj.symbol, res)
+ return res
+
+ def display_address(self, address_browse_record):
+ return self.pool.get('res.partner')._display_address(self.cr, self.uid, address_browse_record)
def repeatIn(self, lst, name,nodes_parent=False):
ret_lst = []
return table_obj.browse(cr, uid, ids, list_class=browse_record_list, context=context, fields_process=_fields_process)
def create(self, cr, uid, ids, data, context=None):
+ if context is None:
+ context = {}
if self.internal_header:
- context.update({'internal_header':self.internal_header})
+ context.update(internal_header=self.internal_header)
+ # skip osv.fields.sanitize_binary_value() because we want the raw bytes in all cases
+ context.update(bin_raw=True)
pool = pooler.get_pool(cr.dbname)
ir_obj = pool.get('ir.actions.report.xml')
report_xml_ids = ir_obj.search(cr, uid,
raise NotImplementedError(_('Unknown report type: %s') % report_type)
fnct_ret = fnct(cr, uid, ids, data, report_xml, context)
if not fnct_ret:
- return (False,False)
+ return False, False
return fnct_ret
def create_source_odt(self, cr, uid, ids, data, report_xml, context=None):
if aname:
try:
name = aname+'.'+result[1]
+ # Remove the default_type entry from the context: this
+ # is for instance used on the account.account_invoices
+ # and is thus not intended for the ir.attachment type
+ # field.
+ ctx = dict(context)
+ ctx.pop('default_type', None)
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
+ }, context=ctx
)
except Exception:
#TODO: should probably raise a proper osv_except instead, shouldn't we? see LP bug #325632
- logging.getLogger('report').error('Could not create saved report attachment', exc_info=True)
+ _logger.error('Could not create saved report attachment', exc_info=True)
results.append(result)
if results:
if results[0][1]=='pdf':
logo = base64.decodestring(rml_parser.logo)
create_doc = self.generators[report_xml.report_type]
pdf = create_doc(etree.tostring(processed_rml),rml_parser.localcontext,logo,title.encode('utf8'))
- return (pdf, report_xml.report_type)
+ return pdf, report_xml.report_type
def create_single_odt(self, cr, uid, ids, data, report_xml, context=None):
if not context:
context = context.copy()
report_type = report_xml.report_type
context['parents'] = sxw_parents
-
- # if binary content was passed as unicode, we must
- # re-encode it as a 8-bit string using the pass-through
- # 'latin1' encoding, to restore the original byte values.
- # See also osv.fields.sanitize_binary_value()
- binary_report_content = report_xml.report_sxw_content.encode("latin1")
+ binary_report_content = report_xml.report_sxw_content
+ if isinstance(report_xml.report_sxw_content, unicode):
+ # if binary content was passed as unicode, we must
+ # re-encode it as a 8-bit string using the pass-through
+ # 'latin1' encoding, to restore the original byte values.
+ # See also osv.fields.sanitize_binary_value()
+ binary_report_content = report_xml.report_sxw_content.encode("latin1")
sxw_io = StringIO.StringIO(binary_report_content)
sxw_z = zipfile.ZipFile(sxw_io, mode='r')
create_doc = self.generators[mime_type]
odt = etree.tostring(create_doc(rml_dom, rml_parser.localcontext),
encoding='utf-8', xml_declaration=True)
- sxw_z = zipfile.ZipFile(sxw_io, mode='a')
- sxw_z.writestr('content.xml', odt)
- sxw_z.writestr('meta.xml', meta)
+ sxw_contents = {'content.xml':odt, 'meta.xml':meta}
if report_xml.header:
#Add corporate header/footer
rml_parser._add_header(odt)
odt = etree.tostring(odt, encoding='utf-8',
xml_declaration=True)
- sxw_z.writestr('styles.xml', odt)
+ sxw_contents['styles.xml'] = odt
finally:
rml_file.close()
- sxw_z.close()
- final_op = sxw_io.getvalue()
+
+ #created empty zip writing sxw contents to avoid duplication
+ sxw_out = StringIO.StringIO()
+ sxw_out_zip = zipfile.ZipFile(sxw_out, mode='w')
+ sxw_template_zip = zipfile.ZipFile (sxw_io, 'r')
+ for item in sxw_template_zip.infolist():
+ if item.filename not in sxw_contents:
+ buffer = sxw_template_zip.read(item.filename)
+ sxw_out_zip.writestr(item.filename, buffer)
+ for item_filename, buffer in sxw_contents.iteritems():
+ sxw_out_zip.writestr(item_filename, buffer)
+ sxw_template_zip.close()
+ sxw_out_zip.close()
+ final_op = sxw_out.getvalue()
sxw_io.close()
- return (final_op, mime_type)
+ sxw_out.close()
+ return final_op, mime_type
def create_single_html2html(self, cr, uid, ids, data, report_xml, context=None):
if not context:
create_doc = self.generators['html2html']
html = etree.tostring(create_doc(html_dom, html_parser.localcontext))
- return (html.replace('&','&').replace('<', '<').replace('>', '>').replace('</br>',''), report_type)
+ return html.replace('&','&').replace('<', '<').replace('>', '>').replace('</br>',''), report_type
def create_single_mako2html(self, cr, uid, ids, data, report_xml, context=None):
mako_html = report_xml.report_rml_content
html_parser.set_context(objs, data, ids, 'html')
create_doc = self.generators['makohtml2html']
html = create_doc(mako_html,html_parser.localcontext)
- return (html,'html')
+ return html,'html'
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: