[FIX] product: fix possible combination with variant active + archive

Before this commit, if multiple variants exist for the same combination it would
consider the combination impossible if any of the variants was archived.

After this commit, it will consider the combination impossible only if all the
corresponding variants are archived.

opw-1959317
PR: #32691
This commit is contained in:
Sébastien Theys
2019-05-21 08:44:55 +00:00
parent e015ee5df3
commit 42cc64b5ce
3 changed files with 36 additions and 9 deletions
+10
View File
@@ -346,6 +346,16 @@ class ProductProduct(models.Model):
product._set_standard_price(vals.get('standard_price') or 0.0)
# `_get_variant_id_for_combination` depends on existing variants
self.clear_caches()
self.env['product.template'].invalidate_cache(
fnames=[
'valid_archived_variant_ids',
'valid_existing_variant_ids',
'product_variant_ids',
'product_variant_id',
'product_variant_count'
],
ids=products.mapped('product_tmpl_id').ids
)
return products
@api.multi
+11 -9
View File
@@ -830,9 +830,16 @@ class ProductTemplate(models.Model):
# combination has different values than the ones configured on the template
return False
if not self.has_dynamic_attributes() and not self._get_variant_for_combination(combination):
# the variant has been deleted
return False
variant = self._get_variant_for_combination(combination)
if self.has_dynamic_attributes():
if variant and not variant.active:
# dynamic and the variant has been archived
return False
else:
if not variant or not variant.active:
# not dynamic, the variant has been archived or deleted
return False
exclusions = self._get_own_attribute_exclusions()
if exclusions:
@@ -849,11 +856,6 @@ class ProductTemplate(models.Model):
if exclusion in combination.ids:
return False
filtered_combination = combination._without_no_variant_attributes()
archived_combinations = self._get_archived_combinations()
if archived_combinations and filtered_combination.ids in archived_combinations:
return False
return True
@api.multi
@@ -887,7 +889,7 @@ class ProductTemplate(models.Model):
for pav in attribute_values:
domain = expression.AND([[('attribute_value_ids', 'in', pav.id)], domain])
res = self.env['product.product'].with_context(active_test=False).search(domain)
res = self.env['product.product'].with_context(active_test=False).search(domain, order='active DESC')
# The domain above is checking for the `product.attribute.value`, but we
# need to make sure it's the same `product.template.attribute.value`.
@@ -312,6 +312,21 @@ class TestProductAttributeValueConfig(TestProductAttributeValueSetup):
variant.unlink()
self.assertFalse(self.computer._is_combination_possible(computer_ssd_256 + computer_ram_8 + computer_hdd_1))
# CASE: if multiple variants exist for the same combination and at least
# one of them is not archived, the combination is possible
values = self.ssd_256 + self.ram_8 + self.hdd_1
self.env['product.product'].create({
'product_tmpl_id': self.computer.id,
'attribute_value_ids': [(6, 0, values.ids)],
'active': False,
})
self.env['product.product'].create({
'product_tmpl_id': self.computer.id,
'attribute_value_ids': [(6, 0, values.ids)],
'active': True,
})
self.assertTrue(self.computer._is_combination_possible(computer_ssd_256 + computer_ram_8 + computer_hdd_1))
def test_get_first_possible_combination(self):
computer_ssd_256 = self._get_product_template_attribute_value(self.ssd_256)
computer_ssd_512 = self._get_product_template_attribute_value(self.ssd_512)