从销售订单的数据误差看odoo15税率的计算逻辑

我的一个台湾客户前段时间发信息来说,销售单的汇总数据不对,总额比未含税金额和税额的总和多了1。

从图上看,两个订单行的未税金额合计没有问题,税额也对,那么这个奇怪的1是从哪里来的呢?

于是我们根据源码的指示找到了计算税额的方法。15.0这块的计算方法与14.0有了明显的差异,字段名由之前的三个分开的字段换成了一个新的字段——tax_totals_json。

1
2
3
4
5
6
7
8
9
10
11
12
@api.depends('order_line.tax_id', 'order_line.price_unit', 'amount_total', 'amount_untaxed')
def _compute_tax_totals_json(self):
def compute_taxes(order_line):
price = order_line.price_unit * (1 - (order_line.discount or 0.0) / 100.0)
order = order_line.order_id
return order_line.tax_id._origin.compute_all(price, order.currency_id, order_line.product_uom_qty, product=order_line.product_id, partner=order.partner_shipping_id)

account_move = self.env['account.move']
for order in self:
tax_lines_data = account_move._prepare_tax_lines_data_for_totals_from_object(order.order_line, compute_taxes)
tax_totals = account_move._get_tax_totals(order.partner_id, tax_lines_data, order.amount_total, order.amount_untaxed, order.currency_id)
order.tax_totals_json = json.dumps(tax_totals)

其中核心方法是account.tax对象的compute_all方法。

compute_all方法详解

compute_all方法的内容很长,涉及到的逻辑比较多,我们这里简要介绍一下其内部逻辑(仅适用于15.0版本,其他版本可能会有不同)

默认情况下,系统在计算税率的时候会先根据系统设置中的Account精度设置对每行进行计算,然后将每行的计算结果进行汇总,作为整单的汇总结果。但是如果公司设置中的tax_calculation_rounding_method参数被设置为round_globally,系统便会将精度提高5个点,让它看起来就跟先汇总结果再进行税额计算一样。

你的支持我的动力