分包收货估值

Odoo 分包收货为什么像在供应商库位里先消耗再成品入账:receipt、供料消耗与估值链路讲透

很多团队以为分包收货只是做一张 incoming picking。实际上 Odoo 会把供应商位置当作制造发生地,把供料消耗和成品收货绑进同一条分包制造链。

制造
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

先说结论

Odoo 的分包收货不是“供应商把成品送来,仓库做个收货”这么简单。

mrp_subcontracting 里,只要一张入库 move 被识别成分包收货,系统就会做三件关键事:

  • 把来源库位改成分包商库位(property_stock_subcontractor
  • 为这张 receipt move 生成或绑定一张分包制造单
  • 让原本预先补到供应商位置的组件,按分包 BOM 在那边被“消耗”

所以从业务语义上看,Odoo 想表达的是:

分包商并不是一个普通供应商收货来源,而是一个发生制造活动的外部生产位置。

为什么很多人会把分包收货看错

因为界面上最显眼的是一张 incoming picking

但源码里真正关键的是 stock.move._action_confirm() 里这段判断:

  • 这是不是从 supplier 到 internal 的 move
  • 它是不是已经来自别的 production
  • 能不能找到 bom_type='subcontract' 的 BOM

一旦成立,Odoo 会把 move 标记为 is_subcontract=True,并把 location_id 改成分包商库存位置。也就是说,这张 move 虽然在 UI 上是“收货”,但在库存语义上已经变成:

  • 成品从分包商位置流入你自己的仓库
  • 而不是从一个普通供应商黑箱里直接流入

这正是后面估值和追溯能成立的前提。

真正的主链路:receipt move 如何变成分包制造

源码里最核心的两段在:

  • mrp_subcontracting/models/stock_move.py
  • mrp_subcontracting/models/stock_picking.py

链路可以概括成这样:

  1. 收货 move confirm 时,_get_subcontract_bom() 找到分包 BOM
  2. move 被重写来源库位,并重新分配预留
  3. picking 调用 _subcontracted_produce()
  4. 系统生成 mrp.production,其中: - subcontractor_id 指向分包商 - location_src_id / location_dest_id 都是分包商位置 - picking_type_id 使用仓库的 subcontracting_type_id
  5. MO confirm 后,BOM 对应的原料 move 在分包商位置发生消耗
  6. 当 picking _action_done(),系统再把关联的分包 MO button_mark_done()

这意味着 receipt done 不是简单结束,而是同时把外部制造活动一起完结。

“Consume supplied components” 到底发生在哪

很多顾问会把“补料给分包商”和“分包商实际消耗了这些料”混成一件事。

其实不是。

补料

补料通常是 resupply picking,把组件先送到供应商的 subcontractor location。

消耗

真正的消耗发生在分包 MO 的原料 move 上。也就是说:

  • resupply 解决的是组件在哪里
  • subcontract MO 解决的是组件为什么被扣掉

这也是为什么源码里分包 receipt 会主动生成 MO;没有这张 MO,系统只有“料送过去了”,却没有“按哪张 BOM 被消耗了”的制造语义。

估值为什么依赖这条链

估值不是只看最终那张入库 move 的金额。

如果你把分包商位置理解错,常见误判有两个:

  • 误以为组件在补料时就应该直接变成成品成本
  • 误以为分包收货只是普通采购入库,不需要制造追溯

实际上,Odoo 要保留的是一条完整链路:

  • 组件先从自有库存转到分包商位置
  • 在分包 MO 上被消耗
  • 成品再从分包商位置收回

这样你才能回答这些关键问题:

  • 这批成品到底用了哪些供料
  • 若分包收货数量变化,关联 MO 如何同步拆分或调量
  • lot/serial 场景下,每个成品批次对应哪组组件消耗

源码里的 _sync_subcontracting_productions() 正是在维护这种同步关系,尤其是在 tracked 产品、拆分收货和 backorder 下。

最容易踩坑的 4 个误区

1. 以为分包 receipt 只是采购入库

不是。它背后还要生成或绑定 subcontract MO。

2. 以为组件在送去分包商时就完成了“制造消耗”

不是。那只是库存位置转移,真正的消耗由 MO 原料 move 承担。

3. 以为供应商位置只是报表上的中转点

不是。它是整条分包估值与追溯链的制造来源位置。

4. 以为分包收货数量改了,只要改 receipt 就行

不行。Odoo 还要同步调整关联的分包 MO,tracked 产品甚至可能按 lot 拆出多张 MO。

排错顺序

如果分包成品数量、消耗或估值看起来不对,建议按这个顺序查:

  1. receipt move 是否真的被识别为 is_subcontract
  2. partner 上是否配置了 property_stock_subcontractor
  3. 对应产品是否能找到 bom_type='subcontract' 的 BOM
  4. resupply 组件是否已正确到达分包商位置
  5. picking done 后,关联 subcontract MO 是否也被 mark done
  6. tracked 场景下 lot 与 move line 数量是否触发了 MO 拆分

一句话记忆法

Odoo 的分包收货,不是“从供应商收回来”,而是“从分包商制造位置把已经消耗过供料的成品收回来”。

DISCUSSION

评论区

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