[MIG] openerp.report: convert to the new API

This commit is contained in:
Raphael Collet
2016-08-18 09:32:45 +02:00
parent d85bf78976
commit 16dece86b1
29 changed files with 408 additions and 426 deletions
+8 -11
View File
@@ -1,18 +1,15 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import openerp
from openerp import api
import interface
import print_xml
import print_fnc
import custom
import render
import int_to_text
import report_sxw
import printscreen
from . import custom
from . import int_to_text
from . import interface
from . import print_fnc
from . import print_xml
from . import printscreen
from . import render
from . import report_sxw
def render_report(cr, uid, ids, name, data, context=None):
"""
+54 -71
View File
@@ -1,23 +1,25 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import cStringIO
import os
import time
from lxml import etree
from pychart import area, arrow, axis, bar_plot, canvas, category_coord, \
fill_style, legend, line_plot, line_style, pie_plot, theme
import openerp
import openerp.tools as tools
from openerp.tools.safe_eval import safe_eval
import print_xml
import render
from interface import report_int
import common
from openerp.osv.orm import BaseModel
from pychart import *
import misc
import cStringIO
from lxml import etree
from openerp.tools.translate import _
from openerp.exceptions import UserError
from openerp.models import BaseModel
from openerp.tools.safe_eval import safe_eval
from openerp.tools.translate import _
from . import common
from . import misc
from . import render
from .interface import report_int
class external_pdf(render.render):
def __init__(self, pdf):
@@ -37,6 +39,7 @@ theme.use_color = 1
class report_custom(report_int):
def __init__(self, name):
report_int.__init__(self, name)
#
# PRE:
# fields = [['address','city'],['name'], ['zip']]
@@ -104,26 +107,18 @@ class report_custom(report_int):
result.append(row)
return result
def create(self, cr, uid, ids, datas, context=None):
if not context:
context={}
self.pool = openerp.registry(cr.dbname)
report = self.pool['ir.report.custom'].browse(cr, uid, [datas['report_id']])[0]
env = openerp.api.Environment(cr, uid, context or {})
report = env['ir.report.custom'].browse([datas['report_id']])
datas['model'] = report.model_id.model
if report.menu_id:
ids = self.pool[report.model_id.model].search(cr, uid, [])
ids = env[report.model_id.model].search([]).ids
datas['ids'] = ids
report_id = datas['report_id']
report = self.pool['ir.report.custom'].read(cr, uid, [report_id], context=context)[0]
fields = self.pool['ir.report.custom.fields'].read(cr, uid, report['fields_child0'], context=context)
fields.sort(lambda x,y : x['sequence'] - y['sequence'])
if report['field_parent']:
parent_field = self.pool['ir.model.fields'].read(cr, uid, [report['field_parent'][0]], ['model'])
model_name = self.pool['ir.model'].read(cr, uid, [report['model_id'][0]], ['model'], context=context)[0]['model']
report = report.read()[0]
fields = env['ir.report.custom.fields'].browse(report['fields_child0']).read()
fields.sort(key=lambda x: x['sequence'])
model_name = env['ir.model'].browse(report['model_id'][0]).model
fct = {
'id': lambda x: x,
@@ -139,7 +134,7 @@ class report_custom(report_int):
field_child = f['field_child'+str(i)]
if field_child:
row.append(
self.pool['ir.model.fields'].read(cr, uid, [field_child[0]], ['name'], context=context)[0]['name']
env['ir.model.fields'].browse(field_child[0]).name
)
if f['fc'+str(i)+'_operande']:
fct_name = 'id'
@@ -152,7 +147,7 @@ class report_custom(report_int):
cond.append(None)
new_fields.append(row)
new_cond.append(cond)
objs = self.pool[model_name].browse(cr, uid, ids)
objs = env[model_name].browse(ids)
# Group by
groupby = None
@@ -167,9 +162,9 @@ class report_custom(report_int):
if report['field_parent']:
level = []
def build_tree(obj, level, depth):
res = self._row_get(cr, uid,[obj], new_fields, new_cond)
res = self._row_get(cr, uid, [obj], new_fields, new_cond)
level.append(depth)
new_obj = safe_eval('obj.'+report['field_parent'][1],{'obj': obj})
new_obj = safe_eval('obj.'+report['field_parent'][1], {'obj': obj})
if not isinstance(new_obj, list) :
new_obj = [new_obj]
for o in new_obj:
@@ -180,7 +175,7 @@ class report_custom(report_int):
for obj in objs:
results += build_tree(obj, level, 0)
else:
results = self._row_get(cr, uid,objs, new_fields, new_cond, group_by=groupby)
results = self._row_get(cr, uid, objs, new_fields, new_cond, group_by=groupby)
fct = {
'calc_sum': lambda l: reduce(lambda x,y: float(x)+float(y), filter(None, l), 0),
@@ -214,7 +209,7 @@ class report_custom(report_int):
row.append(fct[str(fields[col]['operation'])](map(lambda x: x[col], res_dic[key])))
new_res.append(row)
results = new_res
if report['type']=='table':
if report['field_parent']:
res = self._create_tree(uid, ids, report, fields, level, results, context)
@@ -225,12 +220,13 @@ class report_custom(report_int):
sort_idx = idx
break
try :
results.sort(lambda x,y : cmp(float(x[sort_idx]),float(y[sort_idx])))
results.sort(key=lambda x: float(x[sort_idx]))
except :
results.sort(lambda x,y : cmp(x[sort_idx],y[sort_idx]))
results.sort(key=lambda x: x[sort_idx])
if report['limitt']:
results = results[:int(report['limitt'])]
res = self._create_table(uid, ids, report, fields, None, results, context)
elif report['type'] in ('pie','bar', 'line'):
results2 = []
prev = False
@@ -254,6 +250,7 @@ class report_custom(report_int):
res = self._create_bars(cr,uid, ids, report, fields, results2, context)
elif report['type']=='line':
res = self._create_lines(cr,uid, ids, report, fields, results2, context)
return self.obj.get(), 'pdf'
def _create_tree(self, uid, ids, report, fields, level, results, context):
@@ -262,7 +259,7 @@ class report_custom(report_int):
pageSize=[pageSize[1],pageSize[0]]
new_doc = etree.Element('report')
config = etree.SubElement(new_doc, 'config')
def _append_node(name, text):
@@ -319,41 +316,34 @@ class report_custom(report_int):
self.obj.render()
return True
def _create_lines(self, cr, uid, ids, report, fields, results, context):
pool = openerp.registry(cr.dbname)
env = openerp.api.Environment(cr, uid, context or {})
pdf_string = cStringIO.StringIO()
can = canvas.init(fname=pdf_string, format='pdf')
can.show(80,380,'/16/H'+report['title'])
ar = area.T(size=(350,350),
#x_coord = category_coord.T(['2005-09-01','2005-10-22'],0),
x_axis = axis.X(label = fields[0]['name'], format="/a-30{}%s"),
y_axis = axis.Y(label = ', '.join(map(lambda x : x['name'], fields[1:]))))
#x_coord = category_coord.T(['2005-09-01','2005-10-22'],0),
x_axis=axis.X(label = fields[0]['name'], format="/a-30{}%s"),
y_axis=axis.Y(label = ', '.join(map(lambda x : x['name'], fields[1:]))))
process_date = {
'D': lambda x: reduce(lambda xx, yy: xx + '-' + yy, x.split('-')[1:3]),
'M': lambda x: x.split('-')[1],
'Y': lambda x: x.split('-')[0]
}
order_date = {
'D': lambda x: time.mktime((2005, int(x.split('-')[0]), int(x.split('-')[1]), 0, 0, 0, 0, 0, 0)),
'M': lambda x: x,
'Y': lambda x: x
}
abscissa = []
idx = 0
date_idx = None
fct = {}
for f in fields:
field_id = (f['field_child3'] and f['field_child3'][0]) or (f['field_child2'] and f['field_child2'][0]) or (f['field_child1'] and f['field_child1'][0]) or (f['field_child0'] and f['field_child0'][0])
if field_id:
type = pool['ir.model.fields'].read(cr, uid, [field_id],['ttype'])
if type[0]['ttype'] == 'date':
ttype = env['ir.model.fields'].browse(field_id).ttype
if ttype == 'date':
date_idx = idx
fct[idx] = process_date[report['frequency']]
else:
@@ -411,7 +401,7 @@ class report_custom(report_int):
ar.add_plot(plot)
abscissa.update(fields_bar[idx])
idx0 += 1
abscissa = map(lambda x : [x, None], abscissa)
ar.x_coord = category_coord.T(abscissa,0)
ar.draw(can)
@@ -422,30 +412,22 @@ class report_custom(report_int):
pdf_string.close()
return True
def _create_bars(self, cr, uid, ids, report, fields, results, context):
pool = openerp.registry(cr.dbname)
env = openerp.api.Environment(cr, uid, context or {})
pdf_string = cStringIO.StringIO()
can = canvas.init(fname=pdf_string, format='pdf')
can.show(80,380,'/16/H'+report['title'])
process_date = {
'D': lambda x: reduce(lambda xx, yy: xx + '-' + yy, x.split('-')[1:3]),
'M': lambda x: x.split('-')[1],
'Y': lambda x: x.split('-')[0]
}
order_date = {
'D': lambda x: time.mktime((2005, int(x.split('-')[0]), int(x.split('-')[1]), 0, 0, 0, 0, 0, 0)),
'M': lambda x: x,
'Y': lambda x: x
}
ar = area.T(size=(350,350),
x_axis = axis.X(label = fields[0]['name'], format="/a-30{}%s"),
y_axis = axis.Y(label = ', '.join(map(lambda x : x['name'], fields[1:]))))
x_axis=axis.X(label = fields[0]['name'], format="/a-30{}%s"),
y_axis=axis.Y(label = ', '.join(map(lambda x : x['name'], fields[1:]))))
idx = 0
date_idx = None
@@ -453,8 +435,8 @@ class report_custom(report_int):
for f in fields:
field_id = (f['field_child3'] and f['field_child3'][0]) or (f['field_child2'] and f['field_child2'][0]) or (f['field_child1'] and f['field_child1'][0]) or (f['field_child0'] and f['field_child0'][0])
if field_id:
type = pool['ir.model.fields'].read(cr, uid, [field_id],['ttype'])
if type[0]['ttype'] == 'date':
ttype = env['ir.model.fields'].browse(field_id).ttype
if ttype == 'date':
date_idx = idx
fct[idx] = process_date[report['frequency']]
else:
@@ -462,7 +444,7 @@ class report_custom(report_int):
else:
fct[idx] = lambda x : x
idx+=1
# plot are usually displayed year by year
# so we do so if the first field is a date
data_by_year = {}
@@ -480,7 +462,7 @@ class report_custom(report_int):
nb_bar = len(data_by_year)*(len(fields)-1)
colors = map(lambda x:fill_style.Plain(bgcolor=x), misc.choice_colors(nb_bar))
abscissa = {}
for line in data_by_year.keys():
fields_bar = []
@@ -508,7 +490,7 @@ class report_custom(report_int):
data_cum.append([k, float(data[k])+float(prev)])
if fields[idx+1]['cumulate']:
prev += data[k]
idx0 = 0
plot = bar_plot.T(label=fields[idx+1]['name']+' '+str(line), data = data_cum, cluster=(idx0*(len(fields)-1)+idx,nb_bar), fill_style=colors[idx0*(len(fields)-1)+idx])
ar.add_plot(plot)
@@ -601,4 +583,5 @@ class report_custom(report_int):
self.obj = render.rml(rml)
self.obj.render()
return True
report_custom('report.custom')
+29 -38
View File
@@ -3,18 +3,15 @@
import os
import re
import urllib
from lxml import etree
import openerp
import openerp.tools as tools
import openerp.modules
import print_xml
import render
import urllib
from openerp import SUPERUSER_ID
from openerp.report.render.rml2pdf import customfonts
from . import print_xml
from . import render
from openerp.modules import get_module_resource
#
# coerce any type to a unicode string (to preserve non-ascii characters)
@@ -24,6 +21,7 @@ def toxml(value):
unicode_value = tools.ustr(value)
return unicode_value.replace('&', '&amp;').replace('<','&lt;').replace('>','&gt;')
class report_int(object):
_reports = {}
@@ -49,6 +47,7 @@ class report_int(object):
def create(self, cr, uid, ids, datas, context=None):
return False
class report_rml(report_int):
"""
Automatically builds a document using the transformation process:
@@ -73,27 +72,24 @@ class report_rml(report_int):
'makohtml2html' :self.create_makohtml2html,
}
def create(self, cr, uid, ids, datas, context):
registry = openerp.registry(cr.dbname)
def create(self, cr, uid, ids, datas, context=None):
env = openerp.api.Environment(cr, uid, context or {})
xml = self.create_xml(cr, uid, ids, datas, context)
xml = tools.ustr(xml).encode('utf8')
report_type = datas.get('report_type', 'pdf')
if report_type == 'raw':
return xml, report_type
registry['res.font'].font_scan(cr, SUPERUSER_ID, lazy=True, context=context)
env['res.font'].sudo().font_scan(lazy=True)
rml = self.create_rml(cr, xml, uid, context)
ir_actions_report_xml_obj = registry['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'
reports = env['ir.actions.report.xml'].search([('report_name', '=', self.name[7:])])
self.title = reports[0].name if reports else 'Odoo Report'
create_doc = self.generators[report_type]
pdf = create_doc(rml, title=self.title)
return pdf, report_type
def create_xml(self, cr, uid, ids, datas, context=None):
if not context:
context={}
doc = print_xml.document(cr, uid, datas, {})
self.bin_datas.update( doc.bin_datas or {})
doc.parse(self.tmpl, ids, self.table, context)
@@ -102,9 +98,6 @@ class report_rml(report_int):
return self.post_process_xml_data(cr, uid, xml, context)
def post_process_xml_data(self, cr, uid, xml, context=None):
if not context:
context={}
# find the position of the 3rd tag
# (skip the <?xml ...?> and the "root" tag)
iter = re.finditer('<[^>]*>', xml)
@@ -113,7 +106,7 @@ class report_rml(report_int):
pos_xml = i.end()
doc = print_xml.document(cr, uid, {}, {})
tmpl_path = openerp.modules.get_module_resource('base', 'report', 'corporate_defaults.xml')
tmpl_path = get_module_resource('base', 'report', 'corporate_defaults.xml')
doc.parse(tmpl_path, [uid], 'res.users', context)
corporate_header = doc.xml_get()
doc.close()
@@ -131,10 +124,8 @@ class report_rml(report_int):
def create_rml(self, cr, xml, uid, context=None):
if self.tmpl=='' and not self.internal_header:
self.internal_header=True
if not context:
context={}
registry = openerp.registry(cr.dbname)
ir_translation_obj = registry['ir.translation']
env = openerp.api.Environment(cr, uid, context or {})
Translation = env['ir.translation']
# In some case we might not use xsl ...
if not self.xsl:
@@ -172,17 +163,17 @@ class report_rml(report_int):
if node.tail:
tail = node.tail.strip().replace('\n',' ')
if text:
translation1 = ir_translation_obj._get_source(cr, uid, self.name2, 'xsl', lang, text)
if translation1:
node.text = node.text.replace(text, translation1)
text1 = Translation._get_source(self.name2, 'xsl', lang, text)
if text1:
node.text = node.text.replace(text, text1)
if tail:
translation2 = ir_translation_obj._get_source(cr, uid, self.name2, 'xsl', lang, tail)
if translation2:
node.tail = node.tail.replace(tail, translation2)
tail1 = Translation._get_source(self.name2, 'xsl', lang, tail)
if tail1:
node.tail = node.tail.replace(tail, tail1)
translate_aux(node, lang, t)
if context.get('lang', False):
translate(stylesheet.iter(), context['lang'])
if env.lang:
translate(stylesheet.iter(), env.lang)
transform = etree.XSLT(stylesheet)
xml = etree.tostring(
@@ -190,7 +181,7 @@ class report_rml(report_int):
return xml
def create_pdf(self, rml, localcontext = None, logo=None, title=None):
def create_pdf(self, rml, localcontext=None, logo=None, title=None):
if not localcontext:
localcontext = {}
localcontext.update({'internal_header':self.internal_header})
@@ -203,7 +194,7 @@ class report_rml(report_int):
obj.render()
return obj.get()
def create_html(self, rml, localcontext = None, logo=None, title=None):
def create_html(self, rml, localcontext=None, logo=None, title=None):
obj = render.rml2html(rml, localcontext, self.bin_datas)
obj.render()
return obj.get()
@@ -213,28 +204,28 @@ class report_rml(report_int):
obj.render()
return obj.get().encode('utf-8')
def create_html2html(self, rml, localcontext = None, logo=None, title=None):
def create_html2html(self, rml, localcontext=None, logo=None, title=None):
obj = render.html2html(rml, localcontext, self.bin_datas)
obj.render()
return obj.get()
def create_raw(self,rml, localcontext = None, logo=None, title=None):
def create_raw(self,rml, localcontext=None, logo=None, title=None):
obj = render.odt2odt(etree.XML(rml),localcontext)
obj.render()
return etree.tostring(obj.get())
def create_sxw(self,rml,localcontext = None):
def create_sxw(self,rml,localcontext=None):
obj = render.odt2odt(rml,localcontext)
obj.render()
return obj.get()
def create_odt(self,rml,localcontext = None):
def create_odt(self,rml,localcontext=None):
obj = render.odt2odt(rml,localcontext)
obj.render()
return obj.get()
def create_makohtml2html(self,html,localcontext = None):
def create_makohtml2html(self,html,localcontext=None):
obj = render.makohtml2html(html,localcontext)
obj.render()
return obj.get()
+1 -1
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from pychart import *
from pychart import color
colorline = [color.T(r=((r+3) % 11)/10.0,
g=((g+6) % 11)/10.0,
+4 -1
View File
@@ -1,13 +1,16 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from lxml import etree
import re
from lxml import etree
rml_parents = ['tr','story','section']
html_parents = ['tr','body','div']
sxw_parents = ['{http://openoffice.org/2000/table}table-row','{http://openoffice.org/2000/office}body','{http://openoffice.org/2000/text}section']
odt_parents = ['{urn:oasis:names:tc:opendocument:xmlns:office:1.0}body','{urn:oasis:names:tc:opendocument:xmlns:table:1.0}table-row','{urn:oasis:names:tc:opendocument:xmlns:text:1.0}section']
class report(object):
def preprocess_rml(self, root_node,type='pdf'):
_regex1 = re.compile("\[\[(.*?)(repeatIn\(.*?\s*,\s*[\'\"].*?[\'\"]\s*(?:,\s*(.*?)\s*)?\s*\))(.*?)\]\]")
+137 -138
View File
@@ -2,15 +2,16 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from lxml import etree
import openerp
import openerp.tools as tools
from . import print_fnc
from openerp.models import BaseModel
from openerp.tools.safe_eval import safe_eval
import print_fnc
from openerp.osv.orm import BaseModel
class InheritDict(dict):
# Might be usefull when we're doing name lookup for call or eval.
# Might be useful when we're doing name lookup for call or eval.
def __init__(self, parent=None):
self.parent = parent
@@ -23,6 +24,7 @@ class InheritDict(dict):
else:
return self.parent[name]
def tounicode(val):
if isinstance(val, str):
unicode_val = unicode(val, 'utf-8')
@@ -32,14 +34,14 @@ def tounicode(val):
unicode_val = unicode(val)
return unicode_val
class document(object):
def __init__(self, cr, uid, datas, func=False):
# create a new document
self.cr = cr
self.pool = openerp.registry(cr.dbname)
self.func = func or {}
self.datas = datas
self.uid = uid
self.datas = datas
self.func = func or {}
self.bin_datas = {}
def node_attrs_get(self, node):
@@ -86,162 +88,159 @@ class document(object):
return safe_eval(expr, {}, {'obj': record})
def parse_node(self, node, parent, browser, datas=None):
attrs = self.node_attrs_get(node)
if 'type' in attrs:
if attrs['type']=='field':
value = self.get_value(browser, attrs['name'])
#TODO: test this
if value == '' and 'default' in attrs:
value = attrs['default']
env = openerp.api.Environment(self.cr, self.uid, {})
attrs = self.node_attrs_get(node)
if 'type' in attrs:
if attrs['type']=='field':
value = self.get_value(browser, attrs['name'])
#TODO: test this
if value == '' and 'default' in attrs:
value = attrs['default']
el = etree.SubElement(parent, node.tag)
el.text = tounicode(value)
#TODO: test this
for key, value in attrs.iteritems():
if key not in ('type', 'name', 'default'):
el.set(key, value)
elif attrs['type']=='attachment':
model = browser._name
value = self.get_value(browser, attrs['name'])
atts = env['ir.attachment'].search([('res_model','=',model),('res_id','=',int(value))])
datas = atts.read()
if len(datas):
# if there are several, pick first
datas = datas[0]
fname = str(datas['datas_fname'])
ext = fname.split('.')[-1].lower()
if ext in ('jpg','jpeg', 'png'):
import base64
from StringIO import StringIO
dt = base64.decodestring(datas['datas'])
fp = StringIO()
fp.write(dt)
i = str(len(self.bin_datas))
self.bin_datas[i] = fp
el = etree.SubElement(parent, node.tag)
el.text = i
elif attrs['type']=='data':
#TODO: test this
txt = self.datas.get('form', {}).get(attrs['name'], '')
el = etree.SubElement(parent, node.tag)
el.text = txt
elif attrs['type']=='function':
if attrs['name'] in self.func:
txt = self.func[attrs['name']](node)
else:
txt = print_fnc.print_fnc(attrs['name'], node)
el = etree.SubElement(parent, node.tag)
el.text = txt
elif attrs['type']=='eval':
value = self.eval(browser, attrs['expr'])
el = etree.SubElement(parent, node.tag)
el.text = str(value)
elif attrs['type']=='fields':
fields = attrs['name'].split(',')
vals = {}
for b in browser:
value = tuple([self.get_value2(b, f) for f in fields])
if not value in vals:
vals[value]=[]
vals[value].append(b)
keys = vals.keys()
keys.sort()
if 'order' in attrs and attrs['order']=='desc':
keys.reverse()
v_list = [vals[k] for k in keys]
for v in v_list:
el = etree.SubElement(parent, node.tag)
el.text = tounicode(value)
#TODO: test this
for key, value in attrs.iteritems():
if key not in ('type', 'name', 'default'):
el.set(key, value)
for el_cld in node:
self.parse_node(el_cld, el, v)
elif attrs['type']=='attachment':
model = browser._name
value = self.get_value(browser, attrs['name'])
elif attrs['type']=='call':
if len(attrs['args']):
#TODO: test this
# fetches the values of the variables which names where passed in the args attribute
args = [self.eval(browser, arg) for arg in attrs['args'].split(',')]
else:
args = []
# get the object
if 'model' in attrs:
obj = env[attrs['model']]
else:
obj = browser # the record(set) is an instance of the model
ids = self.pool['ir.attachment'].search(self.cr, self.uid, [('res_model','=',model),('res_id','=',int(value))])
datas = self.pool['ir.attachment'].read(self.cr, self.uid, ids)
# get the ids
if 'ids' in attrs:
ids = self.eval(browser, attrs['ids'])
else:
ids = browser.ids
if len(datas):
# if there are several, pick first
datas = datas[0]
fname = str(datas['datas_fname'])
ext = fname.split('.')[-1].lower()
if ext in ('jpg','jpeg', 'png'):
import base64
from StringIO import StringIO
dt = base64.decodestring(datas['datas'])
fp = StringIO()
fp.write(dt)
i = str(len(self.bin_datas))
self.bin_datas[i] = fp
el = etree.SubElement(parent, node.tag)
el.text = i
# call the method itself
newdatas = getattr(obj, attrs['name'])(*args)
elif attrs['type']=='data':
#TODO: test this
txt = self.datas.get('form', {}).get(attrs['name'], '')
el = etree.SubElement(parent, node.tag)
el.text = txt
def parse_result_tree(node, parent, datas):
if not node.tag == etree.Comment:
el = etree.SubElement(parent, node.tag)
atr = self.node_attrs_get(node)
if 'value' in atr:
if not isinstance(datas[atr['value']], (str, unicode)):
txt = str(datas[atr['value']])
else:
txt = datas[atr['value']]
el.text = txt
else:
for el_cld in node:
parse_result_tree(el_cld, el, datas)
if not isinstance(newdatas, (BaseModel, list)):
newdatas = [newdatas]
for newdata in newdatas:
parse_result_tree(node, parent, newdata)
elif attrs['type']=='function':
if attrs['name'] in self.func:
txt = self.func[attrs['name']](node)
elif attrs['type']=='zoom':
value = self.get_value(browser, attrs['name'])
if value:
if not isinstance(value, (BaseModel, list)):
v_list = [value]
else:
txt = print_fnc.print_fnc(attrs['name'], node)
el = etree.SubElement(parent, node.tag)
el.text = txt
elif attrs['type']=='eval':
value = self.eval(browser, attrs['expr'])
el = etree.SubElement(parent, node.tag)
el.text = str(value)
elif attrs['type']=='fields':
fields = attrs['name'].split(',')
vals = {}
for b in browser:
value = tuple([self.get_value2(b, f) for f in fields])
if not value in vals:
vals[value]=[]
vals[value].append(b)
keys = vals.keys()
keys.sort()
if 'order' in attrs and attrs['order']=='desc':
keys.reverse()
v_list = [vals[k] for k in keys]
v_list = value
for v in v_list:
el = etree.SubElement(parent, node.tag)
for el_cld in node:
self.parse_node(el_cld, el, v)
else:
# if there is no "type" attribute in the node, copy it to the xml data and parse its children
if not node.tag == etree.Comment:
if node.tag == parent.tag:
el = parent
else:
el = etree.SubElement(parent, node.tag)
for el_cld in node:
self.parse_node(el_cld,el, browser)
elif attrs['type']=='call':
if len(attrs['args']):
#TODO: test this
# fetches the values of the variables which names where passed in the args attribute
args = [self.eval(browser, arg) for arg in attrs['args'].split(',')]
else:
args = []
# get the object
if 'model' in attrs:
obj = self.pool[attrs['model']]
else:
obj = browser # the record(set) is an instance of the model
# get the ids
if 'ids' in attrs:
ids = self.eval(browser, attrs['ids'])
else:
ids = browse.ids
# call the method itself
newdatas = getattr(obj, attrs['name'])(self.cr, self.uid, ids, *args)
def parse_result_tree(node, parent, datas):
if not node.tag == etree.Comment:
el = etree.SubElement(parent, node.tag)
atr = self.node_attrs_get(node)
if 'value' in atr:
if not isinstance(datas[atr['value']], (str, unicode)):
txt = str(datas[atr['value']])
else:
txt = datas[atr['value']]
el.text = txt
else:
for el_cld in node:
parse_result_tree(el_cld, el, datas)
if not isinstance(newdatas, (BaseModel, list)):
newdatas = [newdatas]
for newdata in newdatas:
parse_result_tree(node, parent, newdata)
elif attrs['type']=='zoom':
value = self.get_value(browser, attrs['name'])
if value:
if not isinstance(value, (BaseModel, list)):
v_list = [value]
else:
v_list = value
for v in v_list:
el = etree.SubElement(parent, node.tag)
for el_cld in node:
self.parse_node(el_cld, el, v)
else:
# if there is no "type" attribute in the node, copy it to the xml data and parse its children
if not node.tag == etree.Comment:
if node.tag == parent.tag:
el = parent
else:
el = etree.SubElement(parent, node.tag)
for el_cld in node:
self.parse_node(el_cld,el, browser)
def xml_get(self):
return etree.tostring(self.doc,encoding="utf-8",xml_declaration=True,pretty_print=True)
def parse_tree(self, ids, model, context=None):
if not context:
context={}
browser = self.pool[model].browse(self.cr, self.uid, ids, context)
env = openerp.api.Environment(self.cr, self.uid, context or {})
browser = env[model].browse(ids)
self.parse_node(self.dom, self.doc, browser)
def parse_string(self, xml, ids, model, context=None):
if not context:
context={}
# parses the xml template to memory
self.dom = etree.XML(xml)
# create the xml data from the xml template
self.parse_tree(ids, model, context)
def parse(self, filename, ids, model, context=None):
if not context:
context={}
# parses the xml template to memory
src_file = tools.file_open(filename)
try:
+2 -2
View File
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import ps_list
import ps_form
from . import ps_list
from . import ps_form
""" A special report, that is automatically formatted to look like the
+13 -15
View File
@@ -1,20 +1,18 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import openerp
from openerp.report.interface import report_int
import openerp.tools as tools
import os
import time
from openerp.report import render
from lxml import etree
import time, os
import openerp
import openerp.tools as tools
from openerp.report import render
from openerp.report.interface import report_int
class report_printscreen_list(report_int):
def __init__(self, name):
report_int.__init__(self, name)
def _parse_node(self, root_node):
result = []
for node in root_node:
@@ -36,19 +34,18 @@ class report_printscreen_list(report_int):
def create(self, cr, uid, ids, datas, context=None):
if not context:
context={}
env = openerp.api.Environment(cr, uid, context)
datas['ids'] = ids
registry = openerp.registry(cr.dbname)
model = registry[datas['model']]
records = env[datas['model']].browse(ids)
# title come from description of model which are specified in py file.
self.title = model._description
result = model.fields_view_get(cr, uid, view_type='form', context=context)
self.title = records._description
result = records.fields_view_get(view_type='form')
fields_order = self._parse_string(result['arch'])
rows = model.read(cr, uid, datas['ids'], result['fields'].keys() )
self._create_table(uid, datas['ids'], result['fields'], fields_order, rows, context, model._description)
rows = records.read(list(result['fields']))
self._create_table(uid, datas['ids'], result['fields'], fields_order, rows, context, records._description)
return self.obj.get(), 'pdf'
def _create_table(self, uid, ids, fields, fields_order, results, context, title=''):
pageSize=[297.0,210.0]
@@ -113,4 +110,5 @@ class report_printscreen_list(report_int):
self.obj = render.rml(rml, self.title)
self.obj.render()
return True
report_printscreen_list('report.printscreen.form')
+31 -33
View File
@@ -1,25 +1,26 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import openerp
from openerp.report.interface import report_int
import openerp.tools as tools
from openerp.tools.safe_eval import safe_eval
from lxml import etree
from openerp.report import render, report_sxw
import locale
import time, os
from operator import itemgetter
import os
import time
from datetime import datetime
from lxml import etree
import openerp
import openerp.tools as tools
from openerp.report import render, report_sxw
from openerp.report.interface import report_int
from openerp.tools.safe_eval import safe_eval
class report_printscreen_list(report_int):
def __init__(self, name):
report_int.__init__(self, name)
super(report_printscreen_list, self).__init__(name)
self.context = {}
self.groupby = []
self.cr=''
self.cr = ''
def _parse_node(self, root_node):
result = []
@@ -43,25 +44,23 @@ class report_printscreen_list(report_int):
def create(self, cr, uid, ids, datas, context=None):
if not context:
context={}
self.cr=cr
context = {}
self.cr = cr
self.context = context
self.groupby = context.get('group_by',[])
self.groupby_no_leaf = context.get('group_by_no_leaf',False)
registry = openerp.registry(cr.dbname)
model = registry[datas['model']]
model_id = registry['ir.model'].search(cr, uid, [('model','=',model._name)])
model_desc = model._description
if model_id:
model_desc = registry['ir.model'].browse(cr, uid, model_id[0], context).name
self.groupby_no_leaf = context.get('group_by_no_leaf', False)
env = openerp.api.Environment(cr, uid, context)
Model = env[datas['model']]
model = env['ir.model'].search([('model', '=', Model._name)])
model_desc = model.name or Model._description
self.title = model_desc
datas['ids'] = ids
result = model.fields_view_get(cr, uid, view_type='tree', context=context)
result = Model.fields_view_get(view_type='tree')
fields_order = self.groupby + self._parse_string(result['arch'])
if self.groupby:
rows = []
def get_groupby_data(groupby = [], domain = []):
records = model.read_group(cr, uid, domain, fields_order, groupby , 0, None, context)
records = Model.read_group(domain, fields_order, groupby, 0, None)
for rec in records:
rec['__group'] = True
rec['__no_leaf'] = self.groupby_no_leaf
@@ -79,18 +78,17 @@ class report_printscreen_list(report_int):
else:
if self.groupby_no_leaf:
continue
child_ids = model.search(cr, uid, inner_domain)
res = model.read(cr, uid, child_ids, result['fields'].keys(), context)
res.sort(lambda x,y: cmp(ids.index(x['id']), ids.index(y['id'])))
children = Model.search(inner_domain)
res = children.read(list(result['fields']))
res.sort(key=lambda x: ids.index(x['id']))
rows.extend(res)
dom = [('id','in',ids)]
if self.groupby_no_leaf and len(ids) and not ids[0]:
dom = datas.get('_domain',[])
get_groupby_data(self.groupby, dom)
else:
rows = model.read(cr, uid, datas['ids'], result['fields'].keys(), context)
ids2 = map(itemgetter('id'), rows) # getting the ids from read result
if datas['ids'] != ids2: # sorted ids were not taken into consideration for print screen
rows = Model.browse(ids).read(list(result['fields']))
if datas['ids'] != rows.ids: # sorted ids were not taken into consideration for print screen
rows_new = []
for id in datas['ids']:
rows_new += [elem for elem in rows if elem['id'] == id]
@@ -98,7 +96,6 @@ class report_printscreen_list(report_int):
res = self._create_table(uid, datas['ids'], result['fields'], fields_order, rows, context, model_desc)
return self.obj.get(), 'pdf'
def _create_table(self, uid, ids, fields, fields_order, results, context, title=''):
pageSize=[297.0, 210.0]
@@ -116,10 +113,10 @@ class report_printscreen_list(report_int):
_append_node('PageHeight', '%.2f' %(pageSize[1] * 2.8346,))
_append_node('report-header', title)
registry = openerp.registry(self.cr.dbname)
_append_node('company', registry['res.users'].browse(self.cr,uid,uid).company_id.name)
rpt_obj = registry['res.users']
rml_obj=report_sxw.rml_parse(self.cr, uid, rpt_obj._name,context)
env = openerp.api.Environment(self.cr, uid, {})
Users = env['res.users']
_append_node('company', Users.browse(uid).company_id.name)
rml_obj = report_sxw.rml_parse(self.cr, uid, Users._name, context)
_append_node('header-date', str(rml_obj.formatLang(time.strftime("%Y-%m-%d"),date=True))+' ' + str(time.strftime("%H:%M")))
l = []
t = 0
@@ -249,4 +246,5 @@ class report_printscreen_list(report_int):
self.obj = render.rml(rml, title=self.title)
self.obj.render()
return True
report_printscreen_list('report.printscreen.list')
+3 -4
View File
@@ -1,10 +1,9 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from simple import simple
from rml import rml, rml2html, rml2txt, odt2odt , html2html, makohtml2html
from render import render
from .simple import simple
from .rml import rml, rml2html, rml2txt, odt2odt , html2html, makohtml2html
from .render import render
try:
from PIL import Image
+1 -1
View File
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from html2html import parseString
from .html2html import parseString
+4 -2
View File
@@ -1,13 +1,15 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from openerp.report.render.rml2pdf import utils
import copy
import base64
import copy
import cStringIO
import re
from reportlab.lib.utils import ImageReader
from openerp.report.render.rml2pdf import utils
_regex = re.compile('\[\[(.+?)\]\]')
utils._regex = re.compile('\[\[\s*(.+?)\s*\]\]',re.DOTALL)
class html2html(object):
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from makohtml2html import parseNode
from .makohtml2html import parseNode
@@ -1,12 +1,14 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
import mako
from lxml import etree
from mako.template import Template
from mako.lookup import TemplateLookup
import os
import mako
from mako.lookup import TemplateLookup
from mako.template import Template
from lxml import etree
_logger = logging.getLogger(__name__)
class makohtml2html(object):
+1 -1
View File
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odt2odt import parseNode
from .odt2odt import parseNode
+2 -1
View File
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from openerp.report.render.rml2pdf import utils
import copy
from openerp.report.render.rml2pdf import utils
class odt2odt(object):
def __init__(self, odt, localcontext):
self.localcontext = localcontext
+12 -8
View File
@@ -1,13 +1,13 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import render
import rml2pdf
import rml2html as htmlizer
import rml2txt as txtizer
import odt2odt as odt
import html2html as html
import makohtml2html as makohtml
from . import render
from . import rml2pdf
from . import rml2html as htmlizer
from . import rml2txt as txtizer
from . import odt2odt as odt
from . import html2html as html
from . import makohtml2html as makohtml
class rml(render.render):
@@ -18,10 +18,10 @@ class rml(render.render):
self.output_type = 'pdf'
self.title=title
def _render(self):
return rml2pdf.parseNode(self.rml, self.localcontext, images=self.bin_datas, path=self.path,title=self.title)
class rml2html(render.render):
def __init__(self, rml,localcontext = None, datas=None):
super(rml2html, self).__init__(datas)
@@ -32,6 +32,7 @@ class rml2html(render.render):
def _render(self):
return htmlizer.parseString(self.rml,self.localcontext)
class rml2txt(render.render):
def __init__(self, rml, localcontext= None, datas=None):
super(rml2txt, self).__init__(datas)
@@ -42,6 +43,7 @@ class rml2txt(render.render):
def _render(self):
return txtizer.parseString(self.rml, self.localcontext)
class odt2odt(render.render):
def __init__(self, rml, localcontext=None, datas=None):
render.render.__init__(self, datas)
@@ -52,6 +54,7 @@ class odt2odt(render.render):
def _render(self):
return odt.parseNode(self.rml_dom,self.localcontext)
class html2html(render.render):
def __init__(self, rml, localcontext=None, datas=None):
render.render.__init__(self, datas)
@@ -62,6 +65,7 @@ class html2html(render.render):
def _render(self):
return html.parseString(self.rml_dom,self.localcontext)
class makohtml2html(render.render):
def __init__(self, html, localcontext = None):
render.render.__init__(self)
+1 -1
View File
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from rml2html import parseString
from .rml2html import parseString
+4 -3
View File
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import sys
import cStringIO
from lxml import etree
import copy
import cStringIO
import sys
from lxml import etree
from openerp.report.render.rml2pdf import utils
+1 -1
View File
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from trml2pdf import parseString, parseNode
from .trml2pdf import parseString, parseNode
+2 -1
View File
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from reportlab.lib import colors
import re
from reportlab.lib import colors
allcols = colors.getAllNamedColors()
regex_t = re.compile('\(([0-9\.]*),([0-9\.]*),([0-9\.]*)\)')
+3 -2
View File
@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from reportlab import rl_config
import logging
import glob
import logging
import os
from reportlab import rl_config
# .apidoc title: TTF Font Table
"""This module allows the mapping of some system-available TTF fonts to
+20 -21
View File
@@ -1,27 +1,14 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import sys
import copy
import reportlab
import re
from reportlab.pdfgen import canvas
from reportlab import platypus
import utils
import color
import os
import logging
import traceback
from lxml import etree
import base64
import copy
import logging
import os
import re
import sys
import traceback
from distutils.version import LooseVersion
from reportlab.platypus.doctemplate import ActionFlowable
from openerp.tools.safe_eval import safe_eval
from reportlab.lib.units import inch,cm,mm
from openerp.tools.misc import file_open
from reportlab.pdfbase import pdfmetrics
from reportlab.lib.pagesizes import A4, letter
try:
from cStringIO import StringIO
@@ -29,8 +16,21 @@ try:
except ImportError:
from StringIO import StringIO
import reportlab
from reportlab import platypus
from reportlab.lib.pagesizes import A4, letter
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfgen import canvas
from reportlab.platypus.doctemplate import ActionFlowable
from lxml import etree
from openerp.tools.misc import file_open
from openerp.tools.safe_eval import safe_eval
from . import color
from . import utils
try:
from customfonts import SetCustomFonts
from .customfonts import SetCustomFonts
except ImportError:
SetCustomFonts=lambda x:None
@@ -271,7 +271,6 @@ class _rml_doc(object):
def setTTFontMapping(self,face, fontname, filename, mode='all'):
from reportlab.lib.fonts import addMapping
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
if mode:
+1 -1
View File
@@ -3,9 +3,9 @@
import copy
import locale
import logging
import re
import reportlab
import openerp.tools as tools
+1 -1
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from rml2txt import parseString, parseNode
from .rml2txt import parseString, parseNode
""" This engine is the minimalistic renderer of RML documents into text files,
+2 -1
View File
@@ -4,9 +4,10 @@
import sys
import StringIO
from lxml import etree
import utils
from . import utils
Font_size= 10.0
+2
View File
@@ -3,8 +3,10 @@
import copy
import re
import reportlab
import reportlab.lib.units
from openerp.tools.safe_eval import safe_eval
_regex = re.compile('\[\[(.+?)\]\]')
+6 -6
View File
@@ -1,17 +1,17 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import render
from cStringIO import StringIO
import copy
import xml.dom.minidom
from cStringIO import StringIO
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table
import reportlab.lib
from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.lib.units import mm
from reportlab.lib.pagesizes import A4
import reportlab.lib
import copy
from . import render
class simple(render.render):
def _render(self):
+56 -56
View File
@@ -1,27 +1,29 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from lxml import etree
import StringIO
import cStringIO
import base64
from datetime import datetime
import cStringIO
import logging
import os
import re
import StringIO
import time
from interface import report_rml
import preprocess
import logging
import openerp.tools as tools
import zipfile
import common
from openerp.exceptions import AccessError
from datetime import datetime
from lxml import etree
import openerp
from openerp import SUPERUSER_ID
import openerp.tools as tools
from . import common
from . import preprocess
from .interface import report_rml
from openerp.exceptions import AccessError
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
from openerp.tools.safe_eval import safe_eval
from openerp.tools.translate import _
_logger = logging.getLogger(__name__)
@@ -59,11 +61,11 @@ def get_date_length(date_format=DEFAULT_SERVER_DATE_FORMAT):
class rml_parse(object):
def __init__(self, cr, uid, name, parents=rml_parents, tag=rml_tag, context=None):
if not context:
context={}
context = {}
self.cr = cr
self.uid = uid
self.pool = openerp.registry(cr.dbname)
user = self.pool['res.users'].browse(cr, uid, uid, context=context)
env = openerp.api.Environment(cr, uid, context)
user = env['res.users'].browse(uid)
self.localcontext = {
'user': user,
'setCompany': self.setCompany,
@@ -93,7 +95,7 @@ class rml_parse(object):
self.lang_dict = {}
self.default_lang = {}
self.lang_dict_called = False
self._transl_regex = re.compile('(\[\[.+?\]\])')
self._transl_regex = re.compile(r'(\[\[.+?\]\])')
def setTag(self, oldtag, newtag, attrs=None):
return newtag, attrs
@@ -123,19 +125,19 @@ class rml_parse(object):
def removeParentNode(self, tag=None):
raise GeneratorExit('Skip')
def set_html_image(self,id,model=None,field=None,context=None):
if not id :
def set_html_image(self, id, model=None, field=None, context=None):
if not id:
return ''
if not model:
model = 'ir.attachment'
try :
id = int(id)
res = self.pool[model].read(self.cr,self.uid,id)
if field :
try:
env = openerp.api.Environment(self.cr, self.uid, {})
res = env[model].browse(int(id)).read()[0]
if field:
return res[field]
elif model =='ir.attachment' :
elif model =='ir.attachment':
return res['datas']
else :
else:
return ''
except Exception:
return ''
@@ -148,13 +150,14 @@ class rml_parse(object):
self.objects = self.objects.with_env(env)
def _get_lang_dict(self):
pool_lang = self.pool['res.lang']
env = openerp.api.Environment(self.cr, self.uid, {})
Lang = env['res.lang']
lang = self.localcontext.get('lang', 'en_US') or 'en_US'
lang_ids = pool_lang.search(self.cr,self.uid,[('code','=',lang)])
if not lang_ids:
lang_ids = pool_lang.search(self.cr,self.uid,[('code','=','en_US')])
lang_obj = pool_lang.browse(self.cr,self.uid,lang_ids[0])
self.lang_dict.update({'lang_obj':lang_obj,'date_format':lang_obj.date_format,'time_format':lang_obj.time_format})
lang_obj = Lang.search([('code', '=', lang)], limit=1) or \
Lang.search([('code', '=', 'en_US')])
self.lang_dict.update({'lang_obj': lang_obj,
'date_format': lang_obj.date_format,
'time_format':lang_obj.time_format})
self.default_lang[lang] = self.lang_dict.copy()
return True
@@ -165,10 +168,10 @@ class rml_parse(object):
def get_digits(self, obj=None, f=None, dp=None):
d = DEFAULT_DIGITS = 2
if dp:
decimal_precision_obj = self.pool['decimal.precision']
d = decimal_precision_obj.precision_get(self.cr, self.uid, dp)
env = openerp.api.Environment(self.cr, self.uid, {})
d = env['decimal.precision'].precision_get(dp)
elif obj and f:
res_digits = getattr(obj._columns[f], 'digits', lambda x: ((16, DEFAULT_DIGITS)))
res_digits = getattr(obj._fields[f], 'digits', lambda x: ((16, DEFAULT_DIGITS)))
if isinstance(res_digits, tuple):
d = res_digits[1]
else:
@@ -243,13 +246,14 @@ class rml_parse(object):
def _translate(self,text):
lang = self.localcontext['lang']
if lang and text and not text.isspace():
transl_obj = self.pool['ir.translation']
env = openerp.api.Environment(self.cr, self.uid, {})
Translation = env['ir.translation']
piece_list = self._transl_regex.split(text)
for pn in range(len(piece_list)):
if not self._transl_regex.match(piece_list[pn]):
source_string = piece_list[pn].replace('\n', ' ').strip()
if len(source_string):
translated_string = transl_obj._get_source(self.cr, self.uid, self.name, ('report', 'rml'), lang, source_string)
translated_string = Translation._get_source(self.name, ('report', 'rml'), lang, source_string)
if translated_string:
piece_list[pn] = piece_list[pn].replace(source_string, translated_string)
text = ''.join(piece_list)
@@ -273,7 +277,7 @@ class rml_parse(object):
found.getparent().replace(found,tag)
return True
def set_context(self, objects, data, ids, report_type = None):
def set_context(self, objects, data, ids, report_type=None):
self.localcontext['data'] = data
self.localcontext['objects'] = objects
self.localcontext['digits_fmt'] = self.digits_fmt
@@ -296,6 +300,7 @@ class rml_parse(object):
# will have to call setCompany() inside the main repeatIn loop.
self.setCompany(objects[0].company_id)
class report_sxw(report_rml, preprocess.report):
"""
The register=True kwarg has been added to help remove the
@@ -319,8 +324,8 @@ class report_sxw(report_rml, preprocess.report):
self.internal_header=True
def getObjects(self, cr, uid, ids, context):
table_obj = openerp.registry(cr.dbname)[self.table]
return table_obj.browse(cr, uid, ids, context=context)
env = openerp.api.Environment(cr, uid, context or {})
return env[self.table].browse(ids)
def create(self, cr, uid, ids, data, context=None):
context = dict(context or {})
@@ -329,15 +334,12 @@ class report_sxw(report_rml, preprocess.report):
# skip osv.fields.sanitize_binary_value() because we want the raw bytes in all cases
context.update(bin_raw=True)
registry = openerp.registry(cr.dbname)
ir_obj = registry['ir.actions.report.xml']
registry['res.font'].font_scan(cr, SUPERUSER_ID, lazy=True, context=context)
env = openerp.api.Environment(cr, uid, context)
env['res.font'].sudo().font_scan(lazy=True)
ir_obj = env['ir.actions.report.xml']
report_xml_ids = ir_obj.search(cr, uid,
[('report_name', '=', self.name[7:])], context=context)
if report_xml_ids:
report_xml = ir_obj.browse(cr, uid, report_xml_ids[0], context=context)
else:
report_xml = ir_obj.search([('report_name', '=', self.name[7:])], limit=1)
if not report_xml:
title = ''
report_file = tools.file_open(self.tmpl, subdir=None)
try:
@@ -384,8 +386,8 @@ class report_sxw(report_rml, preprocess.report):
def create_source_pdf(self, cr, uid, ids, data, report_xml, context=None):
if not context:
context={}
registry = openerp.registry(cr.dbname)
context = {}
env = openerp.api.Environment(cr, uid, context)
attach = report_xml.attachment
if attach:
objs = self.getObjects(cr, uid, ids, context)
@@ -394,12 +396,11 @@ class report_sxw(report_rml, preprocess.report):
aname = safe_eval(attach, {'object':obj, 'time':time})
result = False
if report_xml.attachment_use and aname and context.get('attachment_use', True):
aids = registry['ir.attachment'].search(cr, uid, [('datas_fname','=',aname+'.pdf'),('res_model','=',self.table),('res_id','=',obj.id)])
if aids:
brow_rec = registry['ir.attachment'].browse(cr, uid, aids[0])
if not brow_rec.datas:
att = env['ir.attachment'].search([('datas_fname','=',aname+'.pdf'),('res_model','=',self.table),('res_id','=',obj.id)], limit=1)
if att:
if not att.datas:
continue
d = base64.decodestring(brow_rec.datas)
d = base64.decodestring(att.datas)
results.append((d,'pdf'))
continue
result = self.create_single_pdf(cr, uid, [obj.id], data, report_xml, context)
@@ -414,14 +415,13 @@ class report_sxw(report_rml, preprocess.report):
# field.
ctx = dict(context)
ctx.pop('default_type', None)
registry['ir.attachment'].create(cr, uid, {
env['ir.attachment'].with_context(ctx).create({
'name': aname,
'datas': base64.encodestring(result[0]),
'datas_fname': name,
'res_model': self.table,
'res_id': obj.id,
}, context=ctx
)
})
except AccessError:
#TODO: should probably raise a proper osv_except instead, shouldn't we? see LP bug #325632
_logger.info('Could not create saved report attachment', exc_info=True)