[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
This commit is contained in:
Romain Derie
2018-03-29 13:14:06 +02:00
parent bc75ec7c14
commit 4e81ca7814
2 changed files with 17 additions and 2 deletions
+2 -1
View File
@@ -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"
+15 -1
View File
@@ -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)
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%")