先说结论
Odoo 里的工单依赖,不是“界面上画一条箭头”这么轻。
它至少同时影响三件事:
- 哪些工单默认可以并行开始
- 哪些工单会进入
blocked/ready - 排程时后续工单从什么时候开始算
一句话记:
Operation 依赖先定义在 BOM 上,MO 确认后会复制成 Work Order 依赖;真正阻塞现场执行的是 Work Order 这一层。
为什么很多人会误解“依赖”
因为很多制造系统里的 routing 默认就是线性的:
- 第一步做完
- 第二步再做
- 第三步再做
于是大家容易以为 Odoo 也只是“按 sequence 一个接一个”。
但源码不是这么设计的。
在 mrp.bom 上,官方给了 allow_operation_dependencies;在 mrp.routing.workcenter 上,给了:
blocked_by_operation_idsneeded_by_operation_ids
这说明 Odoo 想表达的不是“自然顺序”,而是可显式建模的工艺依赖图。
如果你开启了依赖功能但没有具体配置,帮助文本里其实已经点明:
勾选后,如果什么都不填,Odoo 会假定所有 operation 都可以同时开始。
这点特别容易被忽略。
Operation 依赖是怎么落到 Work Order 上的
BOM 上的依赖只是模板。
真正执行时,系统会在 MO 确认后,把 operation 级别的依赖映射到 work order 级别。
在 mrp.production 里可以看到:
allow_workorder_dependencies = self.bom_id.allow_operation_dependencies- 然后根据
operation_id.blocked_by_operation_ids去给工单写入blocked_by_workorder_ids
这意味着:
- 设计层先在 BOM 上定义依赖
- 执行层再在具体 MO 上生成对应工单依赖
- 后续状态判断、数量传递、排程冲突,都基于工单依赖运转
所以别把 operation dependency 当成纯说明文字,它会真的进入执行模型。
为什么有的工单会是 blocked,有的却直接 ready
mrp.workorder 里有一段很关键的计算:_compute_qty_ready()。
它不是简单判断“前序 done 了没”,而是在算:
当前工单,最多有多少数量已经被前序工单放行,可以开始处理。
源码逻辑大意是:
- 如果没有任何
blocked_by_workorder_ids,那本工单可处理数量就是剩余数量 - 如果有前置工单,就看前置工单的
qty_produced + qty_reported_from_previous_wo - 当前工单能开的数量,取这些前置可交付数量里的最小值
这背后的业务含义很强:
阻塞不是只看状态,还看“前面到底放过来多少可接续数量”。
所以在部分生产、分批流转、多道工序交接时,阻塞关系才会显得特别真实。
为什么依赖还会影响排程
在 mrp.workorder._plan_workorder() 里,系统会先看所有 blocked_by_workorder_ids。
逻辑非常直接:
- 先递归规划前序工单
- 再把当前工单的
date_start至少推到前序工单的date_finished之后 - 然后再结合 work center 日历、替代工位和空档计算最优时间
这说明依赖关系不是只影响按钮能不能点,它还会直接进入计划起止时间的计算。
所以你看到某个工单“明明有空工位却还没排上”,不一定是排程算法有问题,很可能是前置工单时间链把它卡住了。
Odoo 为什么还要专门防循环依赖
在 operation 和 workorder 两层,官方都加了约束:
_check_no_cyclic_dependencies()- 报错文案是
You cannot create cyclic dependency.
这说明 Odoo 把依赖图当真了。
因为一旦出现循环:
- A 等 B
- B 又等 A
那排程和状态就都没法正确收敛。
所以这不是“体验优化”,而是系统模型必须保证是无环图。
实战里最常见的 4 个误区
1. 以为不开依赖功能也会自动严格串行
不一定。
不开显式依赖时,系统更像是走默认顺序;开了依赖功能但不填关系时,Odoo 反而可能允许并行。
2. 把依赖理解成“前序 done 才能开始”
实际源码里还牵涉 qty_ready,也就是数量级放行。
3. 只在 BOM 上看依赖,不看工单实例
真正执行阻塞发生在 mrp.workorder 这一层。
4. 以为排程只看工位日历
依赖链本身就会推迟计划开始时间。
什么时候该开依赖,什么时候别乱开
适合开启的场景:
- 多工序可部分并行,但又有明确前置约束
- 半成品要先从某工序放行,下一工序才能接
- 现场需要按工艺真实关系排程,而不是只按 sequence 排序
不适合乱开的场景:
- 本来就是简单单线流程
- 团队没有维护依赖图的能力
- 现场数据录入本来就不稳定
因为依赖一旦建起来,排程、状态和数量交接都会更严格,配置质量就很关键。
一句话记忆法
Odoo 的工单依赖不是注释,而是执行约束:它同时决定谁先开工、能开多少、以及什么时候能排进去。
DISCUSSION
评论区