diff --git a/models/sale_coupon_program.py b/models/sale_coupon_program.py index 2a3168623c4..820310a41a8 100644 --- a/models/sale_coupon_program.py +++ b/models/sale_coupon_program.py @@ -218,10 +218,9 @@ class SaleCouponProgram(models.Model): 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) + if program.promo_applicability == 'on_current_order' and \ + program._is_valid_product(program.reward_product_id) and program.reward_type == 'product': ordered_rule_products_qty -= program.reward_product_quantity - # needed_quantity = program.rule_min_quantity if self. if ordered_rule_products_qty >= program.rule_min_quantity: valid_programs |= program return valid_programs @@ -256,7 +255,12 @@ class SaleCouponProgram(models.Model): # 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) if not next_order: programs = programs and programs._filter_programs_on_products(order) - programs = programs and programs._filter_not_ordered_reward_programs(order) + + programs_curr_order = programs.filtered(lambda p: p.promo_applicability == 'on_current_order') + programs = programs.filtered(lambda p: p.promo_applicability == 'on_next_order') + if programs_curr_order: + # Checking if rewards are in the SO should not be performed for rewards on_next_order + programs += programs_curr_order._filter_not_ordered_reward_programs(order) return programs def _is_valid_partner(self, partner): diff --git a/tests/test_program_numbers.py b/tests/test_program_numbers.py index 8284cd1dad4..024781da232 100644 --- a/tests/test_program_numbers.py +++ b/tests/test_program_numbers.py @@ -489,3 +489,31 @@ class TestSaleCouponProgramNumbers(TestSaleCouponCommon): fixed_amount_program.write({'active': False}) # Check archived product will remove discount lines on recompute order.recompute_coupon_lines() self.assertEqual(len(order.order_line.ids), 1, "Archiving the program should remove the program reward line") + + def test_program_next_order(self): + order = self.empty_order + self.env['sale.coupon.program'].create({ + 'name': 'Free Keyboard if at least 1 article', + 'promo_code_usage': 'no_code_needed', + 'promo_applicability': 'on_next_order', + 'program_type': 'promotion_program', + 'reward_type': 'product', + 'reward_product_id': self.wirelessKeyboard.id, + 'rule_min_quantity': 2, + }) + sol1 = self.env['sale.order.line'].create({ + 'product_id': self.iPadMini.id, + 'name': 'iPad Mini', + 'product_uom_qty': 1.0, + 'order_id': order.id, + }) + order.recompute_coupon_lines() + self.assertEqual(len(order.order_line.ids), 1, "Nothing should be added to the cart") + self.assertEqual(len(order.generated_coupon_ids), 0, "No coupon should have been generated yet") + + sol1.product_uom_qty = 2 + order.recompute_coupon_lines() + generated_coupon = order.generated_coupon_ids + self.assertEqual(len(order.order_line.ids), 1, "Nothing should be added to the cart (2)") + self.assertEqual(len(generated_coupon), 1, "A coupon should have been generated") + self.assertEqual(generated_coupon.state, 'reserved', "The coupon should be reserved")