[FIX] delivery_carrier,sale_giftcard: get the right shipping price even with gift card
Step: - Create a product with sale price 120 USD - Create a giftcard with balance 40 uSD - Create a free Shipping cost of 40 USD fixed price and freeing above 100 USD - Go to website->shop, select the product and checkout the cart(the shipping is free because price exceeds 100) - Add the gift card to payment Issue: The shipping price gets from free to 40 Cause: When computing the cost of the shipping the fact of the presence of a giftcard is not considered. Solution: Create a method to returns the amount of giftcard from a sale order and add to total price to check if the shipping is free opw-3107284 closes odoo/odoo#120174 X-original-commit: c57184fd1c3d2846df4f618dee0027364eb62596 Signed-off-by: William Braeckman (wbr) <wbr@odoo.com> Signed-off-by: Djoumatchoua Eteil Junior (etdj) <etdj@odoo.com>
This commit is contained in:
committed by
Eteil Djoumatchoua(etdj)
parent
13de009694
commit
171aa0ec25
@@ -208,7 +208,8 @@ class DeliveryCarrier(models.Model):
|
||||
# save the real price in case a free_over rule overide it to 0
|
||||
res['carrier_price'] = res['price']
|
||||
# free when order is large enough
|
||||
if res['success'] and self.free_over and order._compute_amount_total_without_delivery() >= self.amount:
|
||||
amount_without_delivery = order._compute_amount_total_without_delivery()
|
||||
if res['success'] and self.free_over and self._compute_currency(order, amount_without_delivery, 'pricelist_to_company') >= self.amount:
|
||||
res['warning_message'] = _('The shipping is free since the order amount exceeds %.2f.') % (self.amount)
|
||||
res['price'] = 0.0
|
||||
return res
|
||||
|
||||
@@ -23,7 +23,7 @@ class SaleOrder(models.Model):
|
||||
def _compute_amount_total_without_delivery(self):
|
||||
self.ensure_one()
|
||||
delivery_cost = sum([l.price_total for l in self.order_line if l.is_delivery])
|
||||
return self.env['delivery.carrier']._compute_currency(self, self.amount_total - delivery_cost, 'pricelist_to_company')
|
||||
return self.amount_total - delivery_cost
|
||||
|
||||
@api.depends('order_line')
|
||||
def _compute_delivery_state(self):
|
||||
|
||||
@@ -3,3 +3,4 @@
|
||||
|
||||
from . import loyalty_program
|
||||
from . import loyalty_reward
|
||||
from . import sale_order
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
class SaleOrder(models.Model):
|
||||
_inherit = "sale.order"
|
||||
|
||||
def _compute_amount_total_without_delivery(self):
|
||||
self.ensure_one()
|
||||
lines = self.order_line.filtered(lambda l: l.coupon_id)
|
||||
return super()._compute_amount_total_without_delivery() - sum(lines.mapped('price_unit'))
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_loyalty_delivery
|
||||
@@ -0,0 +1,101 @@
|
||||
# -*- 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
|
||||
|
||||
@common.tagged('post_install', '-at_install')
|
||||
class TestLoyaltyDeliveryCost(common.TransactionCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestLoyaltyDeliveryCost, cls).setUpClass()
|
||||
cls.SaleOrder = cls.env['sale.order']
|
||||
cls.partner_1 = cls.env['res.partner'].create({'name': 'My Test Customer'})
|
||||
cls.pricelist = cls.env['product.pricelist'].create({
|
||||
'name': 'Test Pricelist',
|
||||
})
|
||||
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',
|
||||
'type': 'service',
|
||||
'list_price': 40.0,
|
||||
'categ_id': self.env.ref('delivery.product_category_deliveries').id,
|
||||
})
|
||||
free_delivery = self.env['delivery.carrier'].create({
|
||||
'name': 'Delivery Now Free Over 100',
|
||||
'fixed_price': 40,
|
||||
'delivery_type': 'fixed',
|
||||
'product_id': product_delivery_free.id,
|
||||
'free_over': True,
|
||||
'amount': 100,
|
||||
})
|
||||
program_gift_card = self.env['loyalty.program'].create({
|
||||
'name': 'Gift Cards',
|
||||
'applies_on': 'future',
|
||||
'program_type': 'gift_card',
|
||||
'trigger': 'auto',
|
||||
'reward_ids': [(0, 0, {
|
||||
'reward_type': 'discount',
|
||||
'discount': 1,
|
||||
'discount_mode': 'per_point',
|
||||
'discount_applicability': 'order',
|
||||
})]
|
||||
})
|
||||
self.env['loyalty.generate.wizard'].with_context(active_id=program_gift_card.id).create({
|
||||
'coupon_qty': 1,
|
||||
'points_granted': 40,
|
||||
}).generate_coupons()
|
||||
gift_card = program_gift_card.coupon_ids[0]
|
||||
|
||||
|
||||
sale_normal_delivery_charges = 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,
|
||||
})]
|
||||
})
|
||||
self._apply_promo_code(sale_normal_delivery_charges, gift_card.code)
|
||||
sale_normal_delivery_charges.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,
|
||||
}))
|
||||
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")
|
||||
|
||||
def _apply_promo_code(self, order, code, no_reward_fail=True):
|
||||
status = order._try_apply_code(code)
|
||||
if 'error' in status:
|
||||
raise ValidationError(status['error'])
|
||||
if not status and no_reward_fail:
|
||||
# Can happen if global discount got filtered out in `_get_claimable_rewards`
|
||||
raise ValidationError('No reward to claim with this coupon')
|
||||
coupons = self.env['loyalty.card']
|
||||
rewards = self.env['loyalty.reward']
|
||||
for coupon, coupon_rewards in status.items():
|
||||
coupons |= coupon
|
||||
rewards |= coupon_rewards
|
||||
if len(coupons) == 1 and len(rewards) == 1:
|
||||
status = order._apply_program_reward(rewards, coupons)
|
||||
if 'error' in status:
|
||||
raise ValidationError(status['error'])
|
||||
@@ -165,8 +165,10 @@ class StockPicking(models.Model):
|
||||
def send_to_shipper(self):
|
||||
self.ensure_one()
|
||||
res = self.carrier_id.send_shipping(self)[0]
|
||||
if self.carrier_id.free_over and self.sale_id and self.sale_id._compute_amount_total_without_delivery() >= self.carrier_id.amount:
|
||||
res['exact_price'] = 0.0
|
||||
if self.carrier_id.free_over and self.sale_id:
|
||||
amount_without_delivery = self.sale_id._compute_amount_total_without_delivery()
|
||||
if self.carrier_id._compute_currency(self.sale_id, amount_without_delivery, 'pricelist_to_company') >= self.carrier_id.amount:
|
||||
res['exact_price'] = 0.0
|
||||
self.carrier_price = res['exact_price'] * (1.0 + (self.carrier_id.margin / 100.0))
|
||||
if res['tracking_number']:
|
||||
previous_pickings = self.env['stock.picking']
|
||||
|
||||
Reference in New Issue
Block a user