Odoo 11 实现单按钮同时触发RFQ创建与采购申请状态更新
单按钮触发双操作的实现方案
核心原则是不改动原有两个功能的独立可用状态,仅在RFQ创建流程的末尾追加状态更新动作,既满足联动需求,也避免破坏原有功能的兼容性
具体落地步骤
- 找到
create RFQ功能的核心执行入口
该功能属于Odoo的临时向导流程,核心逻辑写在purchase.request.line.make.purchase.order模型的最终生成方法(一般命名为make_purchase_order)中,是用户点击向导确认按钮后真正执行的代码块。 - 回溯关联的采购请求主记录
向导本身不会直接存储采购请求主记录的关联关系,需要遍历向导中承载的待处理行,通过行关联的purchase.request.line字段,向上找到对应的purchase.request主记录,对收集到的主记录做去重处理,避免重复触发状态更新造成性能浪费。 - 复用原有状态修改的逻辑
不要硬写类似request.write({'state': 'sent'})的字段赋值代码,直接调用原Sent按钮绑定的状态更新方法(通常是action_send这类自定义方法),可以完整复用原逻辑里的前置校验、聊天记录留痕、通知推送等附加能力,不会遗漏原有功能。 - 严格控制代码执行顺序
状态更新的逻辑必须放在原有RFQ生成逻辑执行完成之后,绝对不能提前执行——否则一旦RFQ创建失败,会出现采购请求已被标记为已发送的异常数据状态。
扩展代码参考
通过模型继承的方式扩展原有逻辑,不需要修改原生模块的代码,方便后续模块升级维护:
from odoo import models class PurchaseRequestLineMakePurchaseOrder(models.TransientModel): _inherit = 'purchase.request.line.make.purchase.order' def make_purchase_order(self): # 先完整执行原有RFQ生成的全流程逻辑 default_result = super().make_purchase_order() # 收集去重后的关联采购请求 target_requests = self.env['purchase.request'] for line in self.item_ids: target_requests |= line.purchase_request_line_id.request_id target_requests = target_requests.exists() # 触发原有已发送状态的更新逻辑 if target_requests: target_requests.action_send() return default_result
常见踩坑提醒
- 所有操作保持在同一数据库事务范围内,任意步骤执行失败时自动全量回滚,从机制上保障数据一致性
- 不建议直接删除原有的独立
Sent按钮,保留原有操作路径,减少对现有用户使用习惯的干扰 - 如果原有
action_send方法存在前置校验(比如要求采购请求下所有未处理行都生成RFQ后才可标记为已发送),该逻辑会自动生效,不会出现状态提前跳转的问题 - 如果不需要再显示原有的
Sent按钮,可以在自定义的视图层把按钮隐藏,不需要删除底层方法,避免其他业务流程调用时出现报错
内容的提问来源于stack exchange,提问作者Elhagag Abdalla
相关产品推荐
相关产品推荐

