diff --git a/addons/sale_coupon/models/coupon_program.py b/addons/sale_coupon/models/coupon_program.py index e600f7b3000..885d77b9e1f 100644 --- a/addons/sale_coupon/models/coupon_program.py +++ b/addons/sale_coupon/models/coupon_program.py @@ -89,9 +89,10 @@ class CouponProgram(models.Model): @api.model def _filter_on_validity_dates(self, order): return self.filtered(lambda program: - program.rule_date_from and program.rule_date_to and - program.rule_date_from <= order.date_order and program.rule_date_to >= order.date_order or - not program.rule_date_from or not program.rule_date_to) + (not program.rule_date_from or program.rule_date_from <= order.date_order) + and + (not program.rule_date_to or program.rule_date_to >= order.date_order) + ) @api.model def _filter_promo_programs_with_code(self, order): diff --git a/addons/sale_coupon/tests/test_program_rules.py b/addons/sale_coupon/tests/test_program_rules.py index 5a2c18e7faf..d7dc74f5340 100644 --- a/addons/sale_coupon/tests/test_program_rules.py +++ b/addons/sale_coupon/tests/test_program_rules.py @@ -173,6 +173,59 @@ class TestProgramRules(TestSaleCouponCommon): order.recompute_coupon_lines() self.assertEqual(len(order.order_line.ids), 2, "The promo offert shouldn't have been applied as the number of uses is exceeded") + def test_program_rules_one_date(self): + # Test case: Based on the validity dates and the number of allowed uses + + # VFE NOTE the .rule_id is necessary to ensure the dates constraints doesn't raise + # because the orm applies the related inverse one by one, raising the constraint... + self.immediate_promotion_program.rule_id.write({ + 'rule_date_from': False, + 'rule_date_to': Date.to_string((datetime.now() - timedelta(days=2))), + }) + + order = self.empty_order + order.write({'order_line': [ + (0, False, { + 'product_id': self.product_A.id, + 'name': '1 Product A', + 'product_uom': self.uom_unit.id, + 'product_uom_qty': 1.0, + }), + (0, False, { + 'product_id': self.product_B.id, + 'name': '2 Product B', + 'product_uom': self.uom_unit.id, + 'product_uom_qty': 1.0, + }) + ]}) + order.recompute_coupon_lines() + self.assertNotIn(self.immediate_promotion_program, order._get_applicable_programs()) + self.assertEqual(len(order.order_line.ids), 2, "The promo offert shouldn't have been applied we're not between the validity dates") + + self.immediate_promotion_program.rule_id.write({ + 'rule_date_from': Date.to_string((datetime.now() + timedelta(days=1))), + 'rule_date_to': False, + }) + order.recompute_coupon_lines() + self.assertNotIn(self.immediate_promotion_program, order._get_applicable_programs()) + self.assertEqual(len(order.order_line.ids), 2, "The promo offert shouldn't have been applied we're not between the validity dates") + + self.immediate_promotion_program.rule_id.write({ + 'rule_date_from': False, + 'rule_date_to': Date.to_string((datetime.now() + timedelta(days=2))), + }) + order.recompute_coupon_lines() + self.assertIn(self.immediate_promotion_program, order._get_applicable_programs()) + self.assertEqual(len(order.order_line.ids), 3, "The promo offer should have been applied as we're between the validity dates") + + self.immediate_promotion_program.rule_id.write({ + 'rule_date_from': Date.to_string((datetime.now() - timedelta(days=1))), + 'rule_date_to': False, + }) + order.recompute_coupon_lines() + self.assertIn(self.immediate_promotion_program, order._get_applicable_programs()) + self.assertEqual(len(order.order_line.ids), 3, "The promo offer should have been applied as we're between the validity dates") + def test_program_rules_coupon_qty_and_amount_remove_not_eligible(self): ''' This test will: * Check quantity and amount requirements works as expected (since it's slightly different from a promotion_program)