[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:
Walid HANNICHE (waha)
2023-07-17 20:36:09 +02:00
parent 1e12962743
commit cd93450aa7
2 changed files with 105 additions and 33 deletions
+1 -1
View File
@@ -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)