[FIX] point_of_sale: use compute_all properly for taxes computation

- Use the tax tags returned by the compute_all for the base lines instead of recomputing them separately

Splitting the computation caused inconsistent computation in some cases between the base and tax lines (one could select the refund distribution, while the other selected the invoice one).

- Pass the is_refund parameter to True if either the quantity or the price is negative (but not both)

Those negative lines should correspond to refund repartition (double-checked with the Belgian tax report in v12).

OPW 2351412

closes odoo/odoo#60925

X-original-commit: 7827581b208b464638a91044462d0bc497025326
Signed-off-by: Laurent Smet <smetl@users.noreply.github.com>
Signed-off-by: oco-odoo <oco-odoo@users.noreply.github.com>
This commit is contained in:
oco-odoo
2020-10-28 17:01:03 +00:00
parent ef5e1a914e
commit 2aef5cc5bd
+9 -9
View File
@@ -441,6 +441,7 @@ class PosSession(models.Model):
-1 if line['amount'] < 0 else 1,
# for taxes
tuple((tax['id'], tax['account_id'], tax['tax_repartition_line_id']) for tax in line['taxes']),
line['base_tags'],
)
sales[sale_key] = self._update_amounts(sales[sale_key], {'amount': line['amount']}, line['date_order'])
# Combine tax lines
@@ -715,11 +716,13 @@ class PosSession(models.Model):
# The 'is_refund' parameter is used to compute the tax tags. Ultimately, the tags are part
# of the key used for summing taxes. Since the POS UI doesn't support the tags, inconsistencies
# may arise in 'Round Globally'.
check_refund = lambda x: x.qty * x.price_unit < 0
if self.company_id.tax_calculation_rounding_method == 'round_globally':
is_refund = all(line.qty < 0 for line in order_line.order_id.lines)
is_refund = all(check_refund(line) for line in order_line.order_id.lines)
else:
is_refund = order_line.qty < 0
taxes = tax_ids.compute_all(price_unit=price, quantity=abs(order_line.qty), currency=self.currency_id, is_refund=is_refund).get('taxes', [])
is_refund = check_refund(order_line)
tax_data = tax_ids.compute_all(price_unit=price, quantity=abs(order_line.qty), currency=self.currency_id, is_refund=is_refund)
taxes = tax_data['taxes']
date_order = order_line.order_id.date_order
taxes = [{'date_order': date_order, **tax} for tax in taxes]
return {
@@ -727,6 +730,7 @@ class PosSession(models.Model):
'income_account_id': get_income_account(order_line).id,
'amount': order_line.price_subtotal,
'taxes': taxes,
'base_tags': tuple(tax_data['base_tags']),
}
def _get_rounding_difference_vals(self, amount, amount_converted):
@@ -769,23 +773,19 @@ class PosSession(models.Model):
return self._credit_amounts(partial_vals, amount, amount_converted)
def _get_sale_vals(self, key, amount, amount_converted):
account_id, sign, tax_keys = key
account_id, sign, tax_keys, base_tag_ids = key
tax_ids = set(tax[0] for tax in tax_keys)
applied_taxes = self.env['account.tax'].browse(tax_ids)
title = 'Sales' if sign == 1 else 'Refund'
name = '%s untaxed' % title
if applied_taxes:
name = '%s with %s' % (title, ', '.join([tax.name for tax in applied_taxes]))
base_tags = applied_taxes\
.mapped('invoice_repartition_line_ids' if sign == 1 else 'refund_repartition_line_ids')\
.filtered(lambda line: line.repartition_type == 'base')\
.tag_ids
partial_vals = {
'name': name,
'account_id': account_id,
'move_id': self.move_id.id,
'tax_ids': [(6, 0, tax_ids)],
'tax_tag_ids': [(6, 0, base_tags.ids)],
'tax_tag_ids': [(6, 0, base_tag_ids)],
}
return self._credit_amounts(partial_vals, amount, amount_converted)