[FIX] product, sale, stock: speed up discarding product variants

Modifying product attributes involves discarding product variants via
the method _unlink_or_archive(), which tries to delete variants, and
archive the ones for which the deletion fails.  This process is very
slow when most product variants must be archived.  Instead, we filter
out the variants that must be archived anyway (like the ones used in
sales or stock), in order to avoid the variants that cannot be deleted.

On a product with ~200 variants, the time goes from more than 15 minutes
(the request times out) to around 5 seconds!

opw-2440417

closes odoo/odoo#65027

X-original-commit: 63b2f85079404eafac918a74c95e27051539c133
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
This commit is contained in:
Ivan Yelizariev
2021-01-25 18:32:23 +00:00
committed by Raphael Collet
parent c2f34886ba
commit f9fb24f1b5
3 changed files with 20 additions and 0 deletions
+7
View File
@@ -369,6 +369,9 @@ class ProductProduct(models.Model):
self.clear_caches()
return res
def _filter_to_unlink(self, check_access=True):
return self
def _unlink_or_archive(self, check_access=True):
"""Unlink or archive products.
Try in batch as much as possible because it is much faster.
@@ -386,6 +389,10 @@ class ProductProduct(models.Model):
self.check_access_rights('write')
self.check_access_rule('write')
self = self.sudo()
to_unlink = self._filter_to_unlink()
to_archive = self - to_unlink
to_archive.write({'active': False})
self = to_unlink
try:
with self.env.cr.savepoint(), tools.mute_logger('odoo.sql_db'):
+6
View File
@@ -56,6 +56,12 @@ class ProductProduct(models.Model):
self.ensure_one()
return self.product_tmpl_id._get_combination_info(self.product_template_attribute_value_ids, self.id, add_qty, pricelist, parent_combination)
def _filter_to_unlink(self):
domain = [('product_id', 'in', self.ids)]
lines = self.env['sale.order.line'].read_group(domain, ['product_id'], ['product_id'])
linked_product_ids = [group['product_id'][0] for group in lines]
return super(ProductProduct, self - self.browse(linked_product_ids))._filter_to_unlink()
class ProductAttributeCustomValue(models.Model):
_inherit = "product.attribute.custom.value"
+7
View File
@@ -539,6 +539,13 @@ class Product(models.Model):
return self._get_rules_from_location(rule.location_src_id, seen_rules=seen_rules | rule)
def _filter_to_unlink(self):
domain = [('product_id', 'in', self.ids)]
lines = self.env['stock.production.lot'].read_group(domain, ['product_id'], ['product_id'])
linked_product_ids = [group['product_id'][0] for group in lines]
return super(Product, self - self.browse(linked_product_ids))._filter_to_unlink()
class ProductTemplate(models.Model):
_inherit = 'product.template'
_check_company_auto = True