summaryrefslogtreecommitdiff
path: root/addons/product
diff options
context:
space:
mode:
authorNicolas Galler <ngl@odoo.com>2020-10-22 13:04:14 +0000
committerNicolas Galler <ngl@odoo.com>2020-10-23 14:05:05 +0000
commitc51867b785aab707b1059d6545b9fce7e95a2488 (patch)
treefd02aa6baf18619c2c37bdfbe4639e762edb386f /addons/product
parent8a949019fd39c6c07ae5827462ee96e15f3190a1 (diff)
[FIX] product: archiving last variant must archive product template
Behavior prior to this fix: When archiving the last variant on a template, the product template stays active (contrary to the comment indicating that `toggle_active` will archive the related product.template if there is only one active `product.product`). Behavior after the fix: When archiving the last variant on a template, the product template is archived. When un-archiving that variant, the product template is unarchived as well, without un-archiving the other variants. Note: this is a remake of a fix implemented in 77e5472c041e, as that fix did not correctly count the inactive variants. opw-2349862 closes odoo/odoo#60635 X-original-commit: 01160ee5e7f726f3035c566a13e26825236dedfd Signed-off-by: Nicolas Galler <nicocrm@users.noreply.github.com>
Diffstat (limited to 'addons/product')
-rw-r--r--addons/product/models/product.py16
-rw-r--r--addons/product/models/product_template.py2
-rw-r--r--addons/product/tests/test_variants.py25
3 files changed, 37 insertions, 6 deletions
diff --git a/addons/product/models/product.py b/addons/product/models/product.py
index 7e192b84ee8..fee39fe1d8d 100644
--- a/addons/product/models/product.py
+++ b/addons/product/models/product.py
@@ -689,11 +689,17 @@ class ProductProduct(models.Model):
return self.product_tmpl_id._is_combination_possible(self.product_template_attribute_value_ids, parent_combination=parent_combination, ignore_no_variant=True)
def toggle_active(self):
- """ Archiving related product.template if there is only one active product.product """
- with_one_active = self.filtered(lambda product: len(product.product_tmpl_id.with_context(active_test=False).product_variant_ids) == 1)
- for product in with_one_active:
- product.product_tmpl_id.toggle_active()
- return super(ProductProduct, self - with_one_active).toggle_active()
+ """ Archiving related product.template if there is not any more active product.product
+ (and vice versa, unarchiving the related product template if there is now an active product.product) """
+ result = super().toggle_active()
+ # We deactivate product templates which are active with no active variants.
+ tmpl_to_deactivate = self.filtered(lambda product: (product.product_tmpl_id.active
+ and not product.product_tmpl_id.product_variant_ids)).mapped('product_tmpl_id')
+ # We activate product templates which are inactive with active variants.
+ tmpl_to_activate = self.filtered(lambda product: (not product.product_tmpl_id.active
+ and product.product_tmpl_id.product_variant_ids)).mapped('product_tmpl_id')
+ (tmpl_to_deactivate + tmpl_to_activate).toggle_active()
+ return result
class ProductPackaging(models.Model):
diff --git a/addons/product/models/product_template.py b/addons/product/models/product_template.py
index 50685ef014a..3dac988fc3d 100644
--- a/addons/product/models/product_template.py
+++ b/addons/product/models/product_template.py
@@ -424,7 +424,7 @@ class ProductTemplate(models.Model):
if uom_id and uom_po_id and uom_id.category_id != uom_po_id.category_id:
vals['uom_po_id'] = uom_id.id
res = super(ProductTemplate, self).write(vals)
- if 'attribute_line_ids' in vals or vals.get('active'):
+ if 'attribute_line_ids' in vals or (vals.get('active') and len(self.product_variant_ids) == 0):
self._create_variant_ids()
if 'active' in vals and not vals.get('active'):
self.with_context(active_test=False).mapped('product_variant_ids').write({'active': vals.get('active')})
diff --git a/addons/product/tests/test_variants.py b/addons/product/tests/test_variants.py
index a0ee4134f0a..e952ad1abe4 100644
--- a/addons/product/tests/test_variants.py
+++ b/addons/product/tests/test_variants.py
@@ -259,6 +259,31 @@ class TestVariants(common.TestProductCommon):
self.assertTrue(variant_1.active)
self.assertTrue(template.active)
+ def test_archive_all_variants(self):
+ template = self.env['product.template'].create({
+ 'name': 'template'
+ })
+ self.assertEqual(len(template.product_variant_ids), 1)
+
+ template.write({
+ 'attribute_line_ids': [(0, False, {
+ 'attribute_id': self.size_attr.id,
+ 'value_ids': [
+ (4, self.size_attr.value_ids[0].id, self.size_attr_value_s),
+ (4, self.size_attr.value_ids[1].id, self.size_attr_value_m)
+ ],
+ })]
+ })
+ self.assertEqual(len(template.product_variant_ids), 2)
+ variant_1 = template.product_variant_ids[0]
+ variant_2 = template.product_variant_ids[1]
+ template.product_variant_ids.toggle_active()
+ self.assertFalse(variant_1.active, 'Should archive all variants')
+ self.assertFalse(template.active, 'Should archive related template')
+ variant_1.toggle_active()
+ self.assertTrue(variant_1.active, 'Should activate variant')
+ self.assertFalse(variant_2.active, 'Should not re-activate other variant')
+ self.assertTrue(template.active, 'Should re-activate template')
class TestVariantsNoCreate(common.TestProductCommon):