Odoo中sale.order的invoice_status字段onchange事件未正常触发求助
问题原因分析
你的@api.onchange('invoice_status')无法按预期触发的核心原因是:Odoo的@api.onchange仅响应客户端手动编辑字段的操作,而invoice_status是Odoo原生的计算字段——它的值由服务器端根据订单的发票、发货、订单行状态等自动计算更新,完全没有经过客户端的交互操作,因此不会触发仅由前端驱动的onchange事件。
解决方案
根据需求,提供三种可行的实现方式:
方式一:重写计算字段逻辑
直接继承invoice_status的计算方法,在原逻辑执行后附加你的操作:
import logging from odoo import api, fields, models, _ _logger = logging.getLogger(__name__) class SaleOrder(models.Model): _inherit = "sale.order" # 重写字段定义,保持与原字段一致的配置 invoice_status = fields.Selection( compute='_compute_invoice_status', store=True, readonly=True, selection=[ ('upselling', 'Upselling Opportunity'), ('invoiced', 'Fully Invoiced'), ('to invoice', 'To Invoice'), ('no', 'Nothing to Invoice') ] ) @api.depends('order_line.invoice_status', 'order_line.product_id') def _compute_invoice_status(self): # 先执行原生的计算逻辑 super()._compute_invoice_status() # 处理状态更新后的逻辑 for order in self: _logger.warning("Invoice status updated to: %s" % order.invoice_status)
方式二:重写write方法检测字段变更
通过重写write方法,在订单保存时检查invoice_status是否发生变化:
import logging from odoo import api, fields, models, _ _logger = logging.getLogger(__name__) class SaleOrder(models.Model): _inherit = "sale.order" def write(self, vals): # 记录修改前的状态 old_statuses = {order.id: order.invoice_status for order in self} # 执行原生的保存逻辑 result = super().write(vals) # 检查每个订单的状态是否变更 for order in self: if order.invoice_status != old_statuses[order.id]: _logger.warning("Invoice status changed for order %s: %s -> %s" % (order.name, old_statuses[order.id], order.invoice_status)) return result
方式三:后台自动化规则(无代码方案)
如果不想修改代码,可以在Odoo后台配置自动化规则:
- 进入设置 > 自动化 > 自动化规则
- 创建新规则,模型选择
销售订单 - 触发条件设置为字段值变更,字段选择
发票状态 - 动作选择执行Python代码,填入你的日志逻辑或其他需要的操作
注意事项
- 确保
invoice_status字段的store=True(Odoo原生已设置),否则计算字段不会存储到数据库,无法通过write方法检测到变更 - 如果需要状态变更时立即执行逻辑,方式一的计算方法重写会更及时,因为计算字段的更新会在依赖字段变化时自动触发
内容的提问来源于stack exchange,提问作者Berdus
相关产品推荐
相关产品推荐

