[FIX] sale_coupon: Better performance
On instances with a lot of coupons programs, performance issue arise while using eccommerce (adding item in basket ant opening it in particular). In the client case, he have ~2000 of them. Opening the basket with 1 product take: Before this commit: ~10s After this commit: ~2s ( pyflame is available in the ticket attachment ) `_get_valid_products` use the v13 `filtered_domain` method Average execution time: Before change: 0.001 s After change: 0.0001 s => 10x times gained The average execution time of `_is_valid_product` is 0.002 s (20 times slower than `_get_valid_products` for the same result). => All use of `_is_valid_product` were replaced by `_get_valid_products` In this commit targeting master, we also completely remove `_is_valid_product` as it effectively is no longer used and there are no stable compatibility requirements. OPW-2323599 closes odoo/odoo#56460 X-original-commit: c3a9738e25dbd773e3ee7c2175e62219346ef764 Signed-off-by: Adrian Torres (adt) <adt@odoo.com>
This commit is contained in:
committed by
Adrian Torres
parent
d1391314d9
commit
54c74bb433
@@ -139,16 +139,8 @@ class CouponProgram(models.Model):
|
||||
else:
|
||||
return True
|
||||
|
||||
def _is_valid_product(self, product):
|
||||
# NOTE: if you override this method, think of also overriding _get_valid_products
|
||||
if self.rule_products_domain:
|
||||
domain = ast.literal_eval(self.rule_products_domain) + [('id', '=', product.id)]
|
||||
return bool(self.env['product.product'].search_count(domain))
|
||||
else:
|
||||
return True
|
||||
|
||||
def _get_valid_products(self, products):
|
||||
if self.rule_products_domain:
|
||||
domain = ast.literal_eval(self.rule_products_domain) + [('id', 'in', products.ids)]
|
||||
return self.env['product.product'].search(domain)
|
||||
domain = ast.literal_eval(self.rule_products_domain)
|
||||
return products.filtered_domain(domain)
|
||||
return products
|
||||
|
||||
@@ -121,7 +121,7 @@ class CouponProgram(models.Model):
|
||||
ordered_rule_products_qty = sum(products_qties[product] for product in valid_products)
|
||||
# Avoid program if 1 ordered foo on a program '1 foo, 1 free foo'
|
||||
if program.promo_applicability == 'on_current_order' and \
|
||||
program._is_valid_product(program.reward_product_id) and program.reward_type == 'product':
|
||||
program.reward_type == 'product' and program._get_valid_products(program.reward_product_id):
|
||||
ordered_rule_products_qty -= program.reward_product_quantity
|
||||
if ordered_rule_products_qty >= program.rule_min_quantity:
|
||||
valid_programs |= program
|
||||
|
||||
@@ -78,10 +78,10 @@ class SaleOrder(models.Model):
|
||||
def _get_reward_values_product(self, program):
|
||||
price_unit = self.order_line.filtered(lambda line: program.reward_product_id == line.product_id)[0].price_reduce
|
||||
|
||||
order_lines = (self.order_line - self._get_reward_lines()).filtered(lambda x: program._is_valid_product(x.product_id))
|
||||
order_lines = (self.order_line - self._get_reward_lines()).filtered(lambda x: program._get_valid_products(x.product_id))
|
||||
max_product_qty = sum(order_lines.mapped('product_uom_qty')) or 1
|
||||
# Remove needed quantity from reward quantity if same reward and rule product
|
||||
if program._is_valid_product(program.reward_product_id):
|
||||
if program._get_valid_products(program.reward_product_id):
|
||||
# number of times the program should be applied
|
||||
program_in_order = max_product_qty // (program.rule_min_quantity + program.reward_product_quantity)
|
||||
# multipled by the reward qty
|
||||
|
||||
Reference in New Issue
Block a user