自定义报告通过python odoo 9

时间:2016-10-27 17:16:36

标签: python openerp odoo-8 wkhtmltopdf odoo-9

如何将多个模块数据传递给QWeb报告?是否有类似于从控制器渲染html时传递字典的东西?

class account(model.Models):
    _name = 'account.main'      

    name = fields.Char()


class accountSub(model.Models):
    _name = 'account.sub'

    name = fields.Char()    

class PrintWizard(model.Models):
    _name = 'print.report'


    account = fields.Many2one('erp.account')

    @api.multi
    def print_report(self):
       ctx = self.env.context.copy()
       ctx.update({'domain':[('name','=',self.account.name)]})
       self.with_context(ctx)
       return {'name': 'Report',
            'type': 'ir.actions.report.xml',
            'report_name': 'erp.report_id',
            'report_type': 'qweb-pdf'}


class ErpReport(models.AbstractModel):
   _name = "report.erp.report_id"

   @api.multi
   def print_report(self)
       domain = self.env.context.get('domain')
       print(domain) #Print result was None
       main = self.env['account.main'].search(domain)
       sub = self.env['account.sub'].search([])
       docs = {
          'docs1': main,
          'docs2': sub,
       }
       return self.env['report'].render('erp.report', docs)

QWeb

<report
    id="report_id"
    string="Report"
    model="erp.report"
    report_type="qweb-pdf"
    file="erp.report"
    name="erp.report"
/>

<template id="payment_slip">
    <t t-call="nationalerp_sales.erp_external_layout">
        <t t-call="report.html_container">
            <div class="page">
                <div>
                    <t t-foreach="docs1" t-as="main">
                        <t t-esc="main.name"/>
                    </t>
                    <t t-foreach="docs2" t-as="sub">
                        <t t-esc="sub.name"/>
                    </t>
                </div>
            </div>
        </t>
    </t>
</template>

通过上下文传递数据不起作用。我试图在抽象类中打印域,它返回none。但在我的向导中它没关系

2 个答案:

答案 0 :(得分:2)

如果要在报表打印或将自定义数据传递到模板进行渲染之前运行特定代码,可以创建一个定义render_html函数的抽象模型,以便在打印报表时运行您的函数而不是通用的odoo函数。这在文档中引用 HERE

看看这个例子。

from openerp import models, fields, api, exceptions

class YourReport(models.AbstractModel):
    _name = 'report.your_addon.report_template_id'

    @api.multi
    def render_html(self, data=None):
        report_obj = self.env['report']
        report = report_obj._get_report_from_name('your_addon.report_template_id')
        model1_docs = self.env['your_addon.your_model1'].search([('something','=','something')])
        model2_docs = self.env['your_addon.your_model2'].search([('something','=','something')])   
        docargs = {
            'doc_model': report.model,
            'model1_docs': model1_docs,
            'model2_docs': model2_docs,
        }
        return report_obj.render('your_addon.report_template_id', docargs)

使用修改后的上下文更新:

要使用修改后的上下文调用您的报告,请尝试以下操作(未经测试)。我找不到任何使用修改后的上下文调用报告的示例,但是看起来并不广泛。

ctx = self.env.context.copy()
ctx.update({'domain':[('something','=','something')]})
self.with_context(ctx)
return {
    'name':'Report',
    'type':'ir.actions.report.xml,
    'report_name':'your_addon.report_template_id',
    'report_type':'qweb-pdf'
}

然后,从我们之前定义的报告功能中,您应该能够通过您的环境访问上下文。

domain = self.env.context.get('domain')

您需要在向导中创建一个函数,该函数调用通过上下文的报告。

答案 1 :(得分:1)

以下是创建自定义模型报告的代码,该报告包含在v9 API上。创建自定义对象报告是三步过程

  1. 创建RML Prase自定义报告对象
  2. 将RML报告包装到qweb引擎的AbstractModel报告中。
  3. 自定义对象的设计模板。
  4. 注册您的报告注册表。
  5. 此处列出的所有四部分都带有可能的示例代码。

    RML Prase自定义报告对象

    import time
    from openerp.osv import osv
    from openerp.report import report_sxw
    
    
    class CustomReportPrint(report_sxw.rml_parse):
    
        def __init__(self, cr, uid, name, context):
            super(CustomReportPrint, self).__init__(cr, uid, name, context=context)
            self.localcontext.update({
                'time': time,
                'lst': self._lst,
                'total': self._some_total,
                'get_records':self._get_records,
            })
    
        def _get_records(self, res_ids):
            records = self.pool.get('res.partner').browse(self.cr, self.uid, res_ids)
            return records
    
        def _lst(self, employee_id, dt_from, dt_to, max, *args):
            #Your code goes here
            return res
    
        def _some_total(self, employee_id, dt_from, dt_to, max, *args):
            #Your code goes here
            return [result_dict]
    

    包装 RML Prase对象到QWeb引擎。

    class report_custom_print(osv.AbstractModel):
        _name = 'report.<module_name>.report_custom_print'
        _inherit = 'report.abstract_report'
        _template = '<module_name>.report_custom_print'
        _wrapped_report_class = CustomReportPrint
    

    报告XML如下所示,您可以看到我从自定义报告模型中调用get_records

    <?xml version="1.0" encoding="utf-8"?>
    <openerp>
        <data>
            <template id="report_custom_print">
                <t t-call="report.html_container">
                    <t t-foreach="get_records(data['form']['res_ids'])" t-as="employee">
                        <t t-call="report.internal_layout">
                            <div class="page">
                                <div class="oe_structure" />
                            </div>
                        </t>
                    </t>
                </t>
            </template>
        </data>
    </openerp>
    

    注册报告

        <record id="action_report_custom_print" model="ir.actions.report.xml">
            <field name="name">Custom Print Report</field>
            <field name="report_type">qweb-pdf</field>
            <field name="model">res.partner</field>
            <field name="report_name"><module_name>.report_custom_print</field>
            <field name="report_file"><module_name>.report_custom_print</field>
        </record>
    

    在自定义Rml报告对象中,您可以根据需要定义任意数量的函数,并在__int__下注册它们,您可以根据需要直接在yor rpeort和mutpllate数据上调用这些函数。

    PS:替换你的模块以使机智正常工作。

    希望这会有所帮助。