物料消耗

Odoo 物料消耗为什么会“允许、警告、阻塞”:Consumption Methods、手工领料与关单边界讲透

Odoo 的物料消耗策略不是一个小开关,它会决定 MO 关单时怎么比对理论用量、实际领料以及额外行。本文把 consumption methods 讲清楚。

Odoo 开发 制造 库存
进阶 开发者 2 分钟阅读
0 评论 0 点赞 0 收藏 6 阅读

先说结论

Odoo 里的 consumption method,不是在说“能不能改数量”这么简单。

它真正控制的是:

  • BOM 理论用量和实际消耗不一致时,系统怎么处理
  • MO 在 Mark as Done 前要不要弹警告
  • 哪些情况下普通用户能关单,哪些情况下必须经理介入

一句话记:

consumption 不是领料录入方式,而是制造完工前对“理论消耗 vs 实际消耗”的容忍策略。


三种策略到底分别是什么意思

mrp.bommrp.production 上,官方给了三档:

  • flexible:Allowed
  • warning:Allowed with warning
  • strict:Blocked

帮助文本已经写得很清楚:

  • Allowed:允许偏离 BOM 用量
  • Allowed with warning:允许偏离,但关单时要汇总提醒差异
  • Blocked:不符合 BOM 消耗时,只有经理才能关制造单

也就是说,这不是前端展示文案差异,而是完工控制强度的分级


Odoo 到底怎么判断“消耗不一致”

关键逻辑在 mrp.production._get_consumption_issues()

这段源码做了两步比对:

第一步:先算理论应耗

系统会通过 _get_moves_raw_values() 重新推一次 BOM 对应的原料行,然后按照:

  • 当前 qty_producing
  • BOM 数量比例
  • UoM 换算

把每个产品理论上应该消耗多少算出来。

注意这里不是死拿原单初始数量,而是会按本次实际要完工的数量缩放。

第二步:再算实际已领

系统再去遍历 move_raw_ids,取每个 move 的 _get_picked_quantity()

这里很关键:

  • 看的是 picked / 实际登记的消耗
  • 不是只看原始需求数量
  • 对 BOM 里不存在但你额外领掉的料,也会单独记成 issue

所以 Odoo 比较的是:

理论应该耗多少,和你这次真正登记消耗了多少。

不是“move 上原始 demand 改没改”。


为什么 flexible 看起来“最宽松”,但也不是完全没规则

源码里如果 order.consumption == 'flexible'_get_consumption_issues() 会直接跳过这单。

这意味着:

  • 系统不会因为偏耗去拦你
  • 也不会弹 consumption warning wizard

但这不代表所有数据都自动合理。

flexible 只是说:

系统允许业务现实先落地,再由人自己承担偏耗解释。

所以它更适合:

  • 工艺波动较大
  • 现场按实际投料
  • BOM 只做参考,不做强控制

不适合:

  • 成本核算高度敏感
  • 差异必须闭环追责
  • 需要严格按配方发料的行业

warning 真正的价值是什么

很多团队觉得 warning 很鸡肋:既然最后还是能关,那弹窗有什么意义?

但从源码看,warning 的价值在于:

  • 它不会阻断正常业务
  • 但会在完工收口前把差异正式暴露出来

_action_generate_consumption_wizard() 会把这些差异整理成行:

  • 哪张 MO
  • 哪个产品
  • 实际消耗多少
  • 理论应该多少
  • 当前 consumption 策略是什么

这非常适合大多数制造团队。

因为现实里最常见的问题不是“永远不允许偏差”,而是:

允许偏差,但不允许悄悄偏。

warning 正好对应这种管理方式。


strict 为什么不是“绝对不能多耗少耗”

严格来说,strict 更接近:

出现偏差时,普通制造用户不能自己把这张 MO 当作没事发生一样关掉。

帮助文本里说的是“only a manager can close a manufacturing order when the BoM consumption is not respected”。

所以它不是数学上禁止偏差,而是组织权限上提高了门槛。

这很符合真实工厂管理:

  • 偏差可能 unavoidable
  • 但必须由更高权限的人确认

因此 strict 更像强审批控制,而不是物理禁止。


Manual Consumption 为什么经常把人绕晕

stock.move 上,Odoo 还有 manual_consumption

帮助文本写得很直接:

  • 开启后,这个组件的消耗要手工登记
  • 如果没开启,但你手工改了组件消耗,Odoo 也会认为它进入 manual consumption 语义

很多人会把它和 consumption method 混成一件事。

其实它们是两层:

  • consumption method:偏耗时怎么判
  • manual consumption:消耗是系统自动带,还是要人工明确登记

这就是为什么源码里一边有 _determine_is_manual_consumption(),另一边又有 _get_consumption_issues()

一个管录入方式,一个管差异校验方式


为什么 extra lines 也会被抓出来

源码里有个很容易被忽略的分支:

如果某个实际消耗的产品,根本不在理论 BOM 结果里,但你确实 picked 了非零数量,系统也会把它记成 issue。

这意味着 Odoo 并不是只检查“原有 BOM 行数量对不对”,它还检查:

你有没有多领了 BOM 根本没定义的料。

这对排查现场临时替料、错料、补投临时件特别有用。


实战里最容易踩的 5 个坑

1. 把 consumption method 当成“自动扣料方式”

不是。它主要管的是完工前差异容忍。

2. 以为 warning 只是烦人的弹窗

它本质上是差异正式曝光机制。

3. 以为 strict 代表系统绝对不让偏耗发生

更准确地说,是普通用户不能无视偏差直接收口。

4. 把 manual consumption 和 consumption method 混为一谈

一个管录入,一个管校验。

5. 只盯 BOM 原有行,不看额外领料行

额外 picked 的产品一样会触发 issue。


该怎么选

经验上可以这样理解:

  • flexible:现场自由度最高,适合高波动环境
  • warning:最平衡,适合大多数制造团队
  • strict:适合强配方、强成本、强审计行业

如果团队还没建立稳定的现场数据纪律,别一上来就 strict。

否则最后常见结果不是“更规范”,而是大家想办法绕系统。


一句话记忆法

Odoo 的 consumption method 管的不是怎么领料,而是制造关单前,系统对实际消耗偏离 BOM 的容忍与升级处理方式。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。