先说结论
在 Odoo 里,cash basis tax 不是“付款之后再补一张税凭证”这么简单。
它真正表达的是:
发票先把税额挂在过渡位置,等真实付款发生并形成核销后,再按“本次结清比例”把税额从 transition account 转到正式税务口径。
所以它的核心触发器不是“你点了收款”,而是:
- 发票里确实有
tax_exigibility = 'on_payment'的税 - 发票上存在应收 / 应付 term line
- 付款和发票之间真的形成了
account.partial.reconcile
这就是为什么 cash basis tax 本质上是跟着核销走,不是跟着按钮走。
源码在表达什么
从 /home/ubuntu/odoo-temp/addons/account/models/account_move.py 的 _collect_tax_cash_basis_values() 可以看到,Odoo 会先把一张 move 中需要处理的行分成两类:
tax:本身就是 on payment 的税行base:底层业务行带着 on payment 的税,需要后续按比例转税
而 /home/ubuntu/odoo-temp/addons/account/models/account_partial_reconcile.py 的 _collect_tax_cash_basis_values() 则继续往下做第二层工作:
- 识别这次 partial reconcile 对应的金额
- 计算这次付款覆盖了原单多少比例
- 判断要按哪个公司币还是外币来算比例
- 推出本次 cash basis move 应该落多少税、多少 base
这说明官方不是“付款一次就全额转税”,而是:
每发生一次核销,就按这次核销覆盖的比例去搬动对应的税务金额。
所以 partial payment 才是 cash basis tax 的关键场景,而不是例外场景。
为什么一定要有 transition account
account.tax 和 res.company 里都能看到 cash basis 相关配置,尤其是过渡账户与专门 journal。
这套设计是在解决一个现实问题:
- 发票发生时,业务事实已经存在
- 但税务上还不应当立刻进入正式申报口径
如果系统直接把税额打进正式税账户,后面就没法优雅地表达“税先记住了,但暂时还不 exigible”。
所以 Odoo 采用的是两段式:
- 发票先把税挂到 transition account
- 核销发生后,再通过 cash basis entry 把应转部分搬到正式税账户
这也是为什么配置不全时,源码会直接报错:没有 cash basis journal,系统根本不知道后续那张“税务转正”的凭证该落到哪里。
多币种为什么更容易让人看晕
源码里有一段很关键:如果发票和付款不是同一外币,或者汇率口径不同,系统会重新算 payment_rate。
这说明 cash basis tax 不只是一个税问题,它还同时在处理:
- 本次付款覆盖比例
- 公司币金额
- 外币金额
- 付款日汇率
所以你会看到一个典型现象:
- 发票时点汇率是一套
- 付款时点汇率又是一套
- 现金制税 move 与汇率差额 move 可能同时出现,但它们不是同一件事
一句话记:
cash basis 在决定“这次该转多少税”,exchange difference 在决定“同一笔业务因为汇率变化还差多少币值”。
别把这两张凭证混成一张。
新手最容易误解的 4 件事
1. 以为 cash basis tax 由发票过账触发
不准确。发票只是把后续可转税的基础准备好,真正触发通常发生在核销。
2. 以为一次付款就一定把税全转完
不对。部分收款 / 部分付款下,系统按比例转。
3. 以为 cash basis move 只看税行
不对。源码里明确区分 tax 与 base 两类 to-process lines。
4. 以为 cash basis 和多币种互不影响
错。源码直接把 payment_rate、公司币、外币一起纳入计算。
实战排查顺序
如果用户说“为什么现金制税没生成 / 生成金额不对”,建议按这个顺序查:
- 税的
tax_exigibility是否真的是on_payment - 公司是否配置了 cash basis journal 与 transition account
- 发票上是否真的有 receivable / payable term line
- 付款和发票之间是否形成了 partial/full reconcile
- 是否存在多币种、部分付款或退款互抵场景
一句话记忆法
Odoo 的 cash basis tax 不是“付款后补税”,而是“在核销发生时,按本次结清比例,把税从过渡账户转进正式税务口径”。
DISCUSSION
评论区