先说结论
如果说 stock.quant 更像在回答“库存数量现在还有多少”,那 stock.valuation.layer 更像在回答:
这些库存价值是从哪一批流进来的、还剩多少价值没有被后续流出吃掉。
所以 SVL 不是数量表,而是价值轨迹表。
为什么只看数量不够
数量能告诉你仓里还有 10 个。
但它回答不了:
- 这 10 个对应的是哪批成本
- 还有多少历史价值没被消费
- 后续 FIFO / 平均成本该怎么继续衔接
也就是说,数量解决“还有没有货”,SVL 解决“这些货还剩多少账面价值可承接”。
remaining_qty 和 remaining_value 真正在表达什么
从 stock_account 里的源码可以看到,stock.move 上会计算:
remaining_qtyremaining_value
这两个字段的核心语义是:
- remaining_qty:这条入向价值记录里,还有多少数量没被后续消耗掉
- remaining_value:与这部分剩余数量对应的剩余价值
你可以把它想成:
一笔库存进入系统后,不是瞬间“结束”,而是会在后续出库中被逐步消耗。
为什么这对 FIFO 特别重要
FIFO 的本质就是:
- 先吃掉更早的那批价值层
- 吃掉多少数量,就跟着带走对应多少价值
那系统要做到这一点,就必须知道每一层还剩多少可被继续消耗。
所以 remaining_qty / remaining_value 并不是报表装饰,而是 FIFO 价值流转的关键坐标。
_set_value() 为什么很关键
在 stock_account.models.stock_move 里,_set_value() 是理解价值更新的关键函数之一。
从源码注释和调用路径可以看出,它不是简单“改个字段”,而是在尝试为 move 建立更准确的价值来源:
- 来自采购
- 来自生产
- 来自退货
- 来自标准价
- 来自会计修正
这说明 Odoo 在做的不是“随便记一个库存金额”,而是在努力把价值追溯到更真实的来源。
为什么你会觉得库存价值很绕
因为 Odoo 这块不是只处理一个总金额,而是在处理:
- 分层进入
- 分层剩余
- 分层消耗
- 后续修正
所以它天然比“仓里还有几件货”复杂很多。
你看到的不是一张静态库存表,而是一条持续流动的价值链。
一句话记忆法
quant盯数量,valuation layer盯价值;remaining_qty和remaining_value说的是这层价值还剩多少没被后续流出吃掉。
DISCUSSION
评论区