通过 python odoo 9 自定义报告
custom report through python 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>
通过上下文传递数据无效。我尝试以抽象方式打印域 class 它 return none。但在我的向导中没问题
如果您想在报告打印之前运行特定代码或将自定义数据传递给模板进行渲染,您可以创建一个定义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')
您需要在向导中创建一个函数来调用传递上下文的报表。
下面是创建自定义模型报告的代码,它封装在 v9 API 上。创建自定义对象报告是三步过程
- 创建 RML Prase 自定义报表对象
- 将 RML 报告包装成 qweb 引擎的 AbstractModel 报告。
- 自定义对象的设计模板。
- 注册您的举报注册表。
此处列出了所有四个部分以及可能的示例代码。
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]
包装 QWeb 引擎的 RML Prase 对象。
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__
下注册它们,您可以根据需要直接在您的报告和 mutpllate 数据上调用这些函数。
PS: 替换为您的模块以使机智正常工作。
希望这会有所帮助。
如何将多个模块数据传递给一个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>
通过上下文传递数据无效。我尝试以抽象方式打印域 class 它 return none。但在我的向导中没问题
如果您想在报告打印之前运行特定代码或将自定义数据传递给模板进行渲染,您可以创建一个定义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')
您需要在向导中创建一个函数来调用传递上下文的报表。
下面是创建自定义模型报告的代码,它封装在 v9 API 上。创建自定义对象报告是三步过程
- 创建 RML Prase 自定义报表对象
- 将 RML 报告包装成 qweb 引擎的 AbstractModel 报告。
- 自定义对象的设计模板。
- 注册您的举报注册表。
此处列出了所有四个部分以及可能的示例代码。
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]
包装 QWeb 引擎的 RML Prase 对象。
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__
下注册它们,您可以根据需要直接在您的报告和 mutpllate 数据上调用这些函数。
PS: 替换为您的模块以使机智正常工作。
希望这会有所帮助。