diff --git a/addons/sale_coupon/models/coupon_program.py b/addons/sale_coupon/models/coupon_program.py index 37b90551a42..68ef639a075 100644 --- a/addons/sale_coupon/models/coupon_program.py +++ b/addons/sale_coupon/models/coupon_program.py @@ -30,7 +30,6 @@ class CouponProgram(models.Model): def _check_promo_code(self, order, coupon_code): message = {} - applicable_programs = order._get_applicable_programs() if self.maximum_use_number != 0 and self.order_count >= self.maximum_use_number: message = {'error': _('Promo code %s has been expired.') % (coupon_code)} elif not self._filter_on_mimimum_amount(order): @@ -57,8 +56,9 @@ class CouponProgram(models.Model): message = {'error': _("The customer doesn't have access to this reward.")} elif not self._filter_programs_on_products(order): message = {'error': _("You don't have the required product quantities on your sales order. If the reward is same product quantity, please make sure that all the products are recorded on the sales order (Example: You need to have 3 T-shirts on your sales order if the promotion is 'Buy 2, Get 1 Free'.")} - else: - if self not in applicable_programs and self.promo_applicability == 'on_current_order': + elif self.promo_applicability == 'on_current_order' and not self.env.context.get('applicable_coupon'): + applicable_programs = order._get_applicable_programs() + if self not in applicable_programs: message = {'error': _('At least one of the required conditions is not met to get the reward!')} return message @@ -160,7 +160,8 @@ class CouponProgram(models.Model): # Minimum requirement should not be checked if the coupon got generated by a promotion program (the requirement should have only be checked to generate the coupon) if not next_order: programs = programs and programs._filter_on_mimimum_amount(order) - programs = programs and programs._filter_on_validity_dates(order) + if not self.env.context.get("no_outdated_coupons"): + programs = programs and programs._filter_on_validity_dates(order) programs = programs and programs._filter_unexpired_programs(order) programs = programs and programs._filter_programs_on_partners(order) # Product requirement should not be checked if the coupon got generated by a promotion program (the requirement should have only be checked to generate the coupon) diff --git a/addons/sale_coupon/models/sale_order.py b/addons/sale_coupon/models/sale_order.py index 36bdb713421..d5711874e2e 100644 --- a/addons/sale_coupon/models/sale_order.py +++ b/addons/sale_coupon/models/sale_order.py @@ -254,8 +254,12 @@ class SaleOrder(models.Model): This method is used to return the valid applicable programs on given order. """ self.ensure_one() - programs = self.env['coupon.program'].search([ - ('company_id', 'in', [self.company_id.id, False]) + programs = self.env['coupon.program'].with_context( + no_outdated_coupons=True, + ).search([ + ('company_id', 'in', [self.company_id.id, False]), + '|', ('rule_date_from', '=', False), ('rule_date_from', '<=', self.date_order), + '|', ('rule_date_to', '=', False), ('rule_date_to', '>=', self.date_order), ], order="id")._filter_programs_from_common_rules(self) # no impact code... # should be programs = programs.filtered if we really want to filter... @@ -265,8 +269,13 @@ class SaleOrder(models.Model): def _get_applicable_no_code_promo_program(self): self.ensure_one() - programs = self.env['coupon.program'].search([ + programs = self.env['coupon.program'].with_context( + no_outdated_coupons=True, + applicable_coupon=True, + ).search([ ('promo_code_usage', '=', 'no_code_needed'), + '|', ('rule_date_from', '=', False), ('rule_date_from', '<=', self.date_order), + '|', ('rule_date_to', '=', False), ('rule_date_to', '>=', self.date_order), '|', ('company_id', '=', self.company_id.id), ('company_id', '=', False), ])._filter_programs_from_common_rules(self) return programs @@ -288,6 +297,9 @@ class SaleOrder(models.Model): programs = order._get_applicable_no_code_promo_program() programs = programs._keep_only_most_interesting_auto_applied_global_discount_program() for program in programs: + # VFE REF in master _get_applicable_no_code_programs already filters programs + # why do we need to reapply this bunch of checks in _check_promo_code ???? + # We should only apply a little part of the checks in _check_promo_code... error_status = program._check_promo_code(order, False) if not error_status.get('error'): if program.promo_applicability == 'on_next_order':