[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:
committed by
Raphael Collet
parent
c2f34886ba
commit
f9fb24f1b5
@@ -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'):
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user