From 231669e33269257d1539c9a1f13189a332dda668 Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Mon, 12 Nov 2018 15:24:24 +0100 Subject: [FIX] sale_coupon: remove coupon_program reward if req. not met anymore Before this commit: If a reward had been given on the SO with a coupon_program code and that the program had requirements and that these requirements are not met anymore, recomputing the SO would not remove the reward. Now: If the SO does not met the program requirements anymore, we remove the reward Step to reproduce: - Create a coupon_program with quantity or amount requirements (eg: $200) - Generate a coupon for that program - Add $200 worth of products (matching the program domain) in the SO - Add the generated coupon to that SO - You should get the reward as you have $200 in the SO - Remove some products from the SO to go below $200 - Recompute coupons, the reward won't be removed Closes #3062 --- tests/test_program_rules.py | 67 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'tests/test_program_rules.py') diff --git a/tests/test_program_rules.py b/tests/test_program_rules.py index 181b5adb07e..5339e00cb05 100644 --- a/tests/test_program_rules.py +++ b/tests/test_program_rules.py @@ -4,6 +4,7 @@ from datetime import datetime, timedelta from openerp.addons.sale_coupon.tests.common import TestSaleCouponCommon +from odoo.exceptions import UserError from odoo.fields import Date class TestProgramRules(TestSaleCouponCommon): @@ -171,3 +172,69 @@ 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_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) + * Ensure that if a reward from a coupon_program was allowed and the conditions are not met anymore, + the reward will be removed on recompute. + ''' + self.immediate_promotion_program.active = False # Avoid having this program to add rewards on this test + order = self.empty_order + + program = self.env['sale.coupon.program'].create({ + 'name': 'Get 10% discount if buy at least 4 Product A and $320', + 'program_type': 'coupon_program', + 'reward_type': 'discount', + 'discount_type': 'percentage', + 'discount_percentage': 10.0, + 'rule_products_domain': "[('id', 'in', [%s])]" % (self.product_A.id), + 'rule_min_quantity': 3, + 'rule_minimum_amount': 320.00, + }) + + sol1 = self.env['sale.order.line'].create({ + 'product_id': self.product_A.id, + 'name': 'Product A', + 'product_uom_qty': 2.0, + 'order_id': order.id, + }) + + sol2 = self.env['sale.order.line'].create({ + 'product_id': self.product_B.id, + 'name': 'Product B', + 'product_uom_qty': 4.0, + 'order_id': order.id, + }) + + # Default value for coupon generate wizard is generate by quantity and generate only one coupon + self.env['sale.coupon.generate'].with_context(active_id=program.id).create({}).generate_coupon() + coupon = program.coupon_ids[0] + + # Not enough amount since we only have 220 (100*2 + 5*4) + with self.assertRaises(UserError): + self.env['sale.coupon.apply.code'].with_context(active_id=order.id).create({ + 'coupon_code': coupon.code + }).process_coupon() + + sol2.product_uom_qty = 24 + + # Not enough qty since we only have 3 Product A (Amount is ok: 100*2 + 5*24 = 320) + with self.assertRaises(UserError): + self.env['sale.coupon.apply.code'].with_context(active_id=order.id).create({ + 'coupon_code': coupon.code + }).process_coupon() + + sol1.product_uom_qty = 3 + + self.env['sale.coupon.apply.code'].with_context(active_id=order.id).create({ + 'coupon_code': coupon.code + }).process_coupon() + order.recompute_coupon_lines() + + self.assertEqual(len(order.order_line.ids), 3, "The order should contains the Product A line, the Product B line and the discount line") + + sol1.product_uom_qty = 2 + order.recompute_coupon_lines() + + self.assertEqual(len(order.order_line.ids), 2, "The discount line should have been removed as we don't meet the program requirements") -- cgit v1.2.3 From 63131c258486002831cfbfa980214233fad201f9 Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Mon, 12 Nov 2018 18:06:57 +0100 Subject: [FIX] sale_coupon: reset no more eligible applied coupon to Valid state Before this commit: When a coupon_program's coupon was giving a reward on a SO and then the recompute was removing that reward (eg the SO did not met the requirements anymore) the coupon would not be reset and would be lost. Now: If a coupon's reward got removed for some reason, the coupon got reset to a valid state (`new`) so it can be used again. Step to reproduce: - Generate a coupon from a coupon program that needs requirements (eg $300) - Add that coupon to a SO that has a total over $300 - Coupon is set as `used` and the reward is granted - Remove some products to set the SO total below $300 - Recompute coupon, the reward is correctly removed but the coupon is still set as `used` so it won't be usable again and is basically lost. Closes #3062 --- tests/test_program_rules.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tests/test_program_rules.py') diff --git a/tests/test_program_rules.py b/tests/test_program_rules.py index 5339e00cb05..727f71bcadc 100644 --- a/tests/test_program_rules.py +++ b/tests/test_program_rules.py @@ -233,8 +233,10 @@ class TestProgramRules(TestSaleCouponCommon): order.recompute_coupon_lines() self.assertEqual(len(order.order_line.ids), 3, "The order should contains the Product A line, the Product B line and the discount line") + self.assertEqual(coupon.state, 'used', "The coupon should be set to Consumed as it has been used") sol1.product_uom_qty = 2 order.recompute_coupon_lines() self.assertEqual(len(order.order_line.ids), 2, "The discount line should have been removed as we don't meet the program requirements") + self.assertEqual(coupon.state, 'new', "The coupon should be reset to Valid as it's reward got removed") -- cgit v1.2.3