[FIX] loyalty_delivery: ignore discounts for free delivery
Steps to reproduce: - Create a delivery free over 100$ - Create a discount that apply on all products for 90% - Create an SO for 200 $ Bug: the delivery is free although total amount is under 100$ Fix: Gift cards and eWallets should be taken into account because they are different way of payment the rest of discounts should be ignored opw-3382153 closes odoo/odoo#128795 X-original-commit: 22f5b5ce245a5ebdda0f39f291401fe5bd19e4dc Signed-off-by: Antoine Vandevenne (anv) <anv@odoo.com> Signed-off-by: Walid Hanniche (waha) <waha@odoo.com>
This commit is contained in:
@@ -9,5 +9,5 @@ class SaleOrder(models.Model):
|
||||
|
||||
def _compute_amount_total_without_delivery(self):
|
||||
self.ensure_one()
|
||||
lines = self.order_line.filtered(lambda l: l.coupon_id)
|
||||
lines = self.order_line.filtered(lambda l: l.coupon_id and l.coupon_id.program_type in ['ewallet', 'gift_card'])
|
||||
return super()._compute_amount_total_without_delivery() - sum(lines.mapped('price_unit'))
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests import common, Form
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.fields import Command
|
||||
from odoo.tests import common, Form
|
||||
|
||||
@common.tagged('post_install', '-at_install')
|
||||
class TestLoyaltyDeliveryCost(common.TransactionCase):
|
||||
@@ -17,28 +18,26 @@ class TestLoyaltyDeliveryCost(common.TransactionCase):
|
||||
})
|
||||
cls.product_4 = cls.env['product.product'].create({'name': 'A product to deliver'})
|
||||
cls.product_uom_unit = cls.env.ref('uom.product_uom_unit')
|
||||
|
||||
def test_delivery_cost_gift_card(self):
|
||||
"""
|
||||
A customer has a carrier with the amount greater than the one to have
|
||||
free shipping cost, then uses a gift card that lowers that amount to less
|
||||
than the threshold: the shipping cost should still be 0.0
|
||||
"""
|
||||
|
||||
product_delivery_free = self.env['product.product'].create({
|
||||
'name': 'Free Delivery Charges',
|
||||
cls.product_delivery = cls.env['product.product'].create({
|
||||
'name': 'Delivery Charges',
|
||||
'type': 'service',
|
||||
'list_price': 40.0,
|
||||
'categ_id': self.env.ref('delivery.product_category_deliveries').id,
|
||||
'categ_id': cls.env.ref('delivery.product_category_deliveries').id,
|
||||
})
|
||||
free_delivery = self.env['delivery.carrier'].create({
|
||||
cls.delivery_carrier = cls.env['delivery.carrier'].create({
|
||||
'name': 'Delivery Now Free Over 100',
|
||||
'fixed_price': 40,
|
||||
'delivery_type': 'fixed',
|
||||
'product_id': product_delivery_free.id,
|
||||
'product_id': cls.product_delivery.id,
|
||||
'free_over': True,
|
||||
'amount': 100,
|
||||
})
|
||||
|
||||
def test_delivery_cost_gift_card(self):
|
||||
"""
|
||||
Test that the order amount used to trigger the free delivery doesn't consider gift cards.
|
||||
"""
|
||||
|
||||
program_gift_card = self.env['loyalty.program'].create({
|
||||
'name': 'Gift Cards',
|
||||
'applies_on': 'future',
|
||||
@@ -53,35 +52,108 @@ class TestLoyaltyDeliveryCost(common.TransactionCase):
|
||||
})
|
||||
self.env['loyalty.generate.wizard'].with_context(active_id=program_gift_card.id).create({
|
||||
'coupon_qty': 1,
|
||||
'points_granted': 40,
|
||||
'points_granted': 200,
|
||||
}).generate_coupons()
|
||||
gift_card = program_gift_card.coupon_ids[0]
|
||||
|
||||
|
||||
sale_normal_delivery_charges = self.SaleOrder.create({
|
||||
order = self.SaleOrder.create({
|
||||
'partner_id': self.partner_1.id,
|
||||
'partner_invoice_id': self.partner_1.id,
|
||||
'partner_shipping_id': self.partner_1.id,
|
||||
'pricelist_id': self.pricelist.id,
|
||||
'order_line': [(0, 0, {
|
||||
'name': 'PC Assamble + 2GB RAM',
|
||||
'product_id': self.product_4.id,
|
||||
'product_uom_qty': 1,
|
||||
'product_uom': self.product_uom_unit.id,
|
||||
'price_unit': 120.00,
|
||||
})]
|
||||
'order_line': [Command.create({'product_id': self.product_4.id, 'price_unit': 200.00})]
|
||||
})
|
||||
self._apply_promo_code(sale_normal_delivery_charges, gift_card.code)
|
||||
sale_normal_delivery_charges.action_confirm()
|
||||
self._apply_promo_code(order, gift_card.code)
|
||||
order.action_confirm()
|
||||
|
||||
delivery_wizard = Form(self.env['choose.delivery.carrier'].with_context({
|
||||
'default_order_id': sale_normal_delivery_charges.id,
|
||||
'default_carrier_id': free_delivery.id,
|
||||
'default_order_id': order.id, 'default_carrier_id': self.delivery_carrier.id,
|
||||
}))
|
||||
delivery_wizard.save().button_confirm()
|
||||
|
||||
self.assertEqual(len(sale_normal_delivery_charges.order_line), 3)
|
||||
self.assertEqual(sale_normal_delivery_charges.amount_untaxed, 80.0, "Delivery cost is not Added")
|
||||
self.assertEqual(order.order_line.filtered('is_delivery').price_total, 0)
|
||||
|
||||
|
||||
def test_free_delivery_cost_with_ewallet(self):
|
||||
"""
|
||||
Automatic free shipping of a delivery carrier should not be affected by the
|
||||
use of an ewallet when paying.
|
||||
Paying for an order of value 200 with an ewallet should still trigger the
|
||||
free shipping of the selected carrier if the free shipping is for amounts
|
||||
over 100.
|
||||
"""
|
||||
|
||||
# Create an eWallet Program and its corresponding rewards and coupons.
|
||||
program_ewallet = self.env['loyalty.program'].create({
|
||||
'name': 'eWallet',
|
||||
'program_type': 'ewallet',
|
||||
'reward_ids': [Command.create({
|
||||
'reward_type': 'discount',
|
||||
'discount_mode': 'per_point',
|
||||
'discount': 1,
|
||||
'discount_applicability': 'order',
|
||||
'required_points': 1,
|
||||
})],
|
||||
})
|
||||
self.env['loyalty.generate.wizard'].with_context(active_id=program_ewallet.id).create({
|
||||
'coupon_qty': 1,
|
||||
'points_granted': 200,
|
||||
}).generate_coupons()
|
||||
reward_ewallet = program_ewallet.reward_ids[0]
|
||||
ewallet = program_ewallet.coupon_ids[0]
|
||||
|
||||
# Create an order and pay with the ewallet.
|
||||
order = self.SaleOrder.create({
|
||||
'partner_id': self.partner_1.id,
|
||||
'pricelist_id': self.pricelist.id,
|
||||
'order_line': [Command.create({'product_id': self.product_4.id, 'price_unit': 200.00})]
|
||||
})
|
||||
order._apply_program_reward(reward_ewallet, ewallet)
|
||||
|
||||
delivery_wizard = Form(self.env['choose.delivery.carrier'].with_context({
|
||||
'default_order_id': order.id, 'default_carrier_id': self.delivery_carrier.id,
|
||||
}))
|
||||
delivery_wizard.save().button_confirm()
|
||||
|
||||
self.assertEqual(order.order_line.filtered('is_delivery').price_total, 0)
|
||||
|
||||
def test_delivery_cost_discounts(self):
|
||||
"""
|
||||
make sure discounts aren't taken into account for free delivery
|
||||
"""
|
||||
discount90 = self.env['loyalty.program'].create({
|
||||
'name': '90% Discount',
|
||||
'program_type': 'coupons',
|
||||
'applies_on': 'current',
|
||||
'trigger': 'auto',
|
||||
'rule_ids': [(0, 0, {})],
|
||||
'reward_ids': [(0, 0, {
|
||||
'reward_type': 'discount',
|
||||
'discount': 90,
|
||||
'discount_mode': 'percent',
|
||||
'discount_applicability': 'order',
|
||||
})]
|
||||
})
|
||||
|
||||
# Create an order and apply discount.
|
||||
order = self.SaleOrder.create({
|
||||
'partner_id': self.partner_1.id,
|
||||
'pricelist_id': self.pricelist.id,
|
||||
'order_line': [Command.create({'product_id': self.product_4.id, 'price_unit': 200.00,})]
|
||||
})
|
||||
order._update_programs_and_rewards()
|
||||
coupon = order.coupon_point_ids.coupon_id.filtered(lambda c: c.program_id == discount90)
|
||||
order._apply_program_reward(discount90.reward_ids, coupon)
|
||||
order.action_confirm()
|
||||
|
||||
delivery_wizard = Form(self.env['choose.delivery.carrier'].with_context({
|
||||
'default_order_id': order.id, 'default_carrier_id': self.delivery_carrier.id,
|
||||
}))
|
||||
delivery_wizard.save().button_confirm()
|
||||
|
||||
self.assertEqual(
|
||||
order.order_line.filtered('is_delivery').price_unit,
|
||||
self.product_delivery.list_price
|
||||
)
|
||||
|
||||
|
||||
def _apply_promo_code(self, order, code, no_reward_fail=True):
|
||||
status = order._try_apply_code(code)
|
||||
|
||||
Reference in New Issue
Block a user