diff --git a/__init__.py b/__init__.py index 9071ae81..e75b483b 100644 --- a/__init__.py +++ b/__init__.py @@ -1,5 +1 @@ import ir_report -import py3o_report -import py3o_template -import py3o_server -import py3o_fusion_filetype diff --git a/__openerp__.py b/__openerp__.py index afff8ecb..49cb56cb 100644 --- a/__openerp__.py +++ b/__openerp__.py @@ -43,9 +43,6 @@ The py3o.template package is required; install it with: 'data': [ 'menu.xml', 'ir_report.xml', - 'py3o_template.xml', - 'py3o_server.xml', - 'data/py3o.fusion.filetype.csv', 'security/ir.model.access.csv', ], 'installable': True, diff --git a/ir_report.py b/ir_report.py index 7ae4c52f..7cc5458e 100644 --- a/ir_report.py +++ b/ir_report.py @@ -1,11 +1,15 @@ +import os from openerp.osv import fields, osv +from openerp.report.interface import report_int +from .py3o_parser import Py3oParser +from openerp import addons class report_xml(osv.Model): - ''' Inherit from ir.actions.report.xml to allow customizing the template + """ Inherit from ir.actions.report.xml to allow customizing the template file. The user cam chose a template from a list. The list is configurable in the configuration tab, see py3o_template.py - ''' + """ _inherit = 'ir.actions.report.xml' @@ -37,3 +41,45 @@ class report_xml(osv.Model): u"any kind of report.", ) } + + def _lookup_report(self, cr, name): + """ + Look up a report definition. + """ + + # First lookup in the deprecated place, because if the report + # definition has not been updated, it is more likely the correct + # definition is there. Only reports with custom parser + # specified in Python are still there. + if 'report.' + name in report_int._reports: + new_report = report_int._reports['report.' + name] + if not isinstance(new_report, Py3oParser): + new_report = None + else: + cr.execute( + 'SELECT * ' + 'FROM ir_act_report_xml ' + 'WHERE report_name=%s AND report_type=%s', + (name, 'py3o') + ) + r = cr.dictfetchone() + if r: + kwargs = {} + if r['parser']: + kwargs['parser'] = getattr(addons, r['parser']) + + new_report = Py3oParser( + 'report.' + r['report_name'], + r['model'], + os.path.join('addons', r['report_rml'] or '/'), + header=r['header'], + register=False, + **kwargs + ) + else: + new_report = None + + if new_report: + return new_report + else: + return super(report_xml, self)._lookup_report(cr, name) diff --git a/py3o_parser.py b/py3o_parser.py new file mode 100644 index 00000000..9e6e3aa5 --- /dev/null +++ b/py3o_parser.py @@ -0,0 +1,102 @@ +from openerp.report.report_sxw import report_sxw, rml_parse +from openerp import registry + + +_extender_functions = {} + + +def py3o_report_extender(report_name): + """ + A decorator to define function to extend the context sent to a template. + This will be called at the creation of the report. + The following arguments will be passed to it: + - pool: the model pool + - cr: the database cursor + - uid: the id of the user that call the renderer + - localcontext: The context that will be passed to the report engine + - context: the Odoo context + + Method copied from CampToCamp report_webkit module. + + :param report_name: xml id of the report + :return: + """ + def fct1(fct): + lst = _extender_functions.get(report_name) + if not lst: + lst = [] + _extender_functions[report_name] = lst + lst.append(fct) + return fct + return fct1 + + +class Py3oParser(report_sxw): + """Custom class that use Py3o to render libroffice reports. + Code partially taken from CampToCamp.""" + + def __init__(self, name, table, rml=False, parser=rml_parse, + header=False, store=False, register=True): + self.localcontext = {} + super(Py3oParser, self).__init__( + name, table, rml=rml, parser=parser, + header=header, store=store, register=register + ) + + def create_single_pdf(self, cr, uid, ids, data, report_xml, context=None): + """ Overide this function to generate our py3o report + """ + if report_xml.report_type != 'py3o': + return super(Py3oParser, self).create_single_pdf( + cr, uid, ids, data, report_xml, context=context + ) + + pool = registry(cr.dbname) + model_data_ids = pool['ir.model.data'].search( + cr, uid, [ + ('model', '=', 'ir.actions.report.xml'), + ('res_id', '=', report_xml.id), + ] + ) + + xml_id = None + if model_data_ids: + model_data = pool['ir.model.data'].browse( + cr, uid, model_data_ids[0], context=context + ) + xml_id = '%s,%s' % (model_data.module, model_data.name) + + parser_instance = self.parser(cr, uid, self.name2, context=context) + parser_instance.set_context( + self.getObjects(cr, uid, ids, context), + data, ids, report_xml.report_type + ) + + if xml_id in _extender_functions: + for fct in _extender_functions[xml_id]: + pass + + def create(self, cr, uid, ids, data, context=None): + """ Override this function to handle our py3o report + """ + pool = registry(cr.dbname) + ir_action_report_obj = pool['ir.actions.report.xml'] + report_xml_ids = ir_action_report_obj.search( + cr, uid, [('report_name', '=', self.name[7:])], context=context + ) + if not report_xml_ids: + return super(Py3oParser, self).create( + cr, uid, ids, data, context=context + ) + + report_xml = ir_action_report_obj.browse( + cr, uid, report_xml_ids[0], context=context + ) + + result = self.create_source_pdf( + cr, uid, ids, data, report_xml, context + ) + + if not result: + return False, False + return result \ No newline at end of file