[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:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user