先说结论
在 Odoo 里,putaway 不是“给产品预设一个固定库位”这么简单。
系统真正要回答的问题是:
这次进入某个大库位的货,到底应该继续被分发到哪个更具体的目标子库位。
为了回答这个问题,Odoo 会同时看:
- 产品或产品分类
- package / packaging 对应的 package type
- 目标区域下各个子库位当前已经放了多少
- 这次是按数量放,还是按包裹数量放
- 某些规则还会参考“上次用过的位置”或 storage category
所以 putaway 的本质不是“默认值”,而是目的库位决策器。
为什么很多人会把 putaway 想浅
因为在界面上,它看起来很像一张静态规则表:
- 某产品 → 某库位
- 某分类 → 某区域
于是很容易误以为:
- 收货进来时,系统只是在这张表里查一下映射
但源码里的 _get_putaway_strategy() 明显不是这么轻。
它做的事情更接近:
- 先确定本次适用哪些 putaway rule
- 再看是按包裹容量还是按产品数量评估位置
- 汇总候选子库位当前已有库存与待入库量
- 最后选出最合适的目标库位
这就说明 putaway 不是静态标签,而是带现场状态感知的分配逻辑。
location_id 不是终点,putaway 才决定“最终落点”
这一点非常关键。
很多库存流程里,move 或 move line 已经有了一个 location_dest_id,大家就以为目的库位已经定死。
但在 Odoo 里,这个目的地有时只是“大方向”,比如:
- 收到仓库 Input
- 收到某个上架区域
- 收到一个 view/location 父节点
接下来系统还可能再跑一次 putaway,把货继续分发到真正执行层的子库位。
所以你会看到:
- 表面上单据目的地是一个区域
- 实际 move line 最终落到另一个更细的库位
这不是系统乱改,而是 putaway 正在把“区域目的地”细化成“执行目的地”。
Odoo 为什么会同时看产品、包裹和数量
因为仓库不是所有货都靠同一种维度分配。
如果是散货或按产品放置
系统更关心:
- 当前子库位里这个产品已经有多少
- 这次再放进去会不会超规则
- 哪个子库位更符合存储类别或分配逻辑
如果是整包或按 package type 放置
系统更关心:
- 这个 package 的类型是什么
- 候选库位已承载了多少同类 package
- 哪个位置还能继续接这种包
源码里可以看到,带 package 时会走接近“按包计数”的思路;不带 package 时,则更像“按产品数量聚合”的思路。
也就是说:
Odoo 并不是只在给产品找位子,而是在给“这次进入仓内的库存单元”找位子。
这个库存单元,有时是数量,有时是包。
为什么 package type 会直接影响 putaway
这是很多人第一次读源码时会觉得“原来这么深”的地方。
因为 putaway 规则并不只支持“哪个产品去哪里”,它还能表达:
- 某种包裹类型去哪里
- 某类包更适合哪个区域
- 同种 package type 在不同子库位怎么分配
这背后的业务含义很强:
- 托盘去托盘区
- 小箱去货架格口
- 特定包装规格走特定通道
所以如果你的仓库是按包装单位组织,而不是只按 SKU 数量组织,那么 package type 就不是附属信息,而是 putaway 的关键输入。
_get_putaway_strategy() 真正在避免什么
它最核心的目标之一,是避免“规则上看起来对,但现场越放越乱”。
比如如果系统只做静态映射,就会出现:
- 所有同类货都被塞进第一个规则命中的库位
- 明明其他子库位更空,却永远不被使用
- 按包存放的区域被按数量逻辑错误挤爆
所以它会先把候选子库位当前情况读出来,再决定这次放哪。
也正因为如此,putaway 不只是配置题,还是状态题。
你改一条规则,也许不会立刻看出问题;但随着库位占用变化,分配结果会慢慢偏掉。
为什么 putaway 常常让人觉得“系统没按我想的放”
常见原因有 4 类。
1. 你以为系统只按产品规则匹配
实际上它还可能受 package type 影响。
2. 你看的是大区域,不是最终子库位
move 的目的地和 move line 最终落点不一定是同一级。
3. 你忽略了当前占用量
今天和昨天同一产品进仓,结果不同,不一定是 bug,可能只是候选库位当前容量不同。
4. 你把 putaway 和 removal 混了
- putaway:进来后放哪里
- removal:出去时先拿哪里
两者都和库位有关,但方向完全相反。
实战排查时该怎么看
如果你怀疑 putaway 失灵,不要只看一张规则表。
至少要一起看:
- 目标父库位下有哪些子库位
- putaway rule 匹配的是产品、分类还是 package type
- 当前候选子库位的库存或包裹占用情况
- 这次 move line 是否带 package / packaging 信息
- 最终写入的是 move 的目标库位,还是 move line 被重新定向后的目标库位
很多所谓“上架策略没生效”,最后其实是:
- 生效了,但你看错层级
- 生效了,但被 package type 改写
- 生效了,只是候选库位实时状态让结果变了
一句话记忆法
在 Odoo 里,putaway 不是“给产品配默认库位”,而是系统根据产品、包裹类型和候选库位当前占用情况,对这次入仓库存单元做的一次实时落位决策。
DISCUSSION
评论区