From f92f361d68df68c21a2660af082c392e8eb00d2a Mon Sep 17 00:00:00 2001 From: Victor Feyens Date: Wed, 7 Oct 2020 14:01:33 +0000 Subject: [PATCH] [FIX] sale_coupon: wrong filtering domain If only one of the two dates rules fields is specified, it won't be considered when filtering coupon programs, and the program will always be considered valid... This commit reorder the conditon to correctly consider both fields: rule_date_from and rule_date_to, even if only one of the two field is set. X-original-commit: 871a118d2c72f58185cbf822375282b613e67337 --- addons/sale_coupon/models/coupon_program.py | 7 +-- .../sale_coupon/tests/test_program_rules.py | 53 +++++++++++++++++++ 2 files changed, 57 insertions(+), 3 deletions(-) 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)