[IMP] report: reports with custom parsers can be declared in XML files.
authorVo Minh Thu <vmt@openerp.com>
Fri, 22 Feb 2013 09:34:28 +0000 (10:34 +0100)
committerVo Minh Thu <vmt@openerp.com>
Fri, 22 Feb 2013 09:34:28 +0000 (10:34 +0100)
bzr revid: vmt@openerp.com-20130222093428-f1isxxqlbaj7uhuo

openerp/addons/base/ir/ir_actions.py
openerp/import_xml.rng
openerp/netsvc.py
openerp/report/interface.py
openerp/report/print_xml.py
openerp/report/report_sxw.py
openerp/service/report.py
openerp/tools/convert.py
openerp/tools/test_reports.py

index beb4e27..4f3ed8b 100644 (file)
@@ -96,8 +96,11 @@ class report_xml(osv.osv):
         result = cr.dictfetchall()
         reports = openerp.report.interface.report_int._reports
         for r in result:
+            print ">>> Registering:", r['report_name'], "...",
             if reports.has_key('report.'+r['report_name']):
+                print " Already present."
                 continue
+            print " Done."
             if r['report_rml'] or r['report_rml_content_data']:
                 report_sxw('report.'+r['report_name'], r['model'],
                         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_rml_content': fields.function(_report_content, fnct_inv=_report_content_inv, type='binary', string='RML Content'),
 
+        'parser': fields.char('Parser Class'),
     }
     _defaults = {
         'type': 'ir.actions.report.xml',
index 97b2c4a..5f4c40b 100644 (file)
             <rng:optional><rng:attribute name="sxw"/></rng:optional>
             <rng:optional><rng:attribute name="xml"/></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="header" /> </rng:optional>
             <rng:optional> <rng:attribute name="webkit_header" /> </rng:optional>
index a5e33ff..33d7a22 100644 (file)
@@ -24,6 +24,7 @@
 import errno
 import logging
 import logging.handlers
+import operator
 import os
 import platform
 import release
@@ -45,13 +46,37 @@ import openerp
 
 _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
     # are updated to directly use openerp.osv.osv.service.
     if name == '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)
 #The background is set with 40 plus the number of the color, and the foreground with 30
index f0de963..6c5fc24 100644 (file)
@@ -43,11 +43,17 @@ class report_int(object):
 
     _reports = {}
     
-    def __init__(self, name):
-        if not name.startswith('report.'):
-            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
+    def __init__(self, name, register=True):
+        if register:
+            print "*** Registering report `%s` but it should be registered trough data declaration instead. ***" % name
+            if not name.startswith('report.'):
+                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
@@ -65,8 +71,8 @@ class report_rml(report_int):
             XML -> DATAS -> RML -> PDF -> HTML
         using a XSL:RML transformation
     """
-    def __init__(self, name, table, tmpl, xsl):
-        super(report_rml, self).__init__(name)
+    def __init__(self, name, table, tmpl, xsl, register=True):
+        super(report_rml, self).__init__(name, register=register)
         self.table = table
         self.internal_header=False
         self.tmpl = tmpl
index c2af098..558f7dd 100644 (file)
@@ -264,7 +264,7 @@ class document(object):
     def parse_tree(self, ids, model, context=None):
         if not 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)
 
     def parse_string(self, xml, ids, model, context=None):
index 3256902..0e2a7e1 100644 (file)
@@ -388,8 +388,8 @@ class rml_parse(object):
             self.setCompany(objects[0].company_id)
 
 class report_sxw(report_rml, preprocess.report):
-    def __init__(self, name, table, rml=False, parser=rml_parse, header='external', store=False):
-        report_rml.__init__(self, name, table, rml, '')
+    def __init__(self, name, table, rml=False, parser=rml_parse, header='external', store=False, register=True):
+        report_rml.__init__(self, name, table, rml, '', register=register)
         self.name = name
         self.parser = parser
         self.header = header
index c20c7f0..d7832df 100644 (file)
@@ -90,7 +90,7 @@ def exp_report(db, uid, object, ids, datas=None, context=None):
     def go(id, uid, ids, datas, context):
         cr = openerp.pooler.get_db(db).cursor()
         try:
-            obj = openerp.netsvc.LocalService('report.'+object)
+            obj = openerp.netsvc.LocalService('report.'+object, cursor=cr)
             (result, format) = obj.create(cr, uid, ids, datas, context)
             if not result:
                 tb = sys.exc_info()
index 00b8bf9..a8ba37e 100644 (file)
@@ -302,6 +302,8 @@ form: module.record_id""" % (xml_id,)
             res['header'] = eval(rec.get('header','False'))
         if 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'))
 
index 9ec4dab..71cedc1 100644 (file)
@@ -50,7 +50,7 @@ def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None):
     else:
         rname_s = rname
     _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):
         raise RuntimeError("Result of %s.create() should be a (data,format) tuple, now it is a %s" % \
                                 (rname, type(res)))