适配Odoo报表用于邮件发送:仅为当前partner_id修改环境
解决Odoo报表作为邮件附件传递参数的问题
我懂你现在的困扰——想把OCA的报表做成邮件附件单独发给每个客户,但在邮件模板里传递参数时,卡在了partner_ids: self._context['active_...'这块,尤其是data为None的情况。下面给你几个实用的解决思路和代码示例:
1. 重写报表的参数获取逻辑,兼容邮件模板场景
报表默认依赖向导传入的data或者上下文里的活动记录,但邮件模板触发时的上下文和向导完全不同,所以得让报表能灵活适配两种场景:
def _get_report_values(self, docids, data=None): # 邮件模板调用时data大概率为None,此时从docids(客户ID)提取参数 if not data: # 从docids获取当前要发送的客户记录 target_partners = self.env['res.partner'].browse(docids) # 生成报表需要的参数,比如筛选该客户的关联单据、设置默认范围等 data = { 'partner_ids': docids, # 这里可以补充其他必填参数,比如默认日期范围、报表类型等 } # 沿用原报表的核心逻辑 return super()._get_report_values(docids, data=data)
2. 在邮件模板里正确关联报表并传递参数
邮件模板里添加附件时,别依赖active_ids,直接通过object(当前客户记录)传递ID:
在邮件模板的附件配置里,按以下格式添加:
<attachment> <name>专属客户报表.pdf</name> <type>qweb-pdf</type> <report>你的模块名.报表外部ID</report> <context>{"docids": object.id}</context> </attachment>
这样每发送一封邮件,都会把当前客户的ID传给报表,生成对应内容的附件。
3. 修复partner_ids的上下文依赖问题
你遇到的self._context['active_...'报错,本质是邮件发送时上下文里没有active_ids这个值。所以要彻底改掉从上下文取参数的习惯,换成从data或docids获取:
# 错误写法:依赖不稳定的上下文 # partner_ids = self._context.get('active_ids', []) # 正确写法:优先用传入的data,其次用docids if data and data.get('partner_ids'): partner_ids = data['partner_ids'] else: partner_ids = docids
4. 测试时的关键注意点
- 先单独测试报表:传入单个客户ID,确认能生成正确的专属报表
- 单客户邮件测试:从客户列表选一个客户发送邮件,检查附件内容是否匹配
- 批量发送测试:确保批量处理时,每封邮件的附件都是对应客户的专属报表
这样调整后,就能让报表完美适配邮件附件场景,给每个客户发送专属内容啦。
内容的提问来源于stack exchange,提问作者user2757902




