From 4e81ca7814a9ac6a8eef7e8a1a491ef3b4668557 Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Wed, 28 Mar 2018 18:00:48 +0200 Subject: [PATCH] [FIX] sale_coupon(_delivery): correct discount when specific product Before this commit: 1. With a coupon set on 'specific_product', the discount amount was multiplied by the product quantity twice. (Introduced by a42c27f which apply discount on the full price by using price_total (already multiplied by quantity) over price_unit. 2. With a coupon set on 'cheapest_product', the discount was not discounting taxes. 3. With a coupon set on 'cheapest_product' and `sale_coupon_delivery` installed, it would simply crashes and throws an error since `sale.order.line` has no `program_id` attribute. Now: 1. We no longer multiply by the quantity twice; 2. We apply discount on the full price (with taxes); 3. We use correct attribute to avoid crash. opw-1830986 --- models/sale_order.py | 3 ++- tests/test_free_shipping_reward.py | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/models/sale_order.py b/models/sale_order.py index 7be352afd52..e0f91648823 100644 --- a/models/sale_order.py +++ b/models/sale_order.py @@ -41,7 +41,8 @@ class SaleOrder(models.Model): } def _get_lines_unit_prices(self): - return [x.price_unit for x in self.order_line.filtered(lambda x: not x.is_delivery and not x.program_id)] + # Unit prices tax included + return [x.price_total / x.product_uom_qty for x in self.order_line.filtered(lambda x: not x.is_delivery and not x.is_reward_line)] class SalesOrderLine(models.Model): _inherit = "sale.order.line" diff --git a/tests/test_free_shipping_reward.py b/tests/test_free_shipping_reward.py index 2f69ec8e802..5c8cce3d1a4 100644 --- a/tests/test_free_shipping_reward.py +++ b/tests/test_free_shipping_reward.py @@ -180,4 +180,18 @@ class TestSaleCouponProgramRules(TestSaleCouponCommon): self.assertEqual(len(order.order_line.ids), 4, "We should get a free iPad Mini") self.assertEqual(order.reward_amount, -20 -290.91) self.assertEqual(sum([line.price_total for line in order._get_no_effect_on_threshold_lines()]), 0) - self.assertEqual(order.amount_untaxed, 872.73) \ No newline at end of file + self.assertEqual(order.amount_untaxed, 872.73) + + p_specific_product = 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': 'cheapest_product', + }) + p_specific_product.discount_apply_on = 'cheapest_product' + order.recompute_coupon_lines() + # 872.73 - (20% of 1 iPad) = 872.73 - 64 = 808.73 + self.assertEqual(order.amount_untaxed, 808.73, "One iPad should be discounted by 20%")