You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 01:33:09