【问题标题】:custom report through python odoo 9通过 python odoo 9 自定义报告
【发布时间】:2016-10-27 17:16:35
【问题描述】:

如何将多个模块数据传递给 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>

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

【问题讨论】:

  • 你有这份报告的完整例子吗,你能发给我吗?

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


【解决方案1】:

如果您想在打印报告之前运行特定代码或将自定义数据传递给模板以进行渲染,您可以创建一个定义 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')

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

【讨论】:

  • 如何通过向导将域传递给 model2_docs 和 model1_docs 搜索。我尝试了创建方法,但没有奏效
  • 您必须发布代码以确定原因。它可以是任何东西。我没有看到通过报告传递自定义上下文。
【解决方案2】:

以下是创建自定义模型报告的代码,该报告包装在 v9 API 上。创建自定义对象报告分为三个步骤

  1. 创建 RML Prase 自定义报告对象
  2. 将 RML 报告包装成 qweb 引擎的 AbstractModel 报告。
  3. 自定义对象的设计模板。
  4. 注册您的报告注册表。

此处列出的所有四个部分以及可能的示例代码。

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__ 下,您可以直接在您的报告中调用这些函数并根据需要对数据进行混合。

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

希望这会有所帮助。

【讨论】:

  • 不错的答案,但为什么有人应该在 Odoo 9 中使用已弃用的 RML 报告?
  • 首先我要在这里提到的是您使用的是什么版本?您质疑建议 v9 或更高版本。现在只迁移了 20% 并且仍然保留了大部分旧代码,不幸的是 v9 只有这种处理方式。如果您询问 v10,yes 代码将更改为一定程度。 Avian v9 介于新旧 API 之间。我们还看到不使用旧的解析,只使用包含 rml 解析名称的报告类。仔细运行代码会建议您我们只编写 qweb。 v10 中的相同代码变化不大。
  • 首先这不是我的问题,其次他的示例报告 xml 条目明确指出 type="qweb-pdf"。
  • 我更新了我的问题,请检查报告是否已通过上下文打印。
  • @JediShadow 有没有这样的例子对初学者有更详细的解释?
猜你喜欢
  • 1970-01-01
  • 2021-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多