mirror of
https://github.com/bringout/oca-ocb-sale.git
synced 2026-04-28 06:52:04 +02:00
19.0 vanilla
This commit is contained in:
parent
79f83631d5
commit
73afc09215
6267 changed files with 1534193 additions and 1130106 deletions
|
|
@ -2,3 +2,4 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_free_shipping_reward
|
||||
from . import test_loyalty_delivery
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import Command
|
||||
from odoo.addons.sale_loyalty.tests.common import TestSaleCouponCommon
|
||||
from odoo.fields import Command
|
||||
from odoo.tests import Form, tagged
|
||||
|
||||
from odoo.addons.sale_loyalty.tests.common import TestSaleCouponCommon
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestSaleCouponProgramRules(TestSaleCouponCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestSaleCouponProgramRules, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
|
||||
cls.iPadMini = cls.env['product.product'].create({'name': 'Large Cabinet', 'list_price': 320.0})
|
||||
tax_15pc_excl = cls.env['account.tax'].create({
|
||||
'name': "15% Tax excl",
|
||||
|
|
@ -70,16 +71,13 @@ class TestSaleCouponProgramRules(TestSaleCouponCommon):
|
|||
})],
|
||||
})
|
||||
|
||||
order = self.env['sale.order'].create({
|
||||
'partner_id': self.steve.id,
|
||||
})
|
||||
order = self.empty_order
|
||||
|
||||
# Price of order will be 5*1.15 = 5.75 (tax included)
|
||||
order.write({'order_line': [
|
||||
(0, False, {
|
||||
'product_id': self.product_B.id,
|
||||
'name': 'Product B',
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 1.0,
|
||||
})
|
||||
]})
|
||||
|
|
@ -105,7 +103,6 @@ class TestSaleCouponProgramRules(TestSaleCouponCommon):
|
|||
(0, False, {
|
||||
'product_id': self.product_B.id,
|
||||
'name': 'Product 1B',
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 1.0,
|
||||
'price_unit': 81.74,
|
||||
})
|
||||
|
|
@ -119,7 +116,6 @@ class TestSaleCouponProgramRules(TestSaleCouponCommon):
|
|||
(0, False, {
|
||||
'product_id': self.product_A.id,
|
||||
'name': 'Product 1',
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 1.0,
|
||||
'price_unit': 0.30,
|
||||
})
|
||||
|
|
@ -277,7 +273,7 @@ class TestSaleCouponProgramRules(TestSaleCouponCommon):
|
|||
})
|
||||
self._auto_rewards(order, programs)
|
||||
# 872.73 - (20% of 1 iPad) = 872.73 - 58.18 = 814.55
|
||||
self.assertAlmostEqual(order.amount_untaxed, 1105.46, 2, "One large cabinet should be discounted by 20%")
|
||||
self.assertAlmostEqual(order.amount_untaxed, 1105.45, 2, "One large cabinet should be discounted by 20%")
|
||||
|
||||
def test_free_shipping_reward_last_line(self):
|
||||
"""
|
||||
|
|
@ -302,22 +298,20 @@ class TestSaleCouponProgramRules(TestSaleCouponCommon):
|
|||
})],
|
||||
})
|
||||
# Add points to a partner to trigger the promotion
|
||||
loyalty_card = self.env['loyalty.card'].create({
|
||||
self.env['loyalty.card'].create({
|
||||
'program_id': loyalty_program.id,
|
||||
'partner_id': self.steve.id,
|
||||
'partner_id': self.partner.id,
|
||||
'points': 250,
|
||||
})
|
||||
order = self.env['sale.order'].create({
|
||||
'partner_id': self.steve.id,
|
||||
})
|
||||
order = self.empty_order
|
||||
# Check if we can claim the free shipping reward
|
||||
order._update_programs_and_rewards()
|
||||
claimable_rewards = order._get_claimable_rewards()
|
||||
self.assertEqual(len(claimable_rewards), 1)
|
||||
# Try to apply the loyalty card to the sale order
|
||||
self._apply_promo_code(order, loyalty_card.code)
|
||||
self.assertTrue(self._claim_reward(order, loyalty_program))
|
||||
# Check if there is an error in the sequence
|
||||
# via `_apply_program_reward` in `apply_promo_code` method
|
||||
# via `_apply_program_reward` in `_claim_reward` method
|
||||
|
||||
def test_nothing_delivered_nothing_to_invoice(self):
|
||||
program = self.env['loyalty.program'].create({
|
||||
|
|
@ -336,7 +330,7 @@ class TestSaleCouponProgramRules(TestSaleCouponCommon):
|
|||
})
|
||||
product = self.env['product.product'].create({
|
||||
'name': 'Test product',
|
||||
'type': 'product',
|
||||
'type': 'consu',
|
||||
'list_price': 200.0,
|
||||
'invoice_policy': 'delivery',
|
||||
})
|
||||
|
|
@ -455,11 +449,11 @@ class TestSaleCouponProgramRules(TestSaleCouponCommon):
|
|||
Check that a discount reward is still claimable after the shipping reward is claimed.
|
||||
"""
|
||||
program = self.env['loyalty.program'].create({
|
||||
'name': '10% Discount & Shipping',
|
||||
'name': "10% Discount & Shipping",
|
||||
'applies_on': 'current',
|
||||
'trigger': 'with_code',
|
||||
'program_type': 'promotion',
|
||||
'rule_ids': [Command.create({'mode': 'with_code', 'code': '10PERCENT&SHIPPING'})],
|
||||
'rule_ids': [Command.create({'mode': 'with_code', 'code': "10PERCENT&SHIPPING"})],
|
||||
'reward_ids': [
|
||||
Command.create({
|
||||
'reward_type': 'shipping',
|
||||
|
|
@ -479,7 +473,7 @@ class TestSaleCouponProgramRules(TestSaleCouponCommon):
|
|||
})
|
||||
|
||||
order = self.env['sale.order'].create({
|
||||
'partner_id': self.partner_a.id,
|
||||
'partner_id': self.partner.id,
|
||||
'order_line': [Command.create({'product_id': self.product_B.id})]
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,206 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.fields import Command
|
||||
from odoo.tests import Form, common
|
||||
|
||||
|
||||
@common.tagged('post_install', '-at_install')
|
||||
class TestLoyaltyDeliveryCost(common.TransactionCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
|
||||
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",
|
||||
'type': 'consu',
|
||||
'list_price': 200.0,
|
||||
})
|
||||
cls.product_uom_unit = cls.env.ref('uom.product_uom_unit')
|
||||
cls.product_delivery = cls.env['product.product'].create({
|
||||
'name': 'Delivery Charges',
|
||||
'type': 'service',
|
||||
'list_price': 40.0,
|
||||
'categ_id': cls.env.ref('delivery.product_category_deliveries').id,
|
||||
})
|
||||
cls.delivery_carrier = cls.env['delivery.carrier'].create({
|
||||
'name': 'Delivery Now Free Over 100',
|
||||
'fixed_price': 40,
|
||||
'delivery_type': 'fixed',
|
||||
'product_id': cls.product_delivery.id,
|
||||
'free_over': True,
|
||||
'amount': 100,
|
||||
})
|
||||
# Create a 50% discount on order code
|
||||
cls.env['loyalty.program'].create({
|
||||
'name': "50% discount code",
|
||||
'program_type': 'promo_code',
|
||||
'trigger': 'with_code',
|
||||
'applies_on': 'current',
|
||||
'rule_ids': [Command.create({
|
||||
'code': "test-50pc",
|
||||
})],
|
||||
'reward_ids': [Command.create({
|
||||
'reward_type': 'discount',
|
||||
'discount': 50.0,
|
||||
'discount_mode': 'percent',
|
||||
'discount_applicability': 'order',
|
||||
})],
|
||||
})
|
||||
cls.order = cls.env['sale.order'].create({
|
||||
'partner_id': cls.partner_1.id,
|
||||
'pricelist_id': cls.pricelist.id,
|
||||
'order_line': [Command.create({'product_id': cls.product_4.id})],
|
||||
})
|
||||
|
||||
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',
|
||||
'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': 200,
|
||||
}).generate_coupons()
|
||||
gift_card = program_gift_card.coupon_ids[0]
|
||||
|
||||
order = self.order
|
||||
self._apply_promo_code(order, gift_card.code)
|
||||
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_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.order
|
||||
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.order
|
||||
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 test_discount_percentage_ignores_delivery_lines(self):
|
||||
"""Check that percentage discounts ignore shipping costs."""
|
||||
self.delivery_carrier.free_over = False
|
||||
self._apply_promo_code(self.order, 'test-50pc')
|
||||
|
||||
delivery_wizard = Form(self.env['choose.delivery.carrier'].with_context(
|
||||
default_order_id=self.order.id,
|
||||
default_carrier_id=self.delivery_carrier.id,
|
||||
))
|
||||
delivery_wizard.save().button_confirm()
|
||||
|
||||
self.assertEqual(
|
||||
self.order.order_line.filtered('is_reward_line').price_unit,
|
||||
-self.product_4.list_price / 2,
|
||||
"Reward line should be half of the product's price",
|
||||
)
|
||||
self.assertAlmostEqual(
|
||||
self.order.amount_untaxed,
|
||||
self.product_4.list_price / 2 + self.delivery_carrier.fixed_price,
|
||||
msg="Subtotal should be half of product's list price plus full delivery cost",
|
||||
)
|
||||
|
||||
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'])
|
||||
Loading…
Add table
Add a link
Reference in a new issue