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

Odoo14模型自定义方法如何返回变量实现弹窗展示

问题原因

Odoo 14中自定义方法返回的窗口动作不符合框架规范,是弹窗无法正常加载的核心原因:

  • res_model配置为不存在的my.model,框架找不到对应模型资源直接加载失败
  • views参数格式错误,合法格式为[(视图ID, 视图类型)],直接传入统计变量列表无法被框架识别,也无法完成值传递
  • Odoo标准窗口动作默认从绑定模型拉取记录渲染视图,没有配套的传值、视图匹配逻辑,自然无法展示你统计的发送数值

另外代码存在两个小问题:

  • 日志初始化逻辑每次调用方法都会重复添加文件处理器,多次触发会导致同一条日志被重复写入多次
  • 遍历记录的逻辑可以简化,按钮触发的方法中self本身就是选中的销售订单记录集,不需要从context取active_ids再二次browse,直接遍历self即可减少不必要的数据库查询

修复方案

提供两种可直接运行的实现方式,按需选择即可:

方案1:轻量实现(无需新建额外文件)

直接使用Odoo内置的客户端弹窗动作,不需要新增模型、视图文件,仅修改原方法代码即可。
如果需要居中模态弹窗展示结果,直接替换原方法末尾的return部分,同时修复日志问题即可,完整修改后的方法代码如下:

from odoo import models
import logging

class SaleOrder(models.Model):
    _inherit = "sale.order"
    _description = "Sales order custom proforma multiple"

    def send_multiple_profoma_invoice(self):
        template_id = self._find_mail_template()

        logger = logging.getLogger("output")
        if not logger.handlers:
            logger.setLevel(logging.DEBUG)
            fh = logging.FileHandler('/mnt/extra-addons/output.log')
            fh.setLevel(logging.DEBUG)
            logger.addHandler(fh)

        mail_sent, mail_err = 0, 0

        for sale_order in self:
            try:
                sale_order.with_context(
                    force_send=True
                ).message_post_with_template(
                    template_id, composition_mode='comment',
                    email_layout_xmlid="mail.mail_notification_paynow"
                )
                mail_sent += 1
                logger.info(f'The email is sent {str(sale_order)}')

            except Exception as e:
                mail_err += 1
                logger.error(e.with_traceback(e.__traceback__))

        # 模态弹窗返回
        message = f"""
        <div class="p-3">
            <div class="mb-2"><i class="fa fa-check-circle text-success mr-2"/> 发送成功数量:{mail_sent}</div>
            <div><i class="fa fa-times-circle text-danger mr-2"/> 发送失败数量:{mail_err}</div>
        </div>
        """
        return {
            'type': 'ir.actions.client',
            'tag': 'dialog',
            'params': {
                'title': '批量形式发票发送结果',
                '$content': message,
                'size': 'small',
                'buttons': [
                    {
                        'text': '确定',
                        'classes': 'btn btn-primary',
                        'close': True
                    }
                ]
            }
        }

如果只需要右上角常驻通知提示,可以把弹窗返回部分替换为以下代码:

return {
    'type': 'ir.actions.client',
    'tag': 'display_notification',
    'params': {
        'title': '批量形式发票发送结果',
        'message': f'发送成功:{mail_sent} 封 | 发送失败:{mail_err} 封',
        'sticky': True,
        'type': 'success' if mail_err == 0 else 'warning',
    }
}

方案2:标准向导实现(适合后续扩展功能)

如果后续需要在结果页增加失败记录跳转、重试发送等功能,使用Odoo标准的瞬态模型(TransientModel)实现向导弹窗:

  1. 在模块下新建wizard目录,创建send_result_wizard.py:
from odoo import models, fields

class SendProformaResultWizard(models.TransientModel):
    _name = 'send.proforma.result.wizard'
    _description = '批量发送形式发票结果'

    mail_sent = fields.Integer(string='发送成功数量', readonly=True)
    mail_err = fields.Integer(string='发送失败数量', readonly=True)
  1. 在wizard目录下新建send_result_wizard_views.xml,添加表单视图:
<odoo>
    <record id="view_send_proforma_result_wizard_form" model="ir.ui.view">
        <field name="name">send.proforma.result.wizard.form</field>
        <field name="model">send.proforma.result.wizard</field>
        <field name="arch" type="xml">
            <form string="发送结果">
                <group>
                    <field name="mail_sent"/>
                    <field name="mail_err"/>
                </group>
                <footer>
                    <button string="确定" class="btn-primary" special="cancel"/>
                </footer>
            </form>
        </field>
    </record>
</odoo>
  1. 修改原方法的返回逻辑,循环结束后创建向导记录并返回打开动作:
# 发送循环结束后添加
result_wizard = self.env['send.proforma.result.wizard'].create({
    'mail_sent': mail_sent,
    'mail_err': mail_err
})
return {
    'type': 'ir.actions.act_window',
    'name': '批量形式发票发送结果',
    'view_mode': 'form',
    'res_model': 'send.proforma.result.wizard',
    'res_id': result_wizard.id,
    'view_id': self.env.ref('你的模块技术名.view_send_proforma_result_wizard_form').id,
    'target': 'new',
}

注意需要把代码里的你的模块技术名替换为实际模块的技术名称,同时将新建的wizard py文件加入模块__init__.py的导入列表,视图文件加入__manifest__.py的data列表后升级模块即可生效。


内容的提问来源于stack exchange,提问作者Elunemoon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 00:57:55