会计源码

Odoo 资产模型为什么决定的远不止“折旧几年”:asset model、depreciation board 重算与 modification 边界讲透

很多人把 Odoo asset model 理解成固定资产模板,但真正影响实施成败的,是它如何决定后续折旧板、哪些字段变更会触发重算、以及什么时候必须先冲回未来分录再修改。

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

先说结论

在 Odoo 里,asset model 不是“帮你少填几个字段”的模板工具。

它真正决定的是:

资产一旦进入运行态,后续折旧板怎么生成、哪些参数改动会触发 future move 重算、哪些情况下必须先 reverse 再修改。

所以 asset model 的价值,不是录入便利,而是会计时间表的初始宪法


model 真正给资产注入了什么

account_asset.py 里的 _onchange_model_id() 很直接,会把 model 上的一整组参数灌进资产:

  • method
  • method_number
  • method_period
  • method_progress_factor
  • prorata_computation_type
  • analytic_distribution
  • 折旧/费用/资产科目
  • journal_id

这意味着 asset model 不只是“默认值集合”,而是把一条资产的:

  • 计算方法
  • 会计科目
  • 分析归因
  • 记账日记账

一起定下来。


为什么折旧板不是静态表,而是可重算结果

很多财务系统把折旧表当成导入后就固定的计划。

Odoo 不是这个思路。

compute_depreciation_board() 里,系统会:

  1. 先删掉未来 draft move
  2. 根据当前资产状态调用 _recompute_board()
  3. 重新生成未来折旧分录
  4. 对应运行中的资产,把该过账的分录过账

这意味着折旧板不是独立主数据,而是:

资产参数在某一时点下的计算结果。

所以当参数变化时,板本来就应该重算。


哪些字段变了,会让旧板失去一致性

源码里 onchange_consistent_board() 已经明示:当这些字段变动时,原有折旧板会被清空重算:

  • original_value
  • salvage_value
  • acquisition_date
  • method
  • method_progress_factor
  • method_period
  • method_number
  • prorata_computation_type
  • already_depreciated_amount_import
  • prorata_date

这组字段很像资产计算引擎的“核心输入”。

换句话说,只要你改的不是展示性信息,而是这些真正影响金额/期间分配的参数,旧板就不再可信。


折旧板如何决定每一期金额

_compute_board_amount()_get_linear_amount()_get_end_period_date()_get_delta_days() 共同决定每期怎么摊。

核心不是“总额 ÷ 期数”这么简单,而是同时考虑:

  • linear / degressive / degressive_then_linear
  • 月度还是年度 period
  • 是否 daily computation
  • fiscal year 边界
  • prorata 起点
  • 剩余寿命与剩余金额

这也是为什么两个表面上都叫“5 年折旧”的资产,若:

  • acquisition date 不同
  • prorata 规则不同
  • monthly / yearly 不同

生成的折旧板可能明显不同。


modification 真正改的是未来,不是历史

asset.modify wizard 的提示文案非常值得看。

它反复强调:

  • 到修改日为止,应先补一条截至该日的折旧
  • future entries 会被 recompute
  • 某些情况下要先 reverse 未来已过账分录

这表明 Odoo 的会计边界是:

  • 历史已发生的折旧优先保留
  • 未来尚未发生的折旧可以重算

这比“整张折旧表重新生成”严格得多,也更符合审计要求。


为什么“未来已过账分录”是最硬的边界

asset.modify.create() 里直接限制:

如果未来日期已经存在 posted 且未被 reversal 的 depreciation move,就不能直接修改,要先 reverse。

原因非常朴素:

  • future posted move 已经是正式会计事实
  • 你不能一边承认它已入账,一边又假装它没存在过

所以修改资产并不是 UI 行为,而是会计状态变更。

一旦跨过 posted 边界,就必须显式处理冲回。


gross increase / re-evaluation 为什么又会拉出 parent-child 边界

源码里对子资产、gross increase、parent asset 有单独处理。

尤其在 degressive_then_linear 场景下,子资产会参考 parent 的剩余曲线,避免重估后整条折旧逻辑断裂。

这说明 Odoo 不把 re-evaluation 理解成“把原资产原地改数”,而更接近:

  • 保留原主线
  • 用额外对象承接增值/变更影响
  • 再一起决定未来折旧节奏

这也是很多人第一次接触资产重估时会觉得“为什么系统突然多出一条资产”的原因。


资产模型配置里最该谨慎的地方

1. method 与 method_period 的组合

它决定的是确认节奏,不只是显示方式。

2. prorata_computation_type

它直接改变“天数怎么数”。

3. 科目与 journal

这会影响未来整条折旧链落到哪里记账。

4. analytic distribution

如果你希望折旧持续落到正确分析维度,这不是可有可无的字段。


建议的调试顺序

当资产折旧板不对时,建议按这个顺序查:

  1. 当前资产到底是手工建的,还是由 model 自动灌值
  2. method / period / prorata 参数是否与政策一致
  3. 未来 draft move 是旧板残留,还是已经按新参数删掉重建
  4. 是否存在 future posted move 卡住 modification
  5. 是否涉及 gross increase / parent-child 资产联动

一句话记忆

在 Odoo 里,asset model 决定的不是“模板长什么样”,而是“未来折旧板按什么会计边界被计算、重算和限制修改”。

DISCUSSION

评论区

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