先说结论
制造单上那几个看起来像交通灯的状态,不只是前台提醒。
Odoo 实际上在同时回答两个不同问题:
- 这张 MO 现在能不能按 BOM 逻辑开工?
- 按当前组件在手量,理论上最多能做多少成品?
对应到源码里,就是:
reservation_state:MO readinesscomponents_availability / components_availability_state:组件供给预期production_capacity:当前库存条件下的可生产数量
一句话记:
可用性状态说的是“何时能做”,可生产数量说的是“最多能做多少”。
reservation_state 为什么不等于简单“有货/没货”
在 addons/mrp/models/mrp_production.py 里,reservation_state 被定义成制造单的 readiness,主要值有:
assigned:Readyconfirmed:Waitingwaiting:Waiting Another Operation
这说明 Odoo 并不是只在问“仓库有没有库存”,而是在问:
- 原料 move 的预留状态怎么样
- 是否还在等上游工序或其他操作
- 当前 BOM 配置下,这张单是否已经达到可开工状态
所以看到 Waiting Another Operation 时,不要本能去查库存数,因为问题可能不是缺料,而是链路上还有前序动作没完成。
components_availability 到底多表达了什么
更有意思的是 components_availability。
在 _compute_components_availability() 里,Odoo 不只看当下库存,还会强制计算原料 move 的:
forecast_availabilityforecast_expected_date
然后对每张制造单做判断:
如果有任一关键原料 forecast 数量不足
状态会直接变成:
Not Availablecomponents_availability_state = 'unavailable'
如果数量理论上够,但要等未来日期
系统会把最晚的 forecast_expected_date 取出来,显示成:
Exp 某日期
并进一步分成:
expected:预计会在开工日前到位late:预计到位时间比date_start还晚
这里的信息密度很高。
它不是只在说“缺不缺料”,而是在说:
- 现在不够
- 将来会够
- 但可能赶不上计划开工日
这就是为什么很多用户明明看到 forecast 最终会补上,界面却还是黄/红。因为 Odoo 关心的是对计划是否构成延误,不是只关心“总有一天会到”。
production_capacity 为什么是另一套逻辑
很多人以为有了 components availability,就不需要再看可生产数量。
其实两者不重复。
在 _compute_production_capacity() 里,Odoo 的算法很朴素:
- 先取所有需要真实库存约束的原料 move
- 过滤掉
consu这种消耗品 - 对每条原料算:当前
qty_available / unit_factor - 取所有原料里的最小值
- 最后和
product_qty比较,取较小者
这其实就是经典短板思路:
一张制造单最多能做多少,不看最富余的料,看最短缺的那条料。
举个最简单的例子:
- 做 1 台成品要 2 个壳体、4 颗螺丝、1 块板卡
- 现在壳体够 10 台,螺丝够 100 台,板卡只够 3 台
那 production_capacity 的答案就是 3,不是 10,也不是“反正最终会补货”。
为什么这三个字段要同时看
因为它们回答的是不同层级的问题:
reservation_state
偏执行层。
这张 MO 作为单据,现在处于 Ready、Waiting,还是还在等别的操作。
components_availability
偏计划层。
组件按 forecast 什么时候能齐,是否会晚于计划开工。
production_capacity
偏数量层。
不考虑未来 forecast,只按当前在手量,最多能产多少。
如果把这三件事混成一句“有货没货”,你在现场排查时就很容易走错路。
新手最容易误解的几个点
1)Expected 不等于已经可开工
Expected 的意思是系统预测会到,但现在还不是 Ready 的确定状态。
2)Late 不是说单据已经失败
Late 的意思是按当前 forecast,看起来会晚于计划时间。它是在提醒计划风险,不是给单据宣判死刑。
3)production_capacity 不看 forecast,只看当前在手
所以它经常比组件 forecast 看起来更“悲观”。这不是冲突,而是口径不同。
4)consu 物料不会像存货那样限制可生产数量
源码里专门过滤了 product_id.type == 'consu'。也就是说,可生产数量重点看的是真正受库存约束的组件。
实战里怎么用这些状态
如果你是生产计划或实施顾问,可以这样理解:
当 reservation_state 不对
先查预留、上游工序、move 状态,不要先盯采购预测。
当 components_availability_state = late
重点看最晚一条 forecast_expected_date 来自哪条原料 move。它往往才是真正拖期源头。
当 production_capacity 明显小于 product_qty
说明就算现在立刻开工,也只能做一部分,短板原料已经摆在那里了。
一条很实用的排错顺序
遇到“制造单为什么还不能做”时,建议这样查:
- 看
reservation_state,分清是库存预留问题还是等待前序问题 - 看
components_availability_state,分清是不够、预计可到、还是预计会晚 - 看
production_capacity,确认按当前在手量到底能做多少 - 再回头追是哪一条
move_raw_ids把结果拉坏了
这样你会比单纯看仓库 on hand 数字快很多。
最后总结
Odoo 没有把制造可用性粗暴简化成“有货 / 没货”。
它拆成了三层:
- readiness:现在这张单能不能进入执行
- forecast availability:组件什么时候齐,是否会晚
- production capacity:只按当前库存,最多能做多少
这套设计非常实用,因为制造现场真正需要的不是一个模糊判断,而是三种不同视角:
现在能不能做、未来什么时候能做、眼下最多能做多少。
把这三个概念分开,你读 Odoo 制造单界面的很多状态,就不会再觉得它只是几块颜色标签了。
DISCUSSION
评论区