[IMP] sale_coupon: diverse perf improvements
* Use set instead of recordset to incrementally join records * avoid filtered and mapped calls when possible * use generators correctly sum([gen]) --> sum(gen) X-original-commit: d3daa3793b8fbc9308ec0fb8935d6991b834f3a5 Co-authored-by: Loan Sens <lse@odoo.com>
This commit is contained in:
co-authored by
Loan Sens
parent
d7df652b0f
commit
4e69372685
@@ -64,27 +64,29 @@ class CouponProgram(models.Model):
|
||||
|
||||
@api.model
|
||||
def _filter_on_mimimum_amount(self, order):
|
||||
filtered_programs = self.env['coupon.program']
|
||||
|
||||
no_effect_lines = order._get_no_effect_on_threshold_lines()
|
||||
order_amount = {
|
||||
'amount_untaxed' : order.amount_untaxed - sum([line.price_subtotal for line in no_effect_lines]),
|
||||
'amount_tax' : order.amount_tax - sum([line.price_tax for line in no_effect_lines])
|
||||
'amount_untaxed' : order.amount_untaxed - sum(line.price_subtotal for line in no_effect_lines),
|
||||
'amount_tax' : order.amount_tax - sum(line.price_tax for line in no_effect_lines)
|
||||
}
|
||||
program_ids = set()
|
||||
for program in self:
|
||||
lines = order.order_line.filtered(lambda line:
|
||||
program.reward_type == 'discount' and
|
||||
(line.product_id == program.discount_line_product_id or
|
||||
line.product_id == program.reward_id.discount_line_product_id or
|
||||
(program.program_type == 'promotion_program' and line.is_reward_line)
|
||||
))
|
||||
untaxed_amount = order_amount['amount_untaxed'] - sum([line.price_subtotal for line in lines])
|
||||
tax_amount = order_amount['amount_tax'] - sum([line.price_tax for line in lines])
|
||||
if program.reward_type != 'discount':
|
||||
# avoid the filtered
|
||||
lines = self.env['sale.order.line']
|
||||
else:
|
||||
lines = order.order_line.filtered(lambda line:
|
||||
line.product_id == program.discount_line_product_id or
|
||||
line.product_id == program.reward_id.discount_line_product_id or
|
||||
(program.program_type == 'promotion_program' and line.is_reward_line)
|
||||
)
|
||||
untaxed_amount = order_amount['amount_untaxed'] - sum(line.price_subtotal for line in lines)
|
||||
tax_amount = order_amount['amount_tax'] - sum(line.price_tax for line in lines)
|
||||
program_amount = program._compute_program_amount('rule_minimum_amount', order.currency_id)
|
||||
if program.rule_minimum_amount_tax_inclusion == 'tax_included' and program_amount <= (untaxed_amount + tax_amount) or program.rule_minimum_amount_tax_inclusion == 'tax_excluded' and program_amount <= untaxed_amount:
|
||||
filtered_programs |= program
|
||||
program_ids.add(program.id)
|
||||
|
||||
return filtered_programs
|
||||
return self.browse(program_ids)
|
||||
|
||||
@api.model
|
||||
def _filter_on_validity_dates(self, order):
|
||||
@@ -116,17 +118,23 @@ class CouponProgram(models.Model):
|
||||
products_qties = dict.fromkeys(products, 0)
|
||||
for line in order_lines:
|
||||
products_qties[line.product_id] += line.product_uom_qty
|
||||
valid_programs = self.filtered(lambda program: not program.rule_products_domain)
|
||||
for program in self - valid_programs:
|
||||
valid_program_ids = set()
|
||||
for program in self:
|
||||
if not program.rule_products_domain:
|
||||
valid_program_ids.add(program.id)
|
||||
continue
|
||||
valid_products = program._get_valid_products(products)
|
||||
if not valid_products:
|
||||
# The program can be directly discarded
|
||||
continue
|
||||
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.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
|
||||
return valid_programs
|
||||
valid_program_ids.add(program.id)
|
||||
return self.browse(valid_program_ids)
|
||||
|
||||
def _filter_not_ordered_reward_programs(self, order):
|
||||
"""
|
||||
|
||||
@@ -361,8 +361,9 @@ class SaleOrder(models.Model):
|
||||
applicable_programs = applicable_programs._keep_only_most_interesting_auto_applied_global_discount_program()
|
||||
programs_to_remove = applied_programs - applicable_programs
|
||||
|
||||
reward_product_ids = applied_programs.discount_line_product_id.ids
|
||||
# delete reward line coming from an archived coupon (it will never be updated/removed when recomputing the order)
|
||||
invalid_lines = order.order_line.filtered(lambda line: line.is_reward_line and line.product_id.id not in (applied_programs).mapped('discount_line_product_id').ids)
|
||||
invalid_lines = order.order_line.filtered(lambda line: line.is_reward_line and line.product_id.id not in reward_product_ids)
|
||||
|
||||
if programs_to_remove:
|
||||
product_ids_to_remove = programs_to_remove.discount_line_product_id.ids
|
||||
|
||||
@@ -19,6 +19,6 @@ class CouponProgram(models.Model):
|
||||
return programs
|
||||
|
||||
def _check_promo_code(self, order, coupon_code):
|
||||
if self.reward_type == 'free_shipping' and not order.order_line.filtered(lambda line: line.is_delivery):
|
||||
if self.reward_type == 'free_shipping' and not any(order.is_delivery for order in order.order_line):
|
||||
return {'error': _('The shipping costs are not in the order lines.')}
|
||||
return super(CouponProgram, self)._check_promo_code(order, coupon_code)
|
||||
|
||||
Reference in New Issue
Block a user