[FIX] product: use configurator with deleted attribute
The product configurator can have irrelevant disabled options if the product selected has some archived variants Steps to reproduce: 1. Install Sales and Inventory 2. Create a product with two attributes, each with two values (e.g. Color: C1, C2 and Weight: W1, W2) 3. Open one of the variant, add some stock then archive it 4. Delete the attribute Weight from the product 5. Create a SO for any customer and add the product 6. The product configurator dialog opens but the C1 color is unavailable Solution: Only return the archived combinations for which all of the attribute are still used in the product opw-3427753 closes odoo/odoo#132420 X-original-commit: d5cd215dcf1b7e633c86ad734274a65827368ade Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com> Co-authored-by: Victor Feyens <vfe@odoo.com>
This commit is contained in:
committed by
Victor Feyens
co-authored by
Victor Feyens
parent
522c8cd783
commit
d5878829cd
@@ -798,7 +798,10 @@ class ProductTemplate(models.Model):
|
||||
'archived_combinations': [
|
||||
product.product_template_attribute_value_ids.ids
|
||||
for product in archived_products
|
||||
if product.product_template_attribute_value_ids
|
||||
if product.product_template_attribute_value_ids and all(
|
||||
ptav.ptav_active
|
||||
for ptav in product.product_template_attribute_value_ids
|
||||
)
|
||||
],
|
||||
'parent_exclusions': self._get_parent_attribute_exclusions(parent_combination),
|
||||
'parent_combination': parent_combination.ids,
|
||||
|
||||
@@ -9,8 +9,10 @@ from odoo.addons.sale.tests.common import SaleCommon
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestProductConfiguratorData(HttpCase, ProductVariantsCommon, SaleCommon):
|
||||
|
||||
def test_dropped_attribute_isnt_shown(self):
|
||||
def test_dropped_value_isnt_shown(self):
|
||||
self.assertEqual(len(self.product_template_sofa.product_variant_ids), 3)
|
||||
|
||||
# Use variants s.t. they are archived and not deleted when value is removed
|
||||
self.empty_order.order_line = [
|
||||
Command.create({
|
||||
'product_id': product.id
|
||||
@@ -19,6 +21,7 @@ class TestProductConfiguratorData(HttpCase, ProductVariantsCommon, SaleCommon):
|
||||
]
|
||||
self.empty_order.action_confirm()
|
||||
|
||||
# Remove attribute value
|
||||
self.product_template_sofa.attribute_line_ids.value_ids -= self.color_attribute_red
|
||||
self.assertEqual(len(self.product_template_sofa.product_variant_ids.filtered('active')), 2)
|
||||
|
||||
@@ -44,3 +47,67 @@ class TestProductConfiguratorData(HttpCase, ProductVariantsCommon, SaleCommon):
|
||||
|
||||
# Make sure the inactive ptav was removed from the loaded attributes
|
||||
self.assertEqual(len(result['products'][0]['attribute_lines'][0]['attribute_values']), 2)
|
||||
|
||||
def test_dropped_attribute(self):
|
||||
self.product_template_2_attribute_lines = self.env['product.template'].create({
|
||||
'name': 'Shirt',
|
||||
'categ_id': self.product_category.id,
|
||||
'attribute_line_ids': [
|
||||
Command.create({
|
||||
'attribute_id': self.size_attribute.id,
|
||||
'value_ids': [
|
||||
Command.set([
|
||||
self.size_attribute_l.id,
|
||||
self.size_attribute_m.id,
|
||||
]),
|
||||
],
|
||||
}),
|
||||
Command.create({
|
||||
'attribute_id': self.color_attribute.id,
|
||||
'value_ids': [
|
||||
Command.set([
|
||||
self.color_attribute_red.id,
|
||||
self.color_attribute_blue.id,
|
||||
])
|
||||
],
|
||||
}),
|
||||
],
|
||||
})
|
||||
self.assertEqual(len(self.product_template_2_attribute_lines.product_variant_ids), 4)
|
||||
|
||||
# Use variants s.t. they are archived and not deleted when value is removed
|
||||
self.empty_order.order_line = [
|
||||
Command.create({
|
||||
'product_id': product.id
|
||||
})
|
||||
for product in self.product_template_2_attribute_lines.product_variant_ids
|
||||
]
|
||||
self.empty_order.action_confirm()
|
||||
|
||||
# Remove attribute
|
||||
self.product_template_2_attribute_lines.attribute_line_ids[0].unlink()
|
||||
self.assertEqual(len(self.product_template_2_attribute_lines.product_variant_ids), 2)
|
||||
|
||||
self.authenticate('demo', 'demo')
|
||||
base_url = self.product_template_2_attribute_lines.get_base_url()
|
||||
response = self.opener.post(
|
||||
url=base_url + '/sale_product_configurator/get_values',
|
||||
json={
|
||||
'params': {
|
||||
'product_template_id': self.product_template_2_attribute_lines.id,
|
||||
'quantity': 1.0,
|
||||
'currency_id': 1,
|
||||
'so_date': str(self.env.cr.now()),
|
||||
'product_uom_id': None,
|
||||
'company_id': None,
|
||||
'pricelist_id': None,
|
||||
'ptav_ids': None,
|
||||
'only_main_product': False,
|
||||
},
|
||||
}
|
||||
)
|
||||
result = response.json()['result']
|
||||
|
||||
# Make sure archived combinations with inactive ptav are not loaded as it's useless to
|
||||
# exclude combinations that are not even available
|
||||
self.assertFalse(result['products'][0]['archived_combinations'])
|
||||
|
||||
Reference in New Issue
Block a user