Developments for report designer
base_report_designer module allows you to create your own reports reports and images are stored in the database custom report may override base reports RML modification You can now select to put the image in the RML instead than in a separate file bzr revid: fp@tinyerp.com-0928aef6e14868d3cd6619d9d73031bfc5651ea2
This commit is contained in:
parent
dfa94edfb6
commit
19aa5fdc18
|
@ -90,7 +90,9 @@ class report_xml(osv.osv):
|
|||
'report_name': fields.char('Internal Name', size=64, required=True),
|
||||
'report_xsl': fields.char('XSL path', size=256),
|
||||
'report_xml': fields.char('XML path', size=256),
|
||||
'report_rml': fields.char('RML path', size=256),
|
||||
'report_rml': fields.char('RML path', size=256, help="The .rml path of the file or NULL if the content is in report_rml_content"),
|
||||
'report_sxw_content': fields.binary('SXW content'),
|
||||
'report_rml_content': fields.binary('RML content'),
|
||||
'auto': fields.boolean('Automatic XSL:RML', required=True),
|
||||
'usage': fields.char('Action Usage', size=32),
|
||||
'header': fields.boolean('Add RML header', help="Add or not the coporate RML header"),
|
||||
|
@ -99,6 +101,7 @@ class report_xml(osv.osv):
|
|||
'type': lambda *a: 'ir.actions.report.xml',
|
||||
'auto': lambda *a: True,
|
||||
'header': lambda *a: True,
|
||||
'report_sxw_content': lambda *a: False,
|
||||
}
|
||||
report_xml()
|
||||
|
||||
|
|
|
@ -1319,22 +1319,26 @@ class orm(object):
|
|||
result['arch'] = xarch
|
||||
result['fields'] = xfields
|
||||
if toolbar:
|
||||
def clean(x):
|
||||
x = x[2]
|
||||
for key in ('report_sxw_content','report_rml_content','report_sxw','report_rml'):
|
||||
if key in x:
|
||||
del x[key]
|
||||
return x
|
||||
resprint = self.pool.get('ir.values').get(cr, user, 'action', 'client_print_multi', [(self._name, False)], False, context)
|
||||
resaction = self.pool.get('ir.values').get(cr, user, 'action', 'client_action_multi', [(self._name, False)], False, context)
|
||||
resrelate = self.pool.get('ir.values').get(cr, user, 'action', 'client_action_relate', [(self._name, False)], False, context)
|
||||
resprint = map(lambda x:x[2], resprint)
|
||||
resaction = map(lambda x:x[2], resaction)
|
||||
resprint = map(clean, resprint)
|
||||
resaction = map(clean, resaction)
|
||||
resaction = filter(lambda x: not x.get('multi',False), resaction)
|
||||
resrelate = map(lambda x:x[2], resrelate)
|
||||
for x in resprint+resaction+resrelate:
|
||||
x['string'] = x['name']
|
||||
|
||||
result['toolbar'] = {
|
||||
'print': resprint,
|
||||
'action': resaction,
|
||||
'relate': resrelate
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
# TODO: ameliorer avec NULL
|
||||
|
|
|
@ -160,6 +160,20 @@ class _rml_doc(object):
|
|||
addMapping(name, 1, 0, name) #bold
|
||||
addMapping(name, 1, 1, name) #italic and bold
|
||||
|
||||
def _textual_image(self, node):
|
||||
import base64
|
||||
rc = ''
|
||||
for n in node.childNodes:
|
||||
if n.nodeType in (node.CDATA_SECTION_NODE, node.TEXT_NODE):
|
||||
rc += n.data
|
||||
return base64.decodestring(rc)
|
||||
|
||||
def _images(self, el):
|
||||
result = {}
|
||||
for node in el.getElementsByTagName('image'):
|
||||
result[node.getAttribute('name')] = self._textual_image(node)
|
||||
return result
|
||||
|
||||
def render(self, out):
|
||||
el = self.dom.documentElement.getElementsByTagName('docinit')
|
||||
if el:
|
||||
|
@ -168,6 +182,10 @@ class _rml_doc(object):
|
|||
el = self.dom.documentElement.getElementsByTagName('stylesheet')
|
||||
self.styles = _rml_styles(el)
|
||||
|
||||
el = self.dom.documentElement.getElementsByTagName('images')
|
||||
if el:
|
||||
self.images.update( self._images(el[0]) )
|
||||
|
||||
el = self.dom.documentElement.getElementsByTagName('template')
|
||||
if len(el):
|
||||
pt_obj = _rml_template(out, el[0], self, images=self.images, path=self.path)
|
||||
|
@ -285,12 +303,15 @@ class _rml_canvas(object):
|
|||
if not node.hasAttribute('file'):
|
||||
s = self.images[node.getAttribute('name')]
|
||||
else:
|
||||
try:
|
||||
u = urllib.urlopen(str(node.getAttribute('file')))
|
||||
s = StringIO.StringIO(u.read())
|
||||
except:
|
||||
u = file(os.path.join(self.path,str(node.getAttribute('file'))), 'rb')
|
||||
s = StringIO.StringIO(u.read())
|
||||
if node.getAttribute('file') in self.images:
|
||||
s = StringIO.StringIO(self.images[node.getAttribute('file')])
|
||||
else:
|
||||
try:
|
||||
u = urllib.urlopen(str(node.getAttribute('file')))
|
||||
s = StringIO.StringIO(u.read())
|
||||
except:
|
||||
u = file(os.path.join(self.path,str(node.getAttribute('file'))), 'rb')
|
||||
s = StringIO.StringIO(u.read())
|
||||
img = ImageReader(s)
|
||||
(sx,sy) = img.getSize()
|
||||
|
||||
|
|
|
@ -303,7 +303,12 @@ class report_sxw(report_rml):
|
|||
return table_obj.browse(cr, uid, ids, list_class=browse_record_list, context=context)
|
||||
|
||||
def create(self, cr, uid, ids, data, context={}):
|
||||
rml = tools.file_open(self.tmpl, subdir=None).read()
|
||||
cr.execute('select report_rml_content from ir_act_report_xml where report_name=%s', (self.name[7:],))
|
||||
result = cr.fetchone()
|
||||
if result and result[0]:
|
||||
rml = result[0]
|
||||
else:
|
||||
rml = tools.file_open(self.tmpl, subdir=None).read()
|
||||
|
||||
rml_parser = self.parser(cr, uid, self.name2, context)
|
||||
objs = self.getObjects(cr, uid, ids, context)
|
||||
|
|
|
@ -7,6 +7,7 @@ import osv,ir,pooler
|
|||
|
||||
import csv
|
||||
import os.path
|
||||
import misc
|
||||
|
||||
from config import config
|
||||
|
||||
|
@ -142,6 +143,9 @@ class xml_import(object):
|
|||
res[dest] = rec.getAttribute(field).encode('utf8')
|
||||
if rec.hasAttribute('auto'):
|
||||
res['auto'] = eval(rec.getAttribute('auto'))
|
||||
if rec.hasAttribute('sxw'):
|
||||
sxw_content = misc.file_open(rec.getAttribute('sxw')).read()
|
||||
res['report_sxw_content'] = sxw_content
|
||||
if rec.hasAttribute('header'):
|
||||
res['header'] = eval(rec.getAttribute('header'))
|
||||
xml_id = rec.getAttribute('id').encode('utf8')
|
||||
|
|
Loading…
Reference in New Issue