[FIX] product: price computation based on cost
- Standard price (cost price) is there for variants and for product template when there are no variant, as it has no sense the have one otherwise. Templates with variantS have a cost of 0. - On the website, product shown are the product templates, but you select and then buy the product product (variants). - The pricelist can be set to make a discount based on the cost. ==> If such a pricelist is used, the product templates having more than 1 variant are shown with a price of 0 until you can select the wanted variant opw-3232621 closes odoo/odoo#124594 X-original-commit: 561eba8f2adece4c21ea46c1bd050779ea3dc676 Signed-off-by: Morgane Demesmaeker <edm@odoo.com>
This commit is contained in:
@@ -594,6 +594,8 @@ class ProductTemplate(models.Model):
|
||||
price = template[price_type] or 0.0
|
||||
price_currency = template.currency_id
|
||||
if price_type == 'standard_price':
|
||||
if not price and template.product_variant_ids:
|
||||
price = template.product_variant_ids[0].standard_price
|
||||
price_currency = template.cost_currency_id
|
||||
elif price_type == 'list_price':
|
||||
price += template._get_attributes_extra_price()
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from unittest.mock import patch
|
||||
|
||||
from odoo.fields import Command
|
||||
from odoo.tests import tagged, TransactionCase
|
||||
|
||||
from odoo.addons.base.tests.common import TransactionCaseWithUserDemo, HttpCaseWithUserPortal
|
||||
from odoo.addons.website.tools import MockRequest
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests.common import HttpCase, TransactionCase
|
||||
from odoo.tools import DotDict
|
||||
|
||||
''' /!\/!\
|
||||
Calling `get_pricelist_available` after setting `property_product_pricelist` on
|
||||
@@ -296,6 +296,45 @@ class TestWebsitePriceList(TransactionCase):
|
||||
prices = product._get_sales_prices(self.list_christmas)
|
||||
self.assertFalse('base_price' in prices[product.id])
|
||||
|
||||
def test_pricelist_item_based_on_cost_for_templates(self):
|
||||
""" Test that `_get_sales_prices` from `product_template` computes the correct price when
|
||||
the pricelist item is based on the cost of the product.
|
||||
"""
|
||||
pricelist = self.env['product.pricelist'].create({
|
||||
'name': 'Pricelist base on cost',
|
||||
'item_ids': [Command.create({
|
||||
'base': 'standard_price',
|
||||
'compute_price': 'percentage',
|
||||
'percent_price': 10,
|
||||
})]
|
||||
})
|
||||
|
||||
pa = self.env['product.attribute'].create({'name': 'Attribute'})
|
||||
pav1 = self.env['product.attribute.value'].create({'name': 'Value1', 'attribute_id': pa.id})
|
||||
pav2 = self.env['product.attribute.value'].create({'name': 'Value2', 'attribute_id': pa.id})
|
||||
|
||||
product_template = self.env['product.template'].create({
|
||||
'name': 'Product Template', 'list_price': 10.0, 'standard_price': 5.0
|
||||
})
|
||||
self.assertEqual(product_template.standard_price, 5)
|
||||
price = product_template._get_sales_prices(pricelist)[product_template.id]['price_reduce']
|
||||
msg = "Template has no variants, the price should be computed based on the template's cost."
|
||||
self.assertEqual(price, 4.5, msg)
|
||||
|
||||
product_template.attribute_line_ids = [Command.create({
|
||||
'attribute_id': pa.id, 'value_ids': [Command.set([pav1.id, pav2.id])]
|
||||
})]
|
||||
msg = "Product template with variants should have no cost."
|
||||
self.assertEqual(product_template.standard_price, 0, msg)
|
||||
self.assertEqual(product_template.product_variant_ids[0].standard_price, 0)
|
||||
|
||||
price = product_template._get_sales_prices(pricelist)[product_template.id]['price_reduce']
|
||||
msg = "Template has variants, the price should be computed based on the 1st variant's cost."
|
||||
self.assertEqual(price, 0, msg)
|
||||
|
||||
product_template.product_variant_ids[0].standard_price = 20
|
||||
price = product_template._get_sales_prices(pricelist)[product_template.id]['price_reduce']
|
||||
self.assertEqual(price, 18, msg)
|
||||
|
||||
def simulate_frontend_context(self, website_id=1):
|
||||
# Mock this method will be enough to simulate frontend context in most methods
|
||||
|
||||
Reference in New Issue
Block a user