[FIX] website_sale: harmonize tax computation
Standard `sale` tax flows rely on `_get_tax_included_price_unit`, whereas part of `website_sale` flows do, while another part relies on `_fix_tax_included_price_company`, which doesn't handle some advanced cases (fiscal position mapping of price_included taxes). This commit drops the use of `_fix_tax_included_price_company` in website_sale, to only use the newest API of `_get_tax_included_price_unit`, supposed to handle more cases. Also makes all taxes computation go through a single entry point, `_apply_taxes_to_price`, already used for `combination_info` logic (/shop/product), but not in `_get_sales_prices` (/shop page). opw-3700803 original commit : 662ea281515156a781ab68079d0123ea45ebf40f closes odoo/odoo#160198 Signed-off-by: Laurent Smet (las) <las@odoo.com> Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
This commit is contained in:
@@ -103,24 +103,13 @@ class Product(models.Model):
|
||||
|
||||
def _get_contextual_price_tax_selection(self):
|
||||
self.ensure_one()
|
||||
price = self._get_contextual_price()
|
||||
website = self.env['website'].get_current_website()
|
||||
fiscal_position_sudo = website.sudo().fiscal_position_id
|
||||
product_taxes = self.sudo().taxes_id.filtered(lambda x: x.company_id in self.env.company.parent_ids)
|
||||
if product_taxes:
|
||||
website = self.env['website'].get_current_website()
|
||||
fiscal_position = website.sudo().fiscal_position_id
|
||||
|
||||
price = self._get_tax_included_unit_price(
|
||||
website.company_id,
|
||||
website.currency_id,
|
||||
fields.Date.context_today(self),
|
||||
'sale',
|
||||
fiscal_position=fiscal_position,
|
||||
product_price_unit=price,
|
||||
product_currency=website.currency_id,
|
||||
)
|
||||
line_tax_type = website.show_line_subtotals_tax_selection
|
||||
tax_display = "total_included" if line_tax_type == "tax_included" else "total_excluded"
|
||||
|
||||
taxes = fiscal_position.map_tax(product_taxes)
|
||||
price = taxes.compute_all(price, product=self, partner=self.env['res.partner'])[tax_display]
|
||||
return price
|
||||
return self.env['product.template']._apply_taxes_to_price(
|
||||
self._get_contextual_price(),
|
||||
website.currency_id,
|
||||
product_taxes,
|
||||
fiscal_position_sudo.map_tax(product_taxes),
|
||||
self,
|
||||
)
|
||||
|
||||
@@ -254,7 +254,6 @@ class ProductTemplate(models.Model):
|
||||
return {}
|
||||
|
||||
pricelist and pricelist.ensure_one()
|
||||
partner_sudo = self.env.user.partner_id
|
||||
pricelist = pricelist or self.env['product.pricelist']
|
||||
currency = pricelist.currency_id or self.env.company.currency_id
|
||||
date = fields.Date.context_today(self)
|
||||
@@ -264,11 +263,6 @@ class ProductTemplate(models.Model):
|
||||
show_strike_price = self.env.user.has_group('website_sale.group_product_price_comparison')
|
||||
|
||||
base_sales_prices = self._price_compute('list_price', currency=currency)
|
||||
website = self.env['website'].get_current_website()
|
||||
if website.show_line_subtotals_tax_selection == 'tax_excluded':
|
||||
tax_display = 'total_excluded'
|
||||
else:
|
||||
tax_display = 'total_included'
|
||||
|
||||
res = {}
|
||||
for template in self:
|
||||
@@ -286,10 +280,10 @@ class ProductTemplate(models.Model):
|
||||
if not price_list_contains_template:
|
||||
price_reduce = base_sales_prices[template.id]
|
||||
|
||||
if template.currency_id != pricelist.currency_id:
|
||||
if template.currency_id != currency:
|
||||
base_price = template.currency_id._convert(
|
||||
base_price,
|
||||
pricelist.currency_id,
|
||||
currency,
|
||||
self.env.company,
|
||||
date,
|
||||
round=False
|
||||
@@ -299,13 +293,13 @@ class ProductTemplate(models.Model):
|
||||
base_price = base_sales_prices[template.id]
|
||||
|
||||
# Compare_list_price are never tax included
|
||||
base_price = self.env['account.tax']._fix_tax_included_price_company(
|
||||
base_price, product_taxes, taxes, self.env.company)
|
||||
base_price = taxes.compute_all(base_price, pricelist.currency_id, 1, template, partner_sudo)[tax_display]
|
||||
base_price = self._apply_taxes_to_price(
|
||||
base_price, currency, product_taxes, taxes, self,
|
||||
)
|
||||
|
||||
price_reduce = self.env['account.tax']._fix_tax_included_price_company(
|
||||
price_reduce, product_taxes, taxes, self.env.company)
|
||||
price_reduce = taxes.compute_all(price_reduce, pricelist.currency_id, 1, template, partner_sudo)[tax_display]
|
||||
price_reduce = self._apply_taxes_to_price(
|
||||
price_reduce, currency, product_taxes, taxes, self,
|
||||
)
|
||||
|
||||
template_price_vals = {
|
||||
'price_reduce': price_reduce,
|
||||
@@ -560,11 +554,12 @@ class ProductTemplate(models.Model):
|
||||
def _apply_taxes_to_price(
|
||||
self, price, currency, product_taxes, taxes, product_or_template,
|
||||
):
|
||||
# Ideally, we should use _get_tax_included_unit_price
|
||||
# but it doesn't allow to request tax-excluded amount.
|
||||
website = self.env['website'].get_current_website()
|
||||
price = self.env['account.tax']._fix_tax_included_price_company(
|
||||
price, product_taxes, taxes, self.env.company,
|
||||
price = self.env['product.product']._get_tax_included_unit_price_from_price(
|
||||
price,
|
||||
currency,
|
||||
product_taxes,
|
||||
product_taxes_after_fp=taxes,
|
||||
)
|
||||
show_tax = website.show_line_subtotals_tax_selection
|
||||
tax_display = 'total_excluded' if show_tax == 'tax_excluded' else 'total_included'
|
||||
|
||||
@@ -170,6 +170,13 @@ class TestWebsiteSaleProductAttributeValueConfig(TestSaleProductAttributeValueCo
|
||||
self.assertEqual(round(combination_info['list_price'], 2), 434.78, "434.78$ + 0% tax (mapped from fp 15% -> 0%)")
|
||||
self.assertEqual(combination_info['price_extra'], 173.91, "173.91$ + 0% tax (mapped from fp 15% -> 0%)")
|
||||
|
||||
# Try same flow with tax included for apply tax
|
||||
tax0.write({'name': "Test tax 5", 'amount': 5, 'price_include': True})
|
||||
combination_info = product._get_combination_info()
|
||||
self.assertEqual(round(combination_info['price'], 2), 456.52, "434.78$ + 5% tax (mapped from fp 15% -> 5% for BE)")
|
||||
self.assertEqual(round(combination_info['list_price'], 2), 456.52, "434.78$ + 5% tax (mapped from fp 15% -> 5% for BE)")
|
||||
self.assertEqual(combination_info['price_extra'], 182.61, "173.91$ + 5% tax (mapped from fp 15% -> 5% for BE)")
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install', 'product_pricelist')
|
||||
class TestWebsiteSaleProductPricelist(TestSaleProductAttributeValueCommon):
|
||||
|
||||
Reference in New Issue
Block a user