Odoo14:如何通过Cron发送含stock.warehouse.orderpoint单PDF邮件
Odoo14 实现Cron定时发送合并库存预警报表邮件
问题现状
当前Cron任务会遍历每条stock.warehouse.orderpoint记录并单独发送邮件,需求改为一次性发送包含所有记录的PDF报表邮件。
现有代码
1. Cron定时任务配置
<record id="ir_cron_auto_send_mail_quantity_notifier" model="ir.cron"> <field name="name">Quantity Notifier</field> <field name="model_id" ref="stock.model_stock_warehouse_orderpoint"/> <field name="state">code</field> <field name="code"> for stock in env['stock.warehouse.orderpoint'].search([]): try: stock.send_reminder_mail() env.cr.commit() except Exception as e: pass </field> <field name="active" eval="True"/> <field name="user_id" ref="base.user_root"/> <field name='interval_number'>1</field> <field name='interval_type'>days</field> <field name="numbercall">-1</field> <field name="doall" eval="False"/> </record>
2. 邮件发送函数
class StockWarehouseOrderpoint(models.Model): _inherit = "stock.warehouse.orderpoint" def send_reminder_mail(self, force_send=True): template_id = self.env.ref("my_module.email_template_quantity_reminder") if template_id: template_id.send_mail(self.id, force_send=force_send, email_values={"email_to": "test@gmail.com"},) return True
3. PDF报表模板
<template id="report_quantity_notifier"> <t t-call="web.html_container"> <div class="page"> <table border="1"> <thead> <tr> <th><strong>Article</strong></th> <th><strong>Emplacement</strong></th> <th><strong>Qty Alert</strong></th> <th><strong>Qty disponible</strong></th> </tr> </thead> <tbody> <tr style="font-size:20px" t-foreach="docs" t-as="doc"> <td><span t-field="doc.product_id"/></td> <td><span t-field="doc.location_id"/></td> <td><span t-field="doc.product_min_qty"/></td> <td><span t-field="doc.qty_on_hand"/></td> <td></td> </tr> </tbody> </table> </div> </t> </template> <record id="quantity_report" model="ir.actions.report"> <field name="name">Quantity</field> <field name="model">stock.warehouse.orderpoint</field> <field name="report_type">qweb-pdf</field> <field name="report_name">my_module.report_quantity_notifier</field> <field name="report_file">my_module.report_quantity_notifier</field> <field name="binding_model_id" ref="stock.model_stock_warehouse_orderpoint"/> <field name="binding_type">report</field> </record>
解决方案
1. 修改Cron任务逻辑
将循环单条发送改为调用批量发送方法,移除不必要的手动提交:
<record id="ir_cron_auto_send_mail_quantity_notifier" model="ir.cron"> <field name="name">Quantity Notifier</field> <field name="model_id" ref="stock.model_stock_warehouse_orderpoint"/> <field name="state">code</field> <field name="code"> try: env['stock.warehouse.orderpoint'].send_batch_reminder_mail() except Exception as e: pass </field> <field name="active" eval="True"/> <field name="user_id" ref="base.user_root"/> <field name='interval_number'>1</field> <field name='interval_type'>days</field> <field name="numbercall">-1</field> <field name="doall" eval="False"/> </record>
2. 添加批量发送方法
在模型中新增批量处理方法,生成包含所有记录的PDF并作为附件发送:
import base64 from odoo import models, api class StockWarehouseOrderpoint(models.Model): _inherit = "stock.warehouse.orderpoint" def send_reminder_mail(self, force_send=True): # 保留原有单条发送方法(如无需可删除) template_id = self.env.ref("my_module.email_template_quantity_reminder") if template_id: template_id.send_mail(self.id, force_send=force_send, email_values={"email_to": "test@gmail.com"},) return True def send_batch_reminder_mail(self, force_send=True): # 获取所有库存预警记录(可添加筛选条件,如 qty_on_hand <= product_min_qty) orderpoints = self.search([]) if not orderpoints: return True # 生成PDF报表 report_action = self.env.ref('my_module.quantity_report').sudo() pdf_content, _ = report_action.render_qweb_pdf(orderpoints.ids) # 创建邮件附件 attachment = self.env['ir.attachment'].create({ 'name': '库存预警报表.pdf', 'type': 'binary', 'datas': base64.b64encode(pdf_content), 'store_fname': '库存预警报表.pdf', 'res_model': 'stock.warehouse.orderpoint', 'res_id': orderpoints[0].id if orderpoints else False, 'mimetype': 'application/pdf' }) # 方式一:使用邮件模板发送(需创建对应批量模板) template_id = self.env.ref("my_module.email_template_quantity_reminder_batch") if template_id: template_id.send_mail( orderpoints[0].id, force_send=force_send, email_values={ "email_to": "test@gmail.com", "attachment_ids": [(6, 0, [attachment.id])] } ) # 方式二:直接创建邮件发送(无需模板) # mail_values = { # 'subject': '库存预警报表', # 'body_html': '<p>您好,附件是最新的库存预警报表,请查收。</p>', # 'email_to': 'test@gmail.com', # 'attachment_ids': [(6, 0, [attachment.id])], # } # self.env['mail.mail'].create(mail_values).send() return True
3. 创建批量邮件模板(可选)
如果使用邮件模板发送,新增对应模板:
<template id="email_template_quantity_reminder_batch"> <t t-call="mail.mail_template"> <t t-set="subject">库存预警报表</t> <t t-set="body"> <p>您好,附件是最新的库存预警报表,请查收。</p> </t> </t> </template>
内容的提问来源于stack exchange,提问作者Ing
相关产品推荐
相关产品推荐

