先说结论
在 Odoo 里,下面三件事都可能让库存数量变化:
- scrap
- return picking
- inventory adjustment
但它们表达的业务事实完全不同。
最实用的区分方式是:
- scrap:货失去继续使用资格,要退出正常库存流
- return picking:之前那笔已完成的收 / 发货要沿着反向物流关系回退
- inventory adjustment:系统记录和现实盘点不一致,要把账面纠正到现实
所以这三者不是三个“都能改数”的按钮,而是三种不同的库存语义。
为什么 scrap 和 return 最容易被混
因为两者都可能让某批货“不再留在原来的地方”。
但它们要回答的问题不同:
- scrap 回答的是:这批货还值不值得继续参与正常流转?
- return 回答的是:之前那次完成的流动,要不要正式走一笔逆向流?
换句话说:
- scrap 更像“货坏了 / 不能用了”
- return 更像“原业务动作要反向走回来”
这两个动作对后续追溯、补货、下游 move 关系的意义完全不同。
为什么 return picking 不是“换个方向的 scrap”
stock.return.picking 很值得看。
它做的几件事特别能说明问题:
- 只允许对 done picking 发起 return
- 会先对相关下游 move 做
_do_unreserve() - 会复制出新的 picking
- 新 move 会带上原始关系,如
return_id、origin_returned_move_id - 新 picking 再走
action_confirm()、action_assign()
这说明 return 的本质不是简单减库存,而是:
围绕一笔已经完成的物流事实,再建立一笔正式的逆向物流事实。
所以 return 强调的是“反向业务链仍然成立”,而不是“我只想让数字改回来”。
为什么 inventory adjustment 也不是“最通用的修正入口”
stock.quant._apply_inventory() 的设计非常直白:
- 它比较
inventory_quantity和当前 quant.quantity 的差值 - 然后自动创建库存 move
- 让 quant 最终匹配盘点结果
这说明 inventory adjustment 真正在做的是:
把系统账面纠正为盘点时确认的现实状态。
它不关心原业务动作到底是哪一张销售单、采购单、退货单。
它关心的是:
- 现实里现在是 8
- 系统里记成了 10
- 那就生成修正动作把它调成 8
所以 adjustment 解决的是账实不符,而不是逆向履约。
为什么 scrap 也不是“轻量版 inventory adjustment”
stock.scrap.action_validate() 里会先检查可用量,然后走 do_scrap()。
它的语义中心是:
- 当前库存里有这批货
- 这批货现在要被转进 scrap / inventory usage 方向
- 原因是它不再适合作为正常库存继续流转
注意这里的重点不是“盘点差了多少”,而是“货本身状态变坏了”。
这也是为什么 traceability 里 scrap 会被单独识别成专门节点,而不是被视作普通盘点修正。
三者最核心的区别,不是方向,而是“解释权”
如果把三者都只看成“库存增减”,你会觉得它们差不多。
但从业务解释权来看,它们其实各自回答不同问题:
scrap
为什么货离开了正常库存?
- 因为坏了、过期了、损耗了、不能再用
return
为什么货又走回来了?
- 因为之前那次已完成收 / 发货需要正式反向处理
inventory adjustment
为什么账面变了?
- 因为盘点发现系统认知和现实不一致
这三套解释会直接影响:
- traceability
- 下游 move 关系
- 报表口径
- 责任归因
- 运维排错
实战里怎么选
可以直接用这个判断顺序:
情况 1:货坏了、过期了、样品损耗了
优先用 scrap。
情况 2:客户退回、供应商回退、内部要把已完成流动正式反向走一笔
优先用 return picking。
情况 3:盘点发现系统数量和现实数量不一致,但并不是要表达一笔明确逆向业务
优先用 inventory adjustment。
如果你选入口时脑子里问的是“哪个最快把数改对”,通常就已经在走偏。
正确问题应该是:
我现在到底想表达哪一种库存事实?
最容易踩的 5 个坑
1. 用 adjustment 去覆盖真实报废
这样会把损耗原因抹掉。
2. 用 scrap 去代替客户退货
这样会丢掉逆向业务链。
3. 用 return 去修盘点差异
这样会假装存在一笔并不真实的反向履约。
4. 只看数量结果,不看后续追溯语义
后面越查越乱。
5. 把三者都当成“库存修正按钮”
这是根本误区。
一句话记忆法
scrap 是“货不能再正常用”,return 是“已完成流动要正式反向走回来”,inventory adjustment 是“系统账面要校正到现实盘点”;三者都改数量,但说的是三种完全不同的库存事实。
理解这句话,你以后就不会再用“哪个顺手就点哪个”的方式处理库存异常了。
DISCUSSION
评论区