很多人处理税报结转,靠的是 Excel 里“把上期负数抄到下期”。企业版 account_reports 的 carryover 机制则更像一个可审计的数据通道:它不是把数字硬塞进下一期,而是把“结转事实”单独落成 external value,再由报表表达出来。
参考入口:
enterprise/account_reports/tests/test_tax_report_carryover.py
一、carryover 不是普通余额字段,而是 external expression 结果
测试里 _applied_carryover_balance 使用 engine='external',并在 return validate 后生成 account.report.external.value。这意味着 carryover 被视为“报告上下文输入”,而不是会计分录本身。
二、当前期可能显示 0,但不是没有值,而是被 carryover 吃掉了
测试显示:当期间结果应结转时,报表主列可能是 0,同时在 info_popup_data 里显示 carryover 金额。也就是说,前台看到 0 不代表没发生金额,而是金额被转移到 carryover 语义里表达。
三、下一期应用 carryover 时,也会显式展示 applied carryover
下一期间里,popup 同时显示 carryover 与 applied_carryover。这对审计很重要:你不仅知道有多少期末余额待转,也知道本期实际引用了多少历史结转。
四、tax unit 口径和单公司口径不一定相同
test_tax_report_carry_over_tax_unit 很值得细看:在 tax unit 下,汇总结果可能没有 carryover popup;但切到单公司视角时,其中一家公司仍可能有 carryover。因为税务单元的汇总口径会把成员公司结果相抵后再判断是否需要结转。
五、实战建议
- 看到报表为 0 时,先点 info popup,不要急着判定没数据。
- 税务单元与单公司视角要分开核对 carryover,不要互相套口径。
- 若要自定义税报,优先沿用 external value 思路,不要把 carryover 硬写死进表达式结果。
六、结论
Odoo 的 carryover 机制,解决的不是“把数带过去”,而是“把结转事实以可审计、可解释的方式带过去”。external value 和 popup 正是这层设计的关键。
DISCUSSION
评论区