估值分录

Odoo 发票过账后,库存估值和会计分录是怎样连起来的?

很多人以为供应商发票一过账,库存估值就“顺手一起结算”了;也有人以为库存分录一定等发票。实际上,Odoo 把收货估值、库存分录、发票过账拆成了相互关联但不完全同步的链路。

会计 库存
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 15 阅读

先说结论

在 Odoo 里:

  • 收货校验 会触发库存 move 完成
  • 库存 move 完成 可能立刻生成库存会计分录
  • 供应商发票过账 又是另一条会计主线
  • 但发票价格会影响库存估值取值依据或后续差异理解

所以它们是:

强关联,但不等于同一个时点、同一个动作。

这就是为什么你有时觉得“收货一做账就出了”,有时又觉得“发票过账后才更像最终成本”。


第一层:库存分录并不是等发票按钮来触发

stock_account/models/stock_move.py 里,最关键的入口是 stock.move._action_done()

源码顺序很清楚:

  1. 先给 outgoing move 取当前成本
  2. 调用父类完成库存 move
  3. 对已完成的 incoming / dropship move 设值 _set_value()
  4. 调用 _create_account_move()
  5. 再做一些标准价 / analytic 的后续动作

这说明一个核心事实:

库存会计分录的直接触发点,是库存 move done,而不是供应商发票 action_post。

如果你把这两个入口混成一个,后面就会一直觉得系统行为“忽快忽慢”。


第二层:库存分录是怎么建出来的

同一个文件里的 _create_account_move() 更直接:

  • 先判断哪些 move 需要创建会计分录
  • 汇总会计分录行 aml_vals_list
  • 创建 account.move
  • 把新建的 account_move_id 回绑给 stock move
  • 最后直接 account_move._post()

注意最后这一步很关键:

库存分录不是只创建草稿,它会直接过账。

这也是为什么很多公司在自动估值场景里,会觉得“仓库一校验,账上立刻有动作”。

因为源码就是这么设计的。


第三层:那供应商发票过账到底参与了什么

account/models/account_move.py 里的 action_post(),本质上是在走发票/会计凭证自己的过账流程。

它会调用 _post(soft=False),把发票从 draft 推进到 posted。

这条线和库存 move done 不是同一条线。

所以发票过账本身并不是“替库存补做一次 _create_account_move()”。 它解决的是:

  • 供应商应付确认
  • 发票会计凭证过账
  • 发票价格正式进入已过账会计事实

它和库存估值有关,但不是同一个按钮干同一件事。


真正的连接点:估值取值会参考已过账发票

purchase_stock/models/stock_move.py 里最值得看的,是 _get_value_from_account_move()

这段逻辑会遍历采购行关联的 invoice_lines,但只取:

  • move_id.state == 'posted' 的发票行
  • 并按发票类型、数量、币种换算,计算可用于估值的 value

这意味着什么?

意味着在采购收货场景里,Odoo 对“这个库存 move 应该按什么价值理解”时,会优先参考 已经过账的供应商发票事实

如果还没有足够的已过账发票数据,它又会退回 _get_value_from_quotation(),也就是按采购报价/采购单价格估值。

这才是“发票和库存估值连起来”的真正位置。

不是按钮共享,而是 估值依据共享


为什么你会感觉“有时同步,有时分步”

因为系统面对的是两个不同问题:

问题 1:货物现在是否已经真实入库?

这个由收货校验回答。

问题 2:这批货现在该按什么会计价值理解?

这个要看:

  • 当前成本方法
  • 当前 move 类型
  • 有没有已过账供应商发票
  • 已过账发票覆盖了多少数量

所以在业务感觉上就会出现两种体验:

体验 A:看起来同步

收货一校验,库存分录立刻出来,且价格和你预期差不多。

体验 B:看起来分步

收货先按采购价/临时值入账,后来发票过账后你再看,就会发现解释口径、差异理解或后续估值来源更完整了。

这不是系统摇摆,而是它把 物流事实财务事实 分层处理了。


最容易误解的 4 句话

1. “库存分录是发票过账时才做的”

不对。自动估值场景下,很多库存分录在 move done 时就做了。

2. “发票过账和库存估值完全无关”

也不对。已过账发票会参与估值依据。

3. “只要发票价格变了,收货时那张库存凭证一定同步重做”

别这么想。系统的联动点是估值逻辑与会计事实,不是简单的“删旧重建”。

4. “收货和发票必须同一天做,账才对”

系统设计本来就允许物流事实和财务事实分时出现。


实战理解:把它拆成三层最不容易乱

我会把这条链记成三层:

第一层:物流完成

  • 收货单校验
  • stock.move._action_done()
  • 库存数量变化

第二层:库存会计入账

  • _set_value()
  • _create_account_move()
  • 库存 journal entry 过账

第三层:采购发票事实

  • vendor bill action_post()
  • 价格与数量成为正式已过账会计事实
  • 为估值解释和后续口径提供依据

三层分开看,整个系统就很清楚。


最后一句话

Odoo 不是把“收货”“库存估值”“发票过账”揉成一个按钮完成,而是故意把它们拆成:

  • 物流执行
  • 库存估值入账
  • 发票会计确认

三条彼此关联的链。

所以看到它们有时同步、有时分步,不要先怀疑系统; 先问自己:

你现在看到的,到底是物流事实,还是财务事实,还是估值依据正在从采购价过渡到已过账发票价。

DISCUSSION

评论区

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