diff --git a/models/sale_coupon_program.py b/models/sale_coupon_program.py index 3a02ff59cc9..5ee7bb18507 100644 --- a/models/sale_coupon_program.py +++ b/models/sale_coupon_program.py @@ -220,15 +220,14 @@ class SaleCouponProgram(models.Model): or Buy 1 coke + get 1 coke free then check 2 cokes are on cart or not """ order_lines = order.order_line.filtered(lambda line: line.product_id) - order._get_reward_lines() - products_qties = dict.fromkeys([product for product in order_lines.mapped('product_id')], 0) + products = order_lines.mapped('product_id') + 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: - ordered_rule_products_qty = sum( - qty for product, qty in products_qties.items() - if program._is_valid_product(product) - ) + valid_products = program._get_valid_products(products) + 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._is_valid_product(program.reward_product_id) and program.reward_type == 'product': line = order.order_line.filtered(lambda line: line.product_id == program.reward_product_id) @@ -279,8 +278,15 @@ class SaleCouponProgram(models.Model): 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 = safe_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 = safe_eval(self.rule_products_domain) + [('id', 'in', products.ids)] + return self.env['product.product'].search(domain) + return products diff --git a/models/sale_order.py b/models/sale_order.py index 5f3e8a14c28..83cfb7f24ca 100644 --- a/models/sale_order.py +++ b/models/sale_order.py @@ -346,8 +346,8 @@ class SaleOrder(models.Model): order.no_code_promo_program_ids -= programs_to_remove order.code_promo_program_id -= programs_to_remove order.applied_coupon_ids -= order.applied_coupon_ids.filtered(lambda coupon: coupon.program_id in programs_to_remove) - invalid_lines += order.order_line.filtered(lambda line: line.product_id.id in products_to_remove.ids) - order.write({'order_line': [(2, line.id, False) for line in invalid_lines]}) + invalid_lines |= order.order_line.filtered(lambda line: line.product_id.id in products_to_remove.ids) + invalid_lines.unlink() def _get_applied_programs_with_rewards_on_current_order(self): # Need to add filter on current order. Indeed, it has always been calculating reward line even if on next order (which is useless and do calculation for nothing)