Skip to content
Snippets Groups Projects
Commit 0e72d6d7 authored by Jinjiu Liu's avatar Jinjiu Liu
Browse files

[FIX] website_sale: calculate the tax for no_variant product in cart

Reproduction:
1. Install eCommerce and accounting
2. Go to Accounting->Configuration->Taxes, add one sale tax 15%, and one
0%. Both taxes are included in the price.
3. Go to Configuration-> Fiscal Position, create a new one “test” which
applies the tax mapping from 15% sale tax to the 0%. Check “Detect
Automatically”, set country group as Europe
4. Go to Website->Orders->Customers, set the country of the portal user,
Joel Willis, as Luxembourg. In Sales&Purchase->Fiscal Information set
the fiscal position as “test”
5. Go to Website->Products->Product Variants, create a new one
“test_tax_prod” with price 110, and sale tax 15%, can be sold, can be
purchased and consumable.
6. Go to Website->Configuration->Attribute, create a new product
attribute “test” with Display Type as Ratio, Variant Creation Mode as
Never. Create a value “a” in its attribute values
7. Go to Website->Products->Products, find test_tax_prod, go to its
variant tab, set attribute as “test” with value “a”, publish this
product
8. Open an incognito tab, login as “portal” pwd: portal, search the
product “test_tax_prod”, set the price list as “public price list”, the
price is 95.65 on the page. Add it to the cart, the price is 110

Reason: When we update the order_line, we should update the price based
on the fiscal position for the no_variant products too. However, based
on the current workflow, the price is computed in method
_website_product_id_change before an order line is created. Thus for
no_variant products, the price is not updated.

Fix:  This issue is fixed in saas-15.3 by rewriting the workflow and
calculating the price through an on_change function here: https://github.com/odoo/odoo/blob/saas-15.3/addons/sale/models/sale_order_line.py#L588-L605

In v13, we don’t have this on_change method to compute the new price, so
a similar price update can be created in the cart update for
website_sale. This fix solution was created here: https://github.com/odoo/odoo/commit/ea259218196b2d9dc71beffea697025580c6d696
However, new price computation issues can happen when combining two
pricelists, here: https://github.com/odoo/odoo/commit/8d6a2ca0f3dcf8f8cf4679da2b3ce582b7826391

Thus the fix is eventually done in _website_product_id_change. Added a
new parameter to force checking the orderlines based on the domain. The
orderline is created but only can be searched based on the domain. This
ensures the price is computed correctly for pricelists and for tax.

Added fiscal position test for no variant product

opw-2856956

Fix by re-writing in saas-15.3: https://github.com/odoo/odoo/blob/saas-15.3/addons/sale/models/sale_order_line.py#L588-L605
First related fix: https://github.com/odoo/odoo/commit/ea259218196b2d9dc71beffea697025580c6d696
Second fix to patch for the first fix: https://github.com/odoo/odoo/commit/8d6a2ca0f3dcf8f8cf4679da2b3ce582b7826391



closes odoo/odoo#101087

X-original-commit: d8a730f5
Signed-off-by: default avatarWilliam Braeckman (wbr) <wbr@odoo.com>
Signed-off-by: default avatarLiu Jinjiu (jili) <jili@odoo.com>
parent 8746e0e0
No related branches found
No related tags found
No related merge requests found
......@@ -10,7 +10,7 @@ class SaleOrder(models.Model):
def _cart_find_product_line(self, product_id=None, line_id=None, **kwargs):
self.ensure_one()
lines = super(SaleOrder, self)._cart_find_product_line(product_id, line_id)
lines = super(SaleOrder, self)._cart_find_product_line(product_id, line_id, **kwargs)
if line_id:
return lines
domain = [('id', 'in', lines.ids)]
......
......@@ -80,7 +80,7 @@ class SaleOrder(models.Model):
product = self.env['product.product'].browse(product_id)
# split lines with the same product if it has untracked attributes
if product and (product.product_tmpl_id.has_dynamic_attributes() or product.product_tmpl_id._has_no_variant_attributes()) and not line_id:
if product and (product.product_tmpl_id.has_dynamic_attributes() or product.product_tmpl_id._has_no_variant_attributes()) and not line_id and not kwargs.get('force_search', False):
return self.env['sale.order.line']
domain = [('order_id', '=', self.id), ('product_id', '=', product_id)]
......@@ -132,7 +132,7 @@ class SaleOrder(models.Model):
else:
pu = product.price
if order.pricelist_id and order.partner_id:
order_line = order._cart_find_product_line(product.id)
order_line = order._cart_find_product_line(product.id, force_search=True)
if order_line:
pu = self.env['account.tax']._fix_tax_included_price_company(pu, product.taxes_id, order_line[0].tax_id, self.company_id)
......
......@@ -205,3 +205,78 @@ class TestWebsiteSaleProductPricelist(TestSaleProductAttributeValueCommon, TestW
with MockRequest(self.env, website=current_website, sale_order_id=so.id):
so._cart_update(product_id=test_product.product_variant_id.id, line_id=sol.id, set_qty=1)
self.assertEqual(round(sol.price_total), 50, "100$ with 50% discount + 0% tax (mapped from fp 10% -> 0%)")
def test_cart_update_with_fpos_no_variant_product(self):
# We will test that the mapping of an 10% included tax by a 0% by a fiscal position is taken into account when updating the cart for no_variant product
self.env.user.partner_id.country_id = False
current_website = self.env['website'].get_current_website()
pricelist = current_website.get_current_pricelist()
(self.env['product.pricelist'].search([]) - pricelist).write({'active': False})
# Add 10% tax on product
tax10 = self.env['account.tax'].create({'name': "Test tax 10", 'amount': 10, 'price_include': True, 'amount_type': 'percent', 'type_tax_use': 'sale'})
tax0 = self.env['account.tax'].create({'name': "Test tax 0", 'amount': 0, 'price_include': True, 'amount_type': 'percent', 'type_tax_use': 'sale'})
# Create fiscal position mapping taxes 10% -> 0%
fpos = self.env['account.fiscal.position'].create({
'name': 'test',
})
self.env['account.fiscal.position.tax'].create({
'position_id': fpos.id,
'tax_src_id': tax10.id,
'tax_dest_id': tax0.id,
})
product = self.env['product.product'].create({
'name': 'prod_no_variant',
'list_price': 110,
'taxes_id': [(6, 0, [tax10.id])],
'type': 'consu',
})
# create an attribute with one variant
product_attribute = self.env['product.attribute'].create({
'name': 'test_attr',
'display_type': 'radio',
'create_variant': 'no_variant',
})
# create attribute value
a1 = self.env['product.attribute.value'].create({
'name': 'pa_value',
'attribute_id': product_attribute.id,
'sequence': 1,
})
# set variant value to product template
product_template = self.env['product.template'].search(
[('name', '=', 'prod_no_variant')], limit=1)
product_template.attribute_line_ids = [(0, 0, {
'attribute_id': product_attribute.id,
'value_ids': [(6, 0, [a1.id])],
})]
# publish the product on website
product_template.is_published = True
# create a so for user using the fiscal position
so = self.env['sale.order'].create({
'partner_id': self.env.user.partner_id.id,
})
sol = self.env['sale.order.line'].create({
'name': product_template.name,
'product_id': product.id,
'product_uom_qty': 1,
'product_uom': product_template.uom_id.id,
'price_unit': product_template.list_price,
'order_id': so.id,
'tax_id': [(6, 0, [tax10.id])],
})
self.assertEqual(round(sol.price_total), 110.0, "110$ with 10% included tax")
so.pricelist_id = pricelist
so.fiscal_position_id = fpos
sol.product_id_change()
with MockRequest(self.env, website=current_website, sale_order_id=so.id):
so._cart_update(product_id=product.id, line_id=sol.id, set_qty=1)
self.assertEqual(round(sol.price_total), 100, "100$ with public price+ 0% tax (mapped from fp 10% -> 0%)")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment