很多团队第一次打开制造单概览,会以为它只是把“组件、工单、成品、副产品”排成一张更好看的单据。
但 Odoo 企业版这里做的事情,远比“信息聚合”更重:它在尝试回答一个管理上很难的问题——这张制造单今天到底花了多少钱,和原本以为会花多少钱,差在哪里,差异该怎么解释。
这篇文章主要参考:
addons/mrp/report/mrp_report_mo_overview.pyenterprise/mrp_workorder/report/mrp_report_mo_overview.py
一、MO Overview 不是静态页面,而是一套解释引擎
基础报表 report.mrp.report_mo_overview 的入口是 get_report_values() / _get_report_values(),真正核心在 _get_report_data()。
这一步会先把整张制造单拆成几层:
- 组件数据:
_get_components_data() - 工序数据:
_get_operations_data() - 副产品数据:
_get_byproducts_data() - 汇总行:
_get_mo_summary() - 附加分析:
_get_report_extra_lines()、_get_cost_breakdown_data()
所以它不是“前端把几个 One2many 列出来”,而是后台先构建一份解释结构,再交给 HTML/PDF 展示。
这也是为什么同一张概览既能支持车间现场看明细,也能支持财务或生产经理看单位成本、差异颜色和副产品分摊:它本质上是一份结构化的制造解释数据,而不是普通表单。
二、基础层先算三套口径:MO Cost、BoM Cost、Real Cost
在 _get_report_data() 里,Odoo 先从组件和工序中汇总三类成本:
mo_cost:当前制造单视角下“应该计入”的成本bom_cost:按 BoM 与工艺定义推导出来的理论结构成本real_cost:生产已经实际发生后的真实成本
然后它还会补齐一个很容易被忽略的边界:当前制造单并不一定完整覆盖 BoM 结构。
比如:
- 某些 BoM 组件还没真正生成 move
- 某些工序不在当前 workorder 集合里
- kit 或子结构要额外展开
所以源码会把缺失的组件、缺失的工序也纳入理论口径,避免管理层看到一张“只统计了现存记录、却以为自己看见完整成本”的假报表。
换句话说,MO Overview 不是只忠于数据库里“已经发生的记录”,它也会忠于工艺定义里的“本来应该存在的结构”。
三、企业版真正加重的地方,是把人工成本单独解释出来
企业版扩展发生在 enterprise/mrp_workorder/report/mrp_report_mo_overview.py 的 _get_finished_operation_data()。
这里最关键的设计,不是简单多算一点钱,而是把人工成本从“工序费用的一部分”拆成了可解释的行项目。
它分两种场景:
1)还没有足够实际记录时,用估算值补位
如果 workorder._should_estimate_cost() 为真,系统不会等真实工时齐全才展示,而是直接用:
duration_expectedemployee_costs_hour或工作中心小时人工成本
计算估算人工费。
这意味着报表在制造尚未完全闭环时,也能先给一个“当前最可信”的解释口径。对现场管理来说,这很重要:你不能要求生产主管等到所有记录完美无缺,再去判断这张单有没有跑偏。
2)有真实员工轨迹时,按员工与费率分组回放
如果工单已经有 time_ids,企业版就会按:
employee_idemployee_cost
分组,把每一段实际工时折算成独立的 operation line。
于是你在报表里看到的,就不再只是“焊接工序 2.5 小时”,而更接近:
- 哪个员工做了哪道工序
- 持续了多久
- 当时按哪个小时人工费率计价
- 理论成本和实际成本差异是红是绿
这一步把 MO Overview 从“制造结构报表”推进成了“制造执行解释报表”。
四、颜色装饰不是 UI 小技巧,而是在表达偏差方向
源码里大量使用 _get_comparison_decorator(),根据 expected 与 current 的比较结果返回 danger / success / False。
看上去只是一个颜色样式,实际上它在告诉你:
- 当前实际是否高于预期
- 当前制造单估算是否已经偏离 BoM 理论
- 某道工序或某个汇总口径是否值得追查
这比纯数字更适合现场沟通。
车间主管不一定会盯着每一列金额,但他会立刻看见:
- 哪个工序红了
- 总成本红了还是绿了
- 偏差来自组件还是工序
所以 decorator 不是视觉装饰,而是偏差诊断的第一层语义。
五、副产品不是附注,而是会反向改变主成品成本解释
很多系统里的副产品只体现在库存结果上:产出了什么,数量是多少。
Odoo 的 MO Overview 不是这样。
在 _get_cost_breakdown_data() 里,如果制造单完成且存在副产品 move,系统会根据 cost_share:
- 把组件成本和工序成本拆到不同产物上
- 先汇总每个副产品分走多少总成本
- 再反推主产品剩余保留多少成本
- 最后生成按产品展示的单位成本 breakdown
这件事的管理意义很大。
因为当企业同时产出主产品和副产品时,管理层真正想问的是:
- 主产品单位成本为什么降了/升了
- 是因为人工效率变化,还是副产品分摊比例变化
- 同一张制造单里,成本究竟落到了谁身上
如果没有这层分摊解释,副产品会让报表看起来“结果对、口径乱”。
六、为什么这张报表值得看,而不只是 ERP 自带附件
MO Overview 的价值,不在于把制造数据集中展示,而在于它把三种经常被混淆的东西拆开了:
- 理论结构:BoM 和工艺本来定义了什么
- 执行过程:组件、工单、员工时间实际发生了什么
- 成本解释:这些差异最后如何影响主产品和副产品
这也是为什么企业版会额外补入员工工时与人工费率:对管理层而言,“实际成本为什么和 BoM 不同”必须能被解释到可追责、可复盘的层级。
结论
Odoo 企业版的制造单概览,不是一张把工单和耗料拼在一起的打印页。
它真正做的是:用一套统一报表,把组件成本、工序时间、员工人工费、副产品分摊和偏差提示压成同一种解释语言。
如果你把它只当“生产单详情页”,就会低估它;它其实更接近一张轻量级的制造复盘报表。
DISCUSSION
评论区