很多人第一次打开 Odoo 的 MO Overview,会把它当成一个“看起来比较完整的报表页”。
但如果你去读 addons/mrp/report/mrp_report_mo_overview.py 和对应的前端组件,就会发现它的定位远不止报表:它其实是一个 开工前 / 完工前的制造决策面板。它试图用一张树状视图回答四个问题:
- 组件现在够不够;
- 不够的话上游补货在哪里;
- 工序大概要花多少钱、多久;
- 如果有副产品,成本最后怎么分掉。
这也是为什么很多团队一旦理解了这页,就不再把它当“可有可无的展示层”。
后端不是直接查表,而是在“组装一份制造故事”
get_report_values() / _get_report_values() 最终都落到 _get_report_data(production_id)。
这个方法的结构很清晰:
- 先拿组件数据
_get_components_data(); - 再拿工序数据
_get_operations_data(); - 先算一次初始成本汇总;
- 再补缺失组件、缺失工序带来的 BOM 成本;
- 然后处理副产品
_get_byproducts_data()和 summary; - 最后再生成 extra lines 与 cost breakdown。
也就是说,MO Overview 不是简单读出制造单现状,而是在构造一份“这张 MO 现在为什么是这个状态”的数据对象。
为什么它在开工前就能告诉你 Ready / Not Ready
很多人会疑惑:MO 还没开始,怎么总览页就能判断 readiness?
关键在 _format_state()。
这个方法在 MO 处于 draft / confirmed 且有 components 时,不直接展示记录原始 state,而是重新按组件可生产数量推一个自定义状态:
- 汇总每个组件需要多少;
- 看已保留数量和可自由使用数量;
- 按最短板反推当前 MO 理论上最多能做多少;
- 如果连 0 都做不了,就是 Not Ready。
这和单纯看某个字段完全不同。它是在把“库存可用性”翻译成“制造准备度”。
所以这页并不是被动展示,而是在帮计划员做预判。
为什么总览里会出现补货树,而不是只列原料行
前端 MoOverviewComponentsBlock 最有意思的地方,是它不是平铺组件,而是允许对每个组件继续展开 replenishments,然后在补货节点下面再继续递归渲染组件块。
这意味着它的心智模型不是:
- 组件 A 缺;
- 组件 B 不缺;
而是:
- 组件 A 缺;
- 组件 A 的补货来自某张上游单据;
- 那张上游单据自己又需要哪些组件和工序。
这就是制造现场真正关心的“缺料深度”。只看当前 MO 缺什么,解决不了问题;看见它背后的补货链条,才知道问题卡在第几层。
工序块为什么和组件块分开
前端模板里,MoOverviewOperationsBlock 被单独折成一个块,而不是和组件混排。这是因为 Odoo 在概念上把工序看成另一类成本与产能对象。
在后端 summary 里,工序会贡献:
- MO Cost
- BoM Cost
- Real Cost
在已完工场景下,还会继续拆出:
- Total Cost of Operations
- Cost of Operations per unit
这说明 Odoo 不把工序当组件附件,而是把它当制造本身的第二条成本主线。你如果只盯原料成本,很容易低估排产、工位和人工波动的影响。
副产品为什么在这页尤其重要
很多系统会把副产品单独丢到别的报表里,但 Odoo 把它放进总览页,是因为 _get_byproducts_data() 和 _get_cost_breakdown_data() 会影响“这张 MO 的成本究竟属于谁”。
源码里有一个关键变量:remaining_cost_share。
逻辑非常直白:
- 如果副产品声明了 cost share,就要拿走一部分总成本;
- 主产品只保留剩余部分;
- 最终 cost breakdown 按产品维度给出单位组件成本、单位工序成本和单位总成本。
这意味着 MO Overview 不是单纯告诉你“总共花了多少钱”,而是在告诉你“这笔制造成本最终怎么落到主产品和副产品身上”。
前后端为什么要做这么多显示选项
_include_pdf_specifics() 和前端模板里一堆 showReplenishments / showAvailabilities / showReceipts / showUnitCosts / showMoCosts / showBomCosts / showRealCosts 看上去很繁琐。
但这其实是在解决一个现实问题:不同角色看同一张 MO,需要的不是同一组列。
- 计划员更关心可用性和 receipt;
- 成本人员更关心 BOM / MO / Real cost;
- 现场主管可能只想看 readiness 和工序。
Odoo 没把这些人拆成多张页面,而是通过一个 Overview 数据结构配多组显示视角。这也是它比“静态报表”更像决策面板的原因。
对实施和开发的启发
1. 这页最适合做“异常聚合”,不适合做纯展示定制
如果你要加字段,优先想清楚它是不是帮助用户更快决策。MO Overview 的核心价值不是信息多,而是把决策相关信息放在一起。
2. 不要只改前端模板
很多人看见树表就先改 XML,但这页最关键的工作其实发生在 _get_report_data() 及其子方法。前端只是把已经结构化好的制造故事渲染出来。
3. 这页是理解 Odoo 制造成本观的捷径
它把 components、operations、byproducts 同时放在一张视图里,等于把 Odoo 对“制造成本由什么构成、为何偏差”的理解直接展开给你看。
一句话总结
MO Overview 真正厉害的地方,不是把制造数据堆在一页,而是把 准备度、补货链、工序成本、副产品分摊 这些原本分散的问题,压缩成一张能支持决策的制造总览。这页读懂了,很多制造实施讨论会一下子变得具体。
DISCUSSION
评论区