采购税映射

Odoo 采购税为什么有时和供应商税不一样:supplier_taxes、fiscal position 与采购行税映射讲透

很多人以为采购行税就是产品上的 supplier_taxes 原样带下来。实际上 Odoo 还会先按公司过滤,再经过 fiscal position 的 map_tax 映射,所以结果常常和肉眼预期不同。

采购
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 6 阅读

先说结论

Odoo 采购行上的税,并不是简单地把产品 supplier_taxes_id 复制下来。

/home/ubuntu/odoo-temp/addons/purchase/models/purchase_order_line.py 里,_compute_tax_id() 的逻辑很明确:

  1. 先拿产品的 supplier_taxes_id
  2. 先按公司做 _filter_taxes_by_company(...)
  3. 再通过 fiscal position 执行 map_tax(...)
  4. 最终结果才写到采购行 tax_ids

所以:

采购税 = 供应商税基础集合 × 公司过滤 × fiscal position 映射,而不是产品税字段原样照搬。


为什么“产品税”和“采购行税”常常不一样

因为这两者本来就不处在同一层。

产品上的 supplier_taxes_id

它更像:

  • 这个商品从采购视角看,默认可能适用哪些进项税
  • 一种“候选基础集”

采购行上的 tax_ids

它更像:

  • 这张采购单、这个公司、这个供应商语境下,最终真正要用的税

一旦你有多公司、多地区、税映射场景,这两者不完全相同才是常态。


源码链路:先过滤公司,再映射 fiscal position

_compute_tax_id() 里有两步特别关键。

第一步:_filter_taxes_by_company(line.company_id)

这一步解决的是“同一个产品上可能挂了跨公司税”的问题。

如果不先过滤公司,一个多公司环境里的产品税定义很容易串台。

所以 Odoo 不会盲信产品税配置,而是先问:

  • 当前采购行属于哪个公司
  • 当前公司下哪些税才有资格参与后续计算

第二步:fpos.map_tax(taxes)

在得到公司可用税后,Odoo 再通过 fiscal position 做税映射。

这一步解决的是:

  • 特定供应商
  • 特定国家 / 地区
  • 特定税务位置

下,默认税是否要替换成另一套税。

所以你看到采购行税和产品税不一致,第一反应不该是“系统算错了”,而应该是:

是不是 fiscal position 正在刻意改税。


fiscal position 不是只在销售侧重要

很多顾问对 fiscal position 的直觉来自销售和开票,但采购里它同样很关键。

purchase.order 上,fiscal_position_id 会根据供应商去取默认值;而采购行算税时,又继续引用这个 fiscal position。

换句话说:

  • 单头决定采购单的税务语境
  • 行上根据这个语境完成具体税落地

这就是为什么采购税问题,常常不能只看产品卡片。


价格含税 / 不含税的“错觉”也常从这里来

采购行价格看起来不对,很多人会先怀疑汇率或价目。其实税映射本身就能制造非常强的“价格错觉”。

因为一旦 tax_ids 变了,后续:

  • 含税 / 不含税换算
  • 采购行显示金额
  • Vendor Bill 上的税表达

都会跟着变化。

所以有时你以为是“取价不对”,本质上却是“取到的税不是你脑子里那套税”。


新手最容易忽略的排查顺序

如果采购行税不对,建议按这个顺序查:

  1. 产品 supplier_taxes_id 是什么
  2. 这些税里哪些属于当前公司
  3. 采购单 fiscal_position_id 是什么
  4. fiscal position 把哪些税映射成了哪些税
  5. 最终采购行 tax_ids 是什么

这个顺序比直接盯采购行一格格点来点去高效得多。


和已有会计税文章的边界

这篇不是在讲会计凭证层如何落税,也不是讲 fiscal position 的全景概念,而是专门聚焦:

  • 采购单行如何从产品默认税走到最终 tax_ids

它回答的是采购顾问和实施同学最常见的一句抱怨:

“为什么这张 PO 上的税和产品上配置的不一样?”


一句话记忆

在 Odoo 采购里,产品税只是起点;真正落到采购行上的税,是公司过滤和 fiscal position 映射后的结果。

DISCUSSION

评论区

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