From 453d8ce703d88d535edc82fe01c0891ee5db1197 Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Tue, 24 Apr 2018 13:54:25 +0200 Subject: [FIX] sale_coupon: add tests Previous commit fixed some bugs on `sale_coupon` (#2224). This commit add some tests to be sure these bugs are fixed and won't appear again. task-1866977 Related to #2224 --- tests/test_program_numbers.py | 277 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 266 insertions(+), 11 deletions(-) (limited to 'tests/test_program_numbers.py') diff --git a/tests/test_program_numbers.py b/tests/test_program_numbers.py index 9a698f3cf9b..6b2c29d6050 100644 --- a/tests/test_program_numbers.py +++ b/tests/test_program_numbers.py @@ -2,6 +2,8 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from openerp.addons.sale_coupon.tests.common import TestSaleCouponCommon +from odoo.exceptions import UserError + class TestSaleCouponProgramNumbers(TestSaleCouponCommon): @@ -9,6 +11,8 @@ class TestSaleCouponProgramNumbers(TestSaleCouponCommon): super(TestSaleCouponProgramNumbers, self).setUp() self.iPadMini = self.env.ref('product.product_product_6').copy() + self.iPod = self.env.ref('product.product_product_11').copy() + self.wirelessKeyboard = self.env.ref('product.product_product_9').copy() self.computerCase = self.env.ref('product.product_product_16').copy() self.littleServer = self.env.ref('product.consu_delivery_02').copy() self.steve = self.env['res.partner'].create({ @@ -64,7 +68,7 @@ class TestSaleCouponProgramNumbers(TestSaleCouponCommon): self.env['sale.coupon.apply.code'].sudo().apply_coupon(order, 'test_10pc') self.assertEqual(len(order.order_line.ids), 3, "We should 3 lines as we should have a new line for promo code reduction") self.assertEqual(order.amount_total, 864, "Only paid product should have their price discounted") - order.order_line.filtered(lambda x: 'Discount' in x.name).unlink() # Remove Discount + order.order_line.filtered(lambda x: 'Discount' in x.name).unlink() # Remove Discount # Check free product is removed since we are below minimum required quantity sol1.product_uom_qty = 3 @@ -113,7 +117,7 @@ class TestSaleCouponProgramNumbers(TestSaleCouponCommon): self.assertEqual(len(order.order_line.ids), 4, "We should have 4 lines as we should have a new line for promo code reduction") # Check you can still have auto applied promotion if you have a promo code set to the order - sol4 = self.env['sale.order.line'].create({ + self.env['sale.order.line'].create({ 'product_id': self.iPadMini.id, 'name': 'iPad Mini', 'product_uom_qty': 4.0, @@ -155,11 +159,16 @@ class TestSaleCouponProgramNumbers(TestSaleCouponCommon): sol1._compute_tax_id() order.recompute_coupon_lines() self.assertEqual(len(order.order_line.ids), 2, "We should now get the reduction line since we have 320$ tax included (ipad is 320$ tax included)") - # (320 +15% tax) - (20% of (320 + 15% tax) = 368 + 73.6 = 294.4 + # Name | Qty | price_unit | Tax | HTVA | TVAC | TVA | + # -------------------------------------------------------------------------------- + # iPod | 1 | 320.00 | 15% excl | 320.00 | 368.00 | 48.00 + # 20% discount on ipad | 1 | -64.00 | 15% excl | -64.00 | -73.60 | -9.60 + # -------------------------------------------------------------------------------- + # TOTAL | 256.00 | 294.40 | 38.40 self.assertEqual(order.amount_total, 294.4, "Check discount has been applied correctly (eg: on taxes aswell)") # test coupon with code works the same as auto applied_programs - p_specific_product.write({'promo_code_usage':'code_needed', 'promo_code':'20pc'}) + p_specific_product.write({'promo_code_usage': 'code_needed', 'promo_code': '20pc'}) order.order_line.filtered(lambda l: l.is_reward_line).unlink() order.recompute_coupon_lines() self.assertEqual(len(order.order_line.ids), 1, "Reduction should be removed since we deleted it and it is now a promo code usage, it shouldn't be automatically reapplied") @@ -168,21 +177,267 @@ class TestSaleCouponProgramNumbers(TestSaleCouponCommon): order.recompute_coupon_lines() self.assertEqual(len(order.order_line.ids), 2, "We should now get the reduction line since we have 320$ tax included (ipad is 320$ tax included)") - #check discount applied only on ipad - sol2 = self.env['sale.order.line'].create({ + # check discount applied only on ipad + self.env['sale.order.line'].create({ 'product_id': self.computerCase.id, 'name': 'Computer Case', 'product_uom_qty': 10.0, 'order_id': order.id, }) order.recompute_coupon_lines() - # (10x25) + (320 +15% tax) - (20% of (320 + 15% tax) = 250 + 368 - 73.6 = 544.4 + # Name | Qty | price_unit | Tax | HTVA | TVAC | TVA | + # -------------------------------------------------------------------------------- + # Computer Case | 10 | 25.00 | / | 250.00 | 250.00 | / + # iPad | 1 | 320.00 | 15% excl | 320.00 | 368.00 | 48.00 + # 20% discount on ipad | 1 | -64.00 | 15% excl | -64.00 | -73.60 | -9.60 + # -------------------------------------------------------------------------------- + # TOTAL | 506.00 | 544.40 | 38.40 self.assertEqual(order.amount_total, 544.4, "We should only get reduction on ipad") sol1.product_uom_qty = 10 order.recompute_coupon_lines() - # (10x25) + (10x (320 +15% tax)) - (20% of (10x (320 + 15% tax))) - 2 free iPads = 250 + 3680 - 736 - 736 = 2458 - self.assertEqual(order.amount_total, 2458, "Changing ipad quantity should change discount amount correctly") - + # Note: Since we now have 2 free ipads, we should discount only 8 of the 10 ipads in carts since we don't want to discount free ipads + # Name | Qty | price_unit | Tax | HTVA | TVAC | TVA | + # -------------------------------------------------------------------------------- + # Computer Case | 10 | 25.00 | / | 250.00 | 250.00 | / + # iPad | 10 | 320.00 | 15% excl | 3200.00 | 3680.00 | 480.00 + # Free iPad | 2 | -320.00 | 15% excl | -640.00 | -736.00 | -96.00 + # 20% discount on ipad | 1 | -512.00 | 15% excl | -512.00 | -588.80 | -78.80 + # -------------------------------------------------------------------------------- + # TOTAL | 2298.00 | 2605.20 | 305.20 + self.assertEqual(order.amount_total, 2605.20, "Changing ipad quantity should change discount amount correctly") p_specific_product.discount_max_amount = 200 order.recompute_coupon_lines() - self.assertEqual(order.amount_total, 2994, "The discount should be limited to $200") + # Name | Qty | price_unit | Tax | HTVA | TVAC | TVA | + # -------------------------------------------------------------------------------- + # Computer Case | 10 | 25.00 | / | 250.00 | 250.00 | / + # iPad | 10 | 320.00 | 15% excl | 3200.00 | 3680.00 | 480.00 + # Free iPad | 2 | -320.00 | 15% excl | -640.00 | -736.00 | -96.00 + # 20% discount on ipad | 1 | -200.00 | 15% excl | -200.00 | -230.00 | -30.00 + # limited to 200 HTVA + # -------------------------------------------------------------------------------- + # TOTAL | 2610.00 | 2964.00 | 354.00 + self.assertEqual(order.amount_total, 2964, "The discount should be limited to $200 tax excluded") + self.assertEqual(order.amount_untaxed, 2610, "The discount should be limited to $200 tax excluded (2)") + + def test_program_numbers_one_discount_line_per_tax(self): + order = self.empty_order + # Create taxes + self.tax_15pc_excl = self.env['account.tax'].create({ + 'name': "15% Tax excl", + 'amount_type': 'percent', + 'amount': 15, + }) + self.tax_50pc_excl = self.env['account.tax'].create({ + 'name': "50% Tax excl", + 'amount_type': 'percent', + 'amount': 50, + }) + self.tax_35pc_incl = self.env['account.tax'].create({ + 'name': "35% Tax incl", + 'amount_type': 'percent', + 'amount': 35, + 'price_include': True, + }) + + # Set tax and prices on products as neeed for the test + (self.product_A + self.iPadMini + self.iPod + self.wirelessKeyboard + self.computerCase).write({'list_price': 100}) + (self.iPadMini + self.computerCase).write({'taxes_id': [(4, self.tax_15pc_excl.id, False)]}) + self.iPod.taxes_id = self.tax_10pc_incl + self.wirelessKeyboard.taxes_id = None + self.product_A.taxes_id = (self.tax_35pc_incl + self.tax_50pc_excl) + + # Add products in order + self.env['sale.order.line'].create({ + 'product_id': self.iPadMini.id, + 'name': 'iPad', + 'product_uom_qty': 7.0, + 'order_id': order.id, + }) + sol2 = self.env['sale.order.line'].create({ + 'product_id': self.iPod.id, + 'name': 'iPod', + 'product_uom_qty': 5.0, + 'order_id': order.id, + }) + self.env['sale.order.line'].create({ + 'product_id': self.wirelessKeyboard.id, + 'name': 'Wireless Keyboard', + 'product_uom_qty': 10.0, + 'order_id': order.id, + }) + self.env['sale.order.line'].create({ + 'product_id': self.product_A.id, + 'name': 'product A with multiple taxes', + 'product_uom_qty': 3.0, + 'order_id': order.id, + }) + self.env['sale.order.line'].create({ + 'product_id': self.computerCase.id, + 'name': 'Computer Case', + 'product_uom_qty': 2.0, + 'order_id': order.id, + }) + + # Create needed programs + self.p2.active = False + self.p_ipad = self.env['sale.coupon.program'].create({ + 'name': 'Buy 1 ipad, get one for free', + 'promo_code_usage': 'no_code_needed', + 'reward_type': 'product', + 'program_type': 'promotion_program', + 'reward_product_id': self.iPadMini.id, + 'rule_products_domain': '[["name","ilike","ipad mini"]]', + }) + self.p_ipod = self.env['sale.coupon.program'].create({ + 'name': 'Buy 1 ipod, get one for free', + 'promo_code_usage': 'no_code_needed', + 'reward_type': 'product', + 'program_type': 'promotion_program', + 'reward_product_id': self.iPod.id, + 'rule_products_domain': '[["name","ilike","ipod"]]', + }) + self.p_keyboard = self.env['sale.coupon.program'].create({ + 'name': 'Buy 1 keyboard, get one for free', + 'promo_code_usage': 'no_code_needed', + 'reward_type': 'product', + 'program_type': 'promotion_program', + 'reward_product_id': self.wirelessKeyboard.id, + 'rule_products_domain': '[["name","ilike","keyboard"]]', + }) + + # Name | Qty | price_unit | Tax | HTVA | TVAC | TVA | + # -------------------------------------------------------------------------------- + # iPod | 5 | 100.00 | 10% incl | 454.55 | 500.00 | 45.45 + # Keyboards | 10 | 100.00 | / | 1000.00 | 1000.00 | / + # iPad | 7 | 100.00 | 15% excl | 700.00 | 805.00 | 105.00 + # Computer Case | 2 | 100.00 | 15% excl | 200.00 | 230.00 | 30.00 + # Product A | 3 | 100.00 | 35% incl | 222.22 | 450.00 | 227.78 + # 50% excl + # -------------------------------------------------------------------------------- + # TOTAL | 2576.77 | 2985.00 | 408.23 + + self.assertEqual(order.amount_total, 2985, "The order total without any programs should be 2985") + self.assertEqual(order.amount_untaxed, 2576.77, "The order untaxed total without any programs should be 2576.77") + self.assertEqual(len(order.order_line.ids), 5, "The order without any programs should have 5 lines") + + # Apply all the programs + order.recompute_coupon_lines() + + # Name | Qty | price_unit | Tax | HTVA | TVAC | TVA | + # -------------------------------------------------------------------------------- + # Free iPod | 2 | -100.00 | 10% incl | -181.82 | -200.00 | -18.18 + # Free Keyboard | 5 | -100.00 | / | -500.00 | -500.00 | / + # Free iPad | 3 | -100.00 | 15% excl | -300.00 | -345.00 | -45.00 + # -------------------------------------------------------------------------------- + # TOTAL AFTER APPLYING FREE PRODUCT PROGRAMS | 1594.95 | 1940.00 | 345.05 + + self.assertEqual(order.amount_total, 1940.00, "The order total with programs should be 1940") + self.assertEqual(order.amount_untaxed, 1594.95, "The order untaxed total with programs should be 1594.95") + self.assertEqual(len(order.order_line.ids), 8, "Order should contains 5 regular product lines and 3 free product lines") + + # Apply 10% on top of everything + self.env['sale.coupon.apply.code'].sudo().apply_coupon(order, 'test_10pc') + + # Name | Qty | price_unit | Tax | HTVA | TVAC | TVA | + # -------------------------------------------------------------------------------- + # 10% on tax 10% incl | 1 | -30.00 | 10% incl | -27.27 | -30.00 | -2.73 + # 10% on no tax | 1 | -50.00 | / | -50.00 | -50.00 | / + # 10% on tax 15% excl | 1 | -40.00 | 15% excl | -60.00 | -69.00 | -9.00 + # 10% on tax 35%+50% | 1 | -30.00 | 35% incl | -22.22 | -45.00 | -22.78 + # 50% excl + # -------------------------------------------------------------------------------- + # TOTAL AFTER APPLYING 10% GLOBAL PROGRAM | 1435.46 | 1746.00 | -310.55 + + self.assertEqual(order.amount_total, 1746, "The order total with programs should be 1746") + self.assertEqual(order.amount_untaxed, 1435.46, "The order untaxed total with programs should be 1435.46") + self.assertEqual(len(order.order_line.ids), 12, "Order should contains 5 regular product lines, 3 free product lines and 4 discount lines (one for every tax)") + + # Now we want to apply a 20% discount only on iPad + self.env['sale.coupon.program'].create({ + 'name': '20% reduction on ipad in cart', + 'promo_code_usage': 'no_code_needed', + 'reward_type': 'discount', + 'program_type': 'promotion_program', + 'discount_type': 'percentage', + 'discount_percentage': 20.0, + 'discount_apply_on': 'specific_product', + 'discount_specific_product_id': self.iPadMini.id, + }) + order.recompute_coupon_lines() + # Note: we have 7 regular ipads and 3 free ipads. We should then discount only 4 really paid iPads + + # Name | Qty | price_unit | Tax | HTVA | TVAC | TVA | + # -------------------------------------------------------------------------------- + # 20% on iPad | 1 | -80.00 | 15% excl | -80.00 | -92.00 | -12.00 + # -------------------------------------------------------------------------------- + # TOTAL AFTER APPLYING 20% ON IPAD | 1355.45 | 1654.00 | -298.55 + + self.assertEqual(order.amount_total, 1654, "The order total with programs should be 1654") + self.assertEqual(order.amount_untaxed, 1355.46, "The order untaxed total with programs should be 1435.45") + self.assertEqual(len(order.order_line.ids), 13, "Order should have a new discount line for 20% on iPad") + + # Check that if you delete one of the discount tax line and recompute, it got added back. + order.order_line.filtered(lambda l: '10%' in l.name)[0].unlink() + self.assertEqual(len(order.order_line.ids), 12, "One of the 10% discount line per tax should be removed") + order.recompute_coupon_lines() + self.assertEqual(len(order.order_line.ids), 13, "The 10% discount line that got removed should be recomputed and added back") + + # Check that if you change a product qty, his discount tax line got updated + sol2.product_uom_qty = 7 + order.recompute_coupon_lines() + # iPod | 5 | 100.00 | 10% incl | 454.55 | 500.00 | 45.45 + # Free iPod | 2 | -100.00 | 10% incl | -181.82 | -200.00 | -18.18 + # 10% on tax 10% incl | 1 | -30.00 | 10% incl | -27.27 | -30.00 | -2.73 + # -------------------------------------------------------------------------------- + # TOTAL OF IPOD LINES | 245.46 | 270.00 | 24.54 + # ==> Should become: + # iPod | 7 | 100.00 | 10% incl | 636.36 | 700.00 | 63.64 + # Free iPod | 3 | -100.00 | 10% incl | -272.73 | -300.00 | -27.27 + # 10% on tax 10% incl | 1 | -40.00 | 10% incl | -36.36 | -40.00 | -3.64 + # -------------------------------------------------------------------------------- + # TOTAL OF IPOD LINES AFTER ADDING 2 IPODS | 327.27 | 360.00 | 32.73 + # -------------------------------------------------------------------------------- + # => DIFFERENCES BEFORE/AFTER | 81.81 | 90.00 | 8.19 + self.assertEqual(order.amount_untaxed, 1355.46 + 81.81, "The order should have one more paid ipod with 10% incl tax and discounted by 10%") + + # Check that if you remove a product, his reward lines got removed, especially the discount per tax one + sol2.unlink() + order.recompute_coupon_lines() + # Name | Qty | price_unit | Tax | HTVA | TVAC | TVA | + # -------------------------------------------------------------------------------- + # Keyboards | 10 | 100.00 | / | 1000.00 | 1000.00 | / + # iPad | 7 | 100.00 | 15% excl | 700.00 | 805.00 | 105.00 + # Computer Case | 2 | 100.00 | 15% excl | 200.00 | 230.00 | 30.00 + # Product A | 3 | 100.00 | 35% incl | 222.22 | 450.00 | 227.78 + # 50% excl + # Free Keyboard | 5 | -100.00 | / | -500.00 | -500.00 | / + # Free iPad | 3 | -100.00 | 15% excl | -300.00 | -345.00 | -45.00 + # 10% on no tax | 1 | -50.00 | / | -50.00 | -50.00 | / + # 10% on tax 15% excl | 1 | -40.00 | 15% excl | -60.00 | -69.00 | -9.00 + # 10% on tax 35%+50% | 1 | -30.00 | 35% incl | -22.22 | -45.00 | -22.78 + # 50% excl + # 20% on iPad | 1 | -80.00 | 15% excl | -80.00 | -92.00 | -12.00 + # -------------------------------------------------------------------------------- + # TOTAL | 1110.00 | 1384.00 | 274.00 + self.assertEqual(order.amount_total, 1384, "The order total with programs should be 1654") + self.assertEqual(order.amount_untaxed, 1110, "The order untaxed total with programs should be 1435.45") + self.assertEqual(len(order.order_line.ids), 10, "Order should contains 10 lines: 4 products lines, 2 free products lines, 3 10% discount lines and a 20% discount line") + + def test_program_numbers_extras(self): + # Check that you can't apply a global discount promo code if there is already an auto applied global discount + self.p1.copy({'promo_code_usage': 'no_code_needed', 'name': 'Auto applied 10% global discount'}) + order = self.empty_order + self.env['sale.order.line'].create({ + 'product_id': self.iPadMini.id, + 'name': 'iPad', + 'product_uom_qty': 1.0, + 'order_id': order.id, + }) + order.recompute_coupon_lines() + self.assertEqual(len(order.order_line.ids), 2, "We should get 1 iPad line and 1 10% auto applied global discount line") + self.assertEqual(order.amount_total, 288, "320$ - 10%") + with self.assertRaises(UserError): + # Can't apply a second global discount + self.env['sale.coupon.apply.code'].with_context(active_id=order.id).create({ + 'coupon_code': 'test_10pc' + }).process_coupon() -- cgit v1.2.3 From 5ff0b842dfdc9ed1eefcb2638fb638084e1b1577 Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Wed, 16 May 2018 15:19:14 +0200 Subject: [FIX] sale_coupon: delete 'sibling' lines when deleting a reward line A discount on products with different taxes will result in as many discount lines as there is different taxes. Before this commit, removing one of these lines would not do anything else. Then, recomputing the coupon would regenerate/add back this line. On e-commerce, it means you would never be able to remove the program by deleting its reward lines if there are multiple taxes (and so multiple lines) since it would `recompute_coupon_lines` right away, adding it back directly. Now, this commit will ensure that removing one of these lines will also remove the other ones coming from this program on other taxes. It means removing a regular product will remove it's reward line that will also now remove the other program's discount line on other taxes and ultimately will remove the program from the SO since all the program reward lines got removed. (It won't affect auto applied program since it will be regenerated afterward) task-1866977 Related to #2224 --- tests/test_program_numbers.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'tests/test_program_numbers.py') diff --git a/tests/test_program_numbers.py b/tests/test_program_numbers.py index 6b2c29d6050..9d4c34f8070 100644 --- a/tests/test_program_numbers.py +++ b/tests/test_program_numbers.py @@ -376,11 +376,16 @@ class TestSaleCouponProgramNumbers(TestSaleCouponCommon): self.assertEqual(order.amount_untaxed, 1355.46, "The order untaxed total with programs should be 1435.45") self.assertEqual(len(order.order_line.ids), 13, "Order should have a new discount line for 20% on iPad") - # Check that if you delete one of the discount tax line and recompute, it got added back. + # Check that if you delete one of the discount tax line, the others tax lines from the same promotion got deleted as well. order.order_line.filtered(lambda l: '10%' in l.name)[0].unlink() - self.assertEqual(len(order.order_line.ids), 12, "One of the 10% discount line per tax should be removed") + self.assertEqual(len(order.order_line.ids), 9, "All of the 10% discount line per tax should be removed") + # At this point, removing the iPod's discount line (split per tax) removed also the others discount lines + # linked to the same program (eg: other taxes lines). So the coupon got removed from the SO since there were no discount lines left + + # Add back the coupon to continue the test flow + self.env['sale.coupon.apply.code'].sudo().apply_coupon(order, 'test_10pc') order.recompute_coupon_lines() - self.assertEqual(len(order.order_line.ids), 13, "The 10% discount line that got removed should be recomputed and added back") + self.assertEqual(len(order.order_line.ids), 13, "The 10% discount line should be back") # Check that if you change a product qty, his discount tax line got updated sol2.product_uom_qty = 7 @@ -412,16 +417,12 @@ class TestSaleCouponProgramNumbers(TestSaleCouponCommon): # 50% excl # Free Keyboard | 5 | -100.00 | / | -500.00 | -500.00 | / # Free iPad | 3 | -100.00 | 15% excl | -300.00 | -345.00 | -45.00 - # 10% on no tax | 1 | -50.00 | / | -50.00 | -50.00 | / - # 10% on tax 15% excl | 1 | -40.00 | 15% excl | -60.00 | -69.00 | -9.00 - # 10% on tax 35%+50% | 1 | -30.00 | 35% incl | -22.22 | -45.00 | -22.78 - # 50% excl # 20% on iPad | 1 | -80.00 | 15% excl | -80.00 | -92.00 | -12.00 # -------------------------------------------------------------------------------- - # TOTAL | 1110.00 | 1384.00 | 274.00 - self.assertEqual(order.amount_total, 1384, "The order total with programs should be 1654") - self.assertEqual(order.amount_untaxed, 1110, "The order untaxed total with programs should be 1435.45") - self.assertEqual(len(order.order_line.ids), 10, "Order should contains 10 lines: 4 products lines, 2 free products lines, 3 10% discount lines and a 20% discount line") + # TOTAL | 1242.22 | 1548.00 | 305.78 + self.assertEqual(order.amount_total, 1548, "The order total with programs should be 1548") + self.assertEqual(order.amount_untaxed, 1242.22, "The order untaxed total with programs should be 1242.22") + self.assertEqual(len(order.order_line.ids), 7, "Order should contains 7 lines: 4 products lines, 2 free products lines and a 20% discount line") def test_program_numbers_extras(self): # Check that you can't apply a global discount promo code if there is already an auto applied global discount -- cgit v1.2.3 From 452e90639668288665818a8767258a68a4098dc6 Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Mon, 10 Sep 2018 18:18:46 +0200 Subject: [FIX] (website_)sale_coupon: `_compute_tax_id` with tax on reward line It should get tax from the SOL and not the SO's product as the tax is applied on the SOL only (the reward product has no tax by default). --- tests/test_program_numbers.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'tests/test_program_numbers.py') diff --git a/tests/test_program_numbers.py b/tests/test_program_numbers.py index 9d4c34f8070..39f15fffb0e 100644 --- a/tests/test_program_numbers.py +++ b/tests/test_program_numbers.py @@ -352,6 +352,17 @@ class TestSaleCouponProgramNumbers(TestSaleCouponCommon): self.assertEqual(order.amount_untaxed, 1435.46, "The order untaxed total with programs should be 1435.46") self.assertEqual(len(order.order_line.ids), 12, "Order should contains 5 regular product lines, 3 free product lines and 4 discount lines (one for every tax)") + # -- This is a test inside the test + order.order_line._compute_tax_id() + self.assertEqual(order.amount_total, 1746, "Recomputing tax on sale order lines should not change total amount") + self.assertEqual(order.amount_untaxed, 1435.46, "Recomputing tax on sale order lines should not change untaxed amount") + self.assertEqual(len(order.order_line.ids), 12, "Recomputing tax on sale order lines should not change number of order line") + order.recompute_coupon_lines() + self.assertEqual(order.amount_total, 1746, "Recomputing tax on sale order lines should not change total amount") + self.assertEqual(order.amount_untaxed, 1435.46, "Recomputing tax on sale order lines should not change untaxed amount") + self.assertEqual(len(order.order_line.ids), 12, "Recomputing tax on sale order lines should not change number of order line") + # -- End test inside the test + # Now we want to apply a 20% discount only on iPad self.env['sale.coupon.program'].create({ 'name': '20% reduction on ipad in cart', -- cgit v1.2.3 From af0e47f42f89d624b4c0a74fc2ebb7eb1889da54 Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Fri, 28 Sep 2018 14:07:55 +0200 Subject: [FIX] sale_coupon: compute fixed amount as such Commit 092200073 broke the discount computation for discount of type fixed_amount. Indeed the appropriate method was not called anymore and such discount type would be computed as percentage discount with default value of 10% (field default for percentage). opw-1888484 --- tests/test_program_numbers.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'tests/test_program_numbers.py') diff --git a/tests/test_program_numbers.py b/tests/test_program_numbers.py index 39f15fffb0e..01da22c1de4 100644 --- a/tests/test_program_numbers.py +++ b/tests/test_program_numbers.py @@ -453,3 +453,30 @@ class TestSaleCouponProgramNumbers(TestSaleCouponCommon): self.env['sale.coupon.apply.code'].with_context(active_id=order.id).create({ 'coupon_code': 'test_10pc' }).process_coupon() + + def test_program_fixed_price(self): + # Check fixed amount discount + order = self.empty_order + fixed_amount_program = self.env['sale.coupon.program'].create({ + 'name': '$249 discount', + 'promo_code_usage': 'no_code_needed', + 'program_type': 'promotion_program', + 'discount_type': 'fixed_amount', + 'discount_fixed_amount': 249.0, + }) + sol1 = self.env['sale.order.line'].create({ + 'product_id': self.computerCase.id, + 'name': 'Computer Case', + 'product_uom_qty': 1.0, + 'order_id': order.id, + }) + order.recompute_coupon_lines() + self.assertEqual(order.amount_total, 0, "Total should be null. The fixed amount discount is higher than the SO total, it should be reduced to the SO total") + self.assertEqual(len(order.order_line.ids), 2, "There should be the product line and the reward line") + sol1.product_uom_qty = 17 + order.recompute_coupon_lines() + self.assertEqual(order.amount_total, 176, "Fixed amount discount should be totally deduced") + self.assertEqual(len(order.order_line.ids), 2, "Number of lines should be unchanged as we just recompute the reward line") + 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") -- cgit v1.2.3