[IMP] report: reports with custom parsers can be declared in XML files.
bzr revid: vmt@openerp.com-20130222093428-f1isxxqlbaj7uhuo
This commit is contained in:
parent
a961e5e377
commit
0cb53890df
|
@ -96,8 +96,11 @@ class report_xml(osv.osv):
|
||||||
result = cr.dictfetchall()
|
result = cr.dictfetchall()
|
||||||
reports = openerp.report.interface.report_int._reports
|
reports = openerp.report.interface.report_int._reports
|
||||||
for r in result:
|
for r in result:
|
||||||
|
print ">>> Registering:", r['report_name'], "...",
|
||||||
if reports.has_key('report.'+r['report_name']):
|
if reports.has_key('report.'+r['report_name']):
|
||||||
|
print " Already present."
|
||||||
continue
|
continue
|
||||||
|
print " Done."
|
||||||
if r['report_rml'] or r['report_rml_content_data']:
|
if r['report_rml'] or r['report_rml_content_data']:
|
||||||
report_sxw('report.'+r['report_name'], r['model'],
|
report_sxw('report.'+r['report_name'], r['model'],
|
||||||
opj('addons',r['report_rml'] or '/'), header=r['header'])
|
opj('addons',r['report_rml'] or '/'), header=r['header'])
|
||||||
|
@ -140,6 +143,7 @@ class report_xml(osv.osv):
|
||||||
'report_sxw_content': fields.function(_report_content, fnct_inv=_report_content_inv, type='binary', string='SXW Content',),
|
'report_sxw_content': fields.function(_report_content, fnct_inv=_report_content_inv, type='binary', string='SXW Content',),
|
||||||
'report_rml_content': fields.function(_report_content, fnct_inv=_report_content_inv, type='binary', string='RML Content'),
|
'report_rml_content': fields.function(_report_content, fnct_inv=_report_content_inv, type='binary', string='RML Content'),
|
||||||
|
|
||||||
|
'parser': fields.char('Parser Class'),
|
||||||
}
|
}
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'type': 'ir.actions.report.xml',
|
'type': 'ir.actions.report.xml',
|
||||||
|
|
|
@ -107,6 +107,7 @@
|
||||||
<rng:optional><rng:attribute name="sxw"/></rng:optional>
|
<rng:optional><rng:attribute name="sxw"/></rng:optional>
|
||||||
<rng:optional><rng:attribute name="xml"/></rng:optional>
|
<rng:optional><rng:attribute name="xml"/></rng:optional>
|
||||||
<rng:optional><rng:attribute name="xsl"/></rng:optional>
|
<rng:optional><rng:attribute name="xsl"/></rng:optional>
|
||||||
|
<rng:optional><rng:attribute name="parser"/></rng:optional>
|
||||||
<rng:optional> <rng:attribute name="auto" /> </rng:optional>
|
<rng:optional> <rng:attribute name="auto" /> </rng:optional>
|
||||||
<rng:optional> <rng:attribute name="header" /> </rng:optional>
|
<rng:optional> <rng:attribute name="header" /> </rng:optional>
|
||||||
<rng:optional> <rng:attribute name="webkit_header" /> </rng:optional>
|
<rng:optional> <rng:attribute name="webkit_header" /> </rng:optional>
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
import errno
|
import errno
|
||||||
import logging
|
import logging
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
|
import operator
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import release
|
import release
|
||||||
|
@ -45,13 +46,37 @@ import openerp
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
def LocalService(name):
|
def LocalService(name, cursor=None):
|
||||||
# Special case for addons support, will be removed in a few days when addons
|
# Special case for addons support, will be removed in a few days when addons
|
||||||
# are updated to directly use openerp.osv.osv.service.
|
# are updated to directly use openerp.osv.osv.service.
|
||||||
if name == 'workflow':
|
if name == 'workflow':
|
||||||
return openerp.workflow
|
return openerp.workflow
|
||||||
|
|
||||||
return openerp.report.interface.report_int._reports[name]
|
if cursor is None: # TODO temporary, while refactoring
|
||||||
|
registered_report = openerp.report.interface.report_int._reports[name]
|
||||||
|
print ">>> Oh noes no cursor."
|
||||||
|
return registered_report
|
||||||
|
else:
|
||||||
|
from openerp.report.report_sxw import report_sxw, report_rml
|
||||||
|
cr = cursor
|
||||||
|
opj = os.path.join
|
||||||
|
cr.execute("SELECT * FROM ir_act_report_xml WHERE report_name=%s", (name[len('report.'):],))
|
||||||
|
result = cr.dictfetchall()
|
||||||
|
for r in result:
|
||||||
|
if r['report_rml'] or r['report_rml_content_data']:
|
||||||
|
if r['parser']:
|
||||||
|
kwargs = { 'parser': operator.attrgetter(r['parser'])(openerp.addons) }
|
||||||
|
else:
|
||||||
|
kwargs = {}
|
||||||
|
new_report = report_sxw('report.'+r['report_name'], r['model'],
|
||||||
|
opj('addons',r['report_rml'] or '/'), header=r['header'], register=False, **kwargs)
|
||||||
|
elif r['report_xsl']:
|
||||||
|
new_report = report_rml('report.'+r['report_name'], r['model'],
|
||||||
|
opj('addons',r['report_xml']),
|
||||||
|
r['report_xsl'] and opj('addons',r['report_xsl']), register=False)
|
||||||
|
else:
|
||||||
|
raise Exception, "Unhandled report type: %s" % r
|
||||||
|
return new_report
|
||||||
|
|
||||||
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, _NOTHING, DEFAULT = range(10)
|
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, _NOTHING, DEFAULT = range(10)
|
||||||
#The background is set with 40 plus the number of the color, and the foreground with 30
|
#The background is set with 40 plus the number of the color, and the foreground with 30
|
||||||
|
|
|
@ -43,11 +43,17 @@ class report_int(object):
|
||||||
|
|
||||||
_reports = {}
|
_reports = {}
|
||||||
|
|
||||||
def __init__(self, name):
|
def __init__(self, name, register=True):
|
||||||
if not name.startswith('report.'):
|
if register:
|
||||||
raise Exception('ConceptionError, bad report name, should start with "report."')
|
print "*** Registering report `%s` but it should be registered trough data declaration instead. ***" % name
|
||||||
assert name not in self._reports, 'The report "%s" already exists!' % name
|
if not name.startswith('report.'):
|
||||||
self._reports[name] = self
|
raise Exception('ConceptionError, bad report name, should start with "report."')
|
||||||
|
assert name not in self._reports, 'The report "%s" already exists!' % name
|
||||||
|
self._reports[name] = self
|
||||||
|
else:
|
||||||
|
# The report is instanciated at each use site, which is ok.
|
||||||
|
pass
|
||||||
|
|
||||||
self.__name = name
|
self.__name = name
|
||||||
|
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -65,8 +71,8 @@ class report_rml(report_int):
|
||||||
XML -> DATAS -> RML -> PDF -> HTML
|
XML -> DATAS -> RML -> PDF -> HTML
|
||||||
using a XSL:RML transformation
|
using a XSL:RML transformation
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, table, tmpl, xsl):
|
def __init__(self, name, table, tmpl, xsl, register=True):
|
||||||
super(report_rml, self).__init__(name)
|
super(report_rml, self).__init__(name, register=register)
|
||||||
self.table = table
|
self.table = table
|
||||||
self.internal_header=False
|
self.internal_header=False
|
||||||
self.tmpl = tmpl
|
self.tmpl = tmpl
|
||||||
|
|
|
@ -264,7 +264,7 @@ class document(object):
|
||||||
def parse_tree(self, ids, model, context=None):
|
def parse_tree(self, ids, model, context=None):
|
||||||
if not context:
|
if not context:
|
||||||
context={}
|
context={}
|
||||||
browser = self.pool.get(model).browse(self.cr, self.uid, ids, context)
|
browser = self.pool[model].browse(self.cr, self.uid, ids, context)
|
||||||
self.parse_node(self.dom, self.doc, browser)
|
self.parse_node(self.dom, self.doc, browser)
|
||||||
|
|
||||||
def parse_string(self, xml, ids, model, context=None):
|
def parse_string(self, xml, ids, model, context=None):
|
||||||
|
|
|
@ -388,8 +388,8 @@ class rml_parse(object):
|
||||||
self.setCompany(objects[0].company_id)
|
self.setCompany(objects[0].company_id)
|
||||||
|
|
||||||
class report_sxw(report_rml, preprocess.report):
|
class report_sxw(report_rml, preprocess.report):
|
||||||
def __init__(self, name, table, rml=False, parser=rml_parse, header='external', store=False):
|
def __init__(self, name, table, rml=False, parser=rml_parse, header='external', store=False, register=True):
|
||||||
report_rml.__init__(self, name, table, rml, '')
|
report_rml.__init__(self, name, table, rml, '', register=register)
|
||||||
self.name = name
|
self.name = name
|
||||||
self.parser = parser
|
self.parser = parser
|
||||||
self.header = header
|
self.header = header
|
||||||
|
|
|
@ -90,7 +90,7 @@ def exp_report(db, uid, object, ids, datas=None, context=None):
|
||||||
def go(id, uid, ids, datas, context):
|
def go(id, uid, ids, datas, context):
|
||||||
cr = openerp.pooler.get_db(db).cursor()
|
cr = openerp.pooler.get_db(db).cursor()
|
||||||
try:
|
try:
|
||||||
obj = openerp.netsvc.LocalService('report.'+object)
|
obj = openerp.netsvc.LocalService('report.'+object, cursor=cr)
|
||||||
(result, format) = obj.create(cr, uid, ids, datas, context)
|
(result, format) = obj.create(cr, uid, ids, datas, context)
|
||||||
if not result:
|
if not result:
|
||||||
tb = sys.exc_info()
|
tb = sys.exc_info()
|
||||||
|
|
|
@ -302,6 +302,8 @@ form: module.record_id""" % (xml_id,)
|
||||||
res['header'] = eval(rec.get('header','False'))
|
res['header'] = eval(rec.get('header','False'))
|
||||||
if rec.get('report_type'):
|
if rec.get('report_type'):
|
||||||
res['report_type'] = rec.get('report_type')
|
res['report_type'] = rec.get('report_type')
|
||||||
|
if rec.get('parser'):
|
||||||
|
res['parser'] = rec.get('parser')
|
||||||
|
|
||||||
res['multi'] = rec.get('multi') and eval(rec.get('multi','False'))
|
res['multi'] = rec.get('multi') and eval(rec.get('multi','False'))
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None):
|
||||||
else:
|
else:
|
||||||
rname_s = rname
|
rname_s = rname
|
||||||
_logger.log(netsvc.logging.TEST, " - Trying %s.create(%r)", rname, ids)
|
_logger.log(netsvc.logging.TEST, " - Trying %s.create(%r)", rname, ids)
|
||||||
res = netsvc.LocalService(rname).create(cr, uid, ids, data, context)
|
res = netsvc.LocalService(rname, cursor=cr).create(cr, uid, ids, data, context)
|
||||||
if not isinstance(res, tuple):
|
if not isinstance(res, tuple):
|
||||||
raise RuntimeError("Result of %s.create() should be a (data,format) tuple, now it is a %s" % \
|
raise RuntimeError("Result of %s.create() should be a (data,format) tuple, now it is a %s" % \
|
||||||
(rname, type(res)))
|
(rname, type(res)))
|
||||||
|
|
Loading…
Reference in New Issue