为什么先学这 4 个模型
很多人刚看 Odoo 库存时会觉得乱,不是代码太难,而是脑子里没有一张清晰地图。
最核心的 4 个模型就是:
stock.pickingstock.movestock.move.linestock.quant
只要你先把这 4 个搞明白,后面看出库、入库、调拨、预留、批次、序列号,都会顺很多。
一句话先记住
stock.picking:一整张单据stock.move:这张单据里的“计划搬运需求”stock.move.line:这次实际从哪里拿、拿了多少stock.quant:系统眼里“库存现在实际在哪儿”
你可以把它想成:
picking= 任务单move= 任务项move.line= 执行明细quant= 当前库存事实
1. stock.picking:单据容器
stock.picking 更像是一个业务容器。
比如:
- 一个出库单
- 一个入库单
- 一个内部调拨单
这些在 Odoo 里通常都会落成一条 stock.picking。
它负责的事情主要是:
- 单据编号
- 操作类型(收货 / 发货 / 内部调拨)
- 源单据关联
- 整体状态
- 把多条 move 组织在一起
所以它像“外壳”或者“单据头”。
2. stock.move:计划层
stock.move 是库存流转的计划层。
例如销售单确认后,系统可能生成一条 move:
- 产品 A
- 从
WH/Stock - 到
Customers - 计划数量 10
注意,这时它表达的是:
“应该搬 10 个”
它还没精确到:
- 从哪个货架拿
- 是哪个 lot
- 是哪个 package
所以 move 是“应该发生什么”,不是“已经怎么执行”。
3. stock.move.line:执行层
stock.move.line 是实际执行明细。
它会具体到:
- 从哪个库位拿
- 哪个批次
- 哪个包裹
- 哪个货主
- 实际拿了多少
这也是为什么一个 move 经常会拆成多条 move line。
例如:
- 同一个产品要出 10 个
- A 库位有 6 个
- B 库位有 4 个
那一条 move,最后可能就变成两条 move line:
- line1:A 库位,6
- line2:B 库位,4
4. stock.quant:库存事实层
stock.quant 才是 Odoo 真正用来表示“库存现在长什么样”的模型。
它记录的是某种库存事实组合,例如:
- 产品 P
- 在
WH/Stock - 批次
LOT-A - 包裹
PACK-01 - 货主为空
- 当前数量 20
所以 quant 不是单据,不是任务,而是:
“此时此刻,这批库存真实存在于哪里”
当系统预留库存时,本质上就是去 quant 里找可用货。
这 4 个模型怎么串起来
最常见链路是这样的:
- 销售单确认
- 生成
stock.picking - picking 下面生成若干
stock.move - 分配库存时,move 去
stock.quant里找货 - 找到后生成若干
stock.move.line - 验证单据时,按 move line 扣减 quant
所以它们之间的关系不是平级,而是有层次的:
- picking 组织 move
- move 生成 / 驱动 move line
- move line 消耗 quant
新手最容易混淆的两组关系
move 和 move.line 的区别
很多人会把它们当一回事。
其实不是:
move= 计划需求move.line= 实际执行明细
move.line 和 quant 的区别
也经常混。
move.line= 本次操作做了什么quant= 系统当前库存事实是什么
一句话:
- line 是“动作记录”
- quant 是“库存现状”
学库存源码时的建议顺序
如果你准备继续深入,我建议按下面顺序学:
- 先搞懂这 4 个模型
- 再看
stock.picking.action_assign() - 再看
stock.move._action_assign() - 再看
stock.quant._gather()/_get_reserve_quantity() - 最后再看 lot、serial、package、owner 这些细分维度
这样不容易一上来就被细节淹没。
总结
Odoo 库存模块里这 4 个核心模型可以这样理解:
stock.picking管单据stock.move管计划stock.move.line管执行stock.quant管库存事实
如果这四层关系你脑子里清楚了,后面学出库、入库、预留、调拨,基本都会顺起来。
DISCUSSION
评论区