566 lines
23 KiB
Python
566 lines
23 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||
|
|
||
|
from odoo import Command
|
||
|
from odoo.exceptions import ValidationError
|
||
|
from odoo.tests import tagged, new_test_user
|
||
|
from odoo.tools.float_utils import float_compare
|
||
|
|
||
|
from odoo.addons.sale_loyalty.tests.common import TestSaleCouponCommon
|
||
|
|
||
|
|
||
|
@tagged('post_install', '-at_install')
|
||
|
class TestLoyalty(TestSaleCouponCommon):
|
||
|
|
||
|
@classmethod
|
||
|
def setUpClass(cls):
|
||
|
super().setUpClass()
|
||
|
cls.env['loyalty.program'].search([]).write({'active': False})
|
||
|
|
||
|
cls.partner_a = cls.env['res.partner'].create({'name': 'Jean Jacques'})
|
||
|
|
||
|
cls.product_a = cls.env['product.product'].create({
|
||
|
'name': 'Product C',
|
||
|
'list_price': 100,
|
||
|
'sale_ok': True,
|
||
|
'taxes_id': [(6, 0, [])],
|
||
|
})
|
||
|
|
||
|
cls.user_salemanager = new_test_user(cls.env, login='user_salemanager', groups='sales_team.group_sale_manager')
|
||
|
|
||
|
def test_nominative_programs(self):
|
||
|
loyalty_program, ewallet_program = self.env['loyalty.program'].create([
|
||
|
{
|
||
|
'name': 'Loyalty Program',
|
||
|
'program_type': 'loyalty',
|
||
|
'trigger': 'auto',
|
||
|
'applies_on': 'both',
|
||
|
'rule_ids': [(0, 0, {
|
||
|
'reward_point_mode': 'unit',
|
||
|
'reward_point_amount': 1,
|
||
|
'product_ids': [self.product_a.id],
|
||
|
})],
|
||
|
'reward_ids': [(0, 0, {
|
||
|
'reward_type': 'discount',
|
||
|
'discount': 1.5,
|
||
|
'discount_mode': 'per_point',
|
||
|
'discount_applicability': 'order',
|
||
|
'required_points': 3,
|
||
|
})],
|
||
|
},
|
||
|
{
|
||
|
'name': 'eWallet Program',
|
||
|
'program_type': 'ewallet',
|
||
|
'applies_on': 'future',
|
||
|
'trigger': 'auto',
|
||
|
'rule_ids': [(0, 0, {
|
||
|
'reward_point_mode': 'money',
|
||
|
'reward_point_amount': 10,
|
||
|
})],
|
||
|
'reward_ids': [(0, 0, {})],
|
||
|
}
|
||
|
])
|
||
|
|
||
|
order = self.env['sale.order'].create({
|
||
|
'partner_id': self.partner_a.id,
|
||
|
})
|
||
|
order._update_programs_and_rewards()
|
||
|
claimable_rewards = order._get_claimable_rewards()
|
||
|
# Should be empty since we do not have any coupon created yet
|
||
|
self.assertFalse(claimable_rewards, "No program should be applicable")
|
||
|
loyalty_card, ewallet_coupon = self.env['loyalty.card'].create([
|
||
|
{
|
||
|
'program_id': loyalty_program.id,
|
||
|
'partner_id': self.partner_a.id,
|
||
|
'points': 10,
|
||
|
},
|
||
|
{
|
||
|
'program_id': ewallet_program.id,
|
||
|
'partner_id': self.partner_a.id,
|
||
|
'points': 0,
|
||
|
},
|
||
|
])
|
||
|
order.write({
|
||
|
'order_line': [(0, 0, {
|
||
|
'product_id': self.product_a.id,
|
||
|
'product_uom_qty': 1,
|
||
|
})]
|
||
|
})
|
||
|
order._update_programs_and_rewards()
|
||
|
claimable_rewards = order._get_claimable_rewards()
|
||
|
self.assertEqual(len(claimable_rewards), 1, "The ewallet program should not be applicable since the card has no points.")
|
||
|
vals = order._get_reward_values_discount(loyalty_program.reward_ids[0], loyalty_card)
|
||
|
self.assertEqual(
|
||
|
vals[0]['points_cost'] % loyalty_program.reward_ids.required_points,
|
||
|
0,
|
||
|
"Can only use a whole number of required points",
|
||
|
)
|
||
|
self.assertEqual(vals[0]['points_cost'], 9, "Use maximum available points for the reward")
|
||
|
ewallet_coupon.points = 50
|
||
|
order._update_programs_and_rewards()
|
||
|
claimable_rewards = order._get_claimable_rewards()
|
||
|
self.assertEqual(len(claimable_rewards), 2, "Now that the ewallet has some points they should both be applicable.")
|
||
|
|
||
|
def test_cancel_order_with_coupons(self):
|
||
|
"""This test ensure that creating an order with coupons will not
|
||
|
raise an access error on POS line modele when canceling the order."""
|
||
|
|
||
|
self.env['loyalty.program'].create({
|
||
|
'name': '10% Discount',
|
||
|
'program_type': 'coupons',
|
||
|
'applies_on': 'current',
|
||
|
'trigger': 'auto',
|
||
|
'rule_ids': [(0, 0, {})],
|
||
|
'reward_ids': [(0, 0, {
|
||
|
'reward_type': 'discount',
|
||
|
'discount': 10,
|
||
|
'discount_mode': 'percent',
|
||
|
'discount_applicability': 'order',
|
||
|
})]
|
||
|
})
|
||
|
|
||
|
order = self.env['sale.order'].with_user(self.user_salemanager).create({
|
||
|
'partner_id': self.partner_a.id,
|
||
|
'order_line': [
|
||
|
(0, 0, {
|
||
|
'product_id': self.product_a.id,
|
||
|
})
|
||
|
]
|
||
|
})
|
||
|
|
||
|
order._update_programs_and_rewards()
|
||
|
self.assertTrue(order.coupon_point_ids)
|
||
|
|
||
|
# Canceling the order should not raise an access error:
|
||
|
# During the cancel process, we are trying to get `use_count` of the coupon,
|
||
|
# and we call the `_compute_use_count` that is also in pos_loyalty.
|
||
|
# This last one will try to find related POS lines while user have not access to POS.
|
||
|
order._action_cancel()
|
||
|
self.assertFalse(order.coupon_point_ids)
|
||
|
|
||
|
def test_distribution_amount_payment_programs(self):
|
||
|
"""
|
||
|
Check how the amount of a payment reward is distributed.
|
||
|
An ewallet should not be used to refund taxes.
|
||
|
Its amount must be distributed between the products.
|
||
|
"""
|
||
|
|
||
|
# Create two products
|
||
|
product_a, product_b = self.env['product.product'].create([
|
||
|
{
|
||
|
'name': 'Product A',
|
||
|
'list_price': 100,
|
||
|
'sale_ok': True,
|
||
|
'taxes_id': [Command.set(self.tax_15pc_excl.ids)],
|
||
|
},
|
||
|
{
|
||
|
'name': 'Product B',
|
||
|
'list_price': 100,
|
||
|
'sale_ok': True,
|
||
|
'taxes_id': [Command.set(self.tax_15pc_excl.ids)],
|
||
|
},
|
||
|
])
|
||
|
|
||
|
# Create a coupon and a ewallet
|
||
|
coupon_program, ewallet_program = self.env['loyalty.program'].create([
|
||
|
{
|
||
|
'name': 'Coupon Program',
|
||
|
'program_type': 'coupons',
|
||
|
'trigger': 'with_code',
|
||
|
'applies_on': 'both',
|
||
|
'reward_ids': [Command.create({
|
||
|
'reward_type': 'discount',
|
||
|
'discount': 100.0,
|
||
|
'discount_applicability': 'specific',
|
||
|
'discount_product_domain': '[("name", "=", "Product A")]',
|
||
|
})],
|
||
|
},
|
||
|
{
|
||
|
'name': 'eWallet Program',
|
||
|
'program_type': 'ewallet',
|
||
|
'applies_on': 'future',
|
||
|
'trigger': 'auto',
|
||
|
'rule_ids': [Command.create({
|
||
|
'reward_point_mode': 'money',
|
||
|
})],
|
||
|
'reward_ids': [Command.create({
|
||
|
'discount_mode': 'per_point',
|
||
|
'discount': 1,
|
||
|
'discount_applicability': 'order',
|
||
|
})],
|
||
|
}
|
||
|
])
|
||
|
|
||
|
coupon_partner, _ = self.env['loyalty.card'].create([
|
||
|
{
|
||
|
'program_id': coupon_program.id,
|
||
|
'partner_id': self.partner_a.id,
|
||
|
'points': 1,
|
||
|
'code': '5555',
|
||
|
},
|
||
|
{
|
||
|
'program_id': ewallet_program.id,
|
||
|
'partner_id': self.partner_a.id,
|
||
|
'points': 115,
|
||
|
},
|
||
|
])
|
||
|
|
||
|
# Create the order
|
||
|
order = self.env['sale.order'].with_user(self.user_salemanager).create({
|
||
|
'partner_id': self.partner_a.id,
|
||
|
'order_line': [
|
||
|
Command.create({
|
||
|
'product_id': product_a.id,
|
||
|
}),
|
||
|
Command.create({
|
||
|
'product_id': product_b.id,
|
||
|
}),
|
||
|
]
|
||
|
})
|
||
|
|
||
|
self.assertEqual(order.amount_total, 230.0)
|
||
|
self.assertEqual(order.amount_untaxed, 200.0)
|
||
|
self.assertEqual(order.amount_tax, 30.0)
|
||
|
|
||
|
# Apply the eWallet
|
||
|
order._update_programs_and_rewards()
|
||
|
self._claim_reward(order, ewallet_program)
|
||
|
|
||
|
self.assertEqual(order.amount_total, 115.0)
|
||
|
self.assertEqual(order.amount_untaxed, 85.0)
|
||
|
self.assertEqual(order.amount_tax, 30.0)
|
||
|
self.assertEqual(order.reward_amount, -115.0)
|
||
|
|
||
|
# Apply the coupon
|
||
|
self._apply_promo_code(order, coupon_partner.code)
|
||
|
|
||
|
self.assertEqual(order.amount_total, 0.0)
|
||
|
self.assertEqual(order.amount_untaxed, -15.0)
|
||
|
self.assertEqual(order.amount_tax, 15.0)
|
||
|
self.assertEqual(order.reward_amount, -215.0)
|
||
|
|
||
|
def test_discount_max_amount_on_specific_product(self):
|
||
|
product_a = self.product_A
|
||
|
product_b = self.product_B
|
||
|
product_a.write({'taxes_id': [Command.set(self.tax_20pc_excl.ids)]})
|
||
|
product_b.write({'list_price': -20, 'taxes_id': [Command.set(self.tax_20pc_excl.ids)]})
|
||
|
|
||
|
self.env['loyalty.program'].search([]).write({'active': False})
|
||
|
promotion = self.env['loyalty.program'].create({
|
||
|
'name': '10% Discount',
|
||
|
'program_type': 'promotion',
|
||
|
'trigger': 'auto',
|
||
|
'rule_ids': [Command.create({'reward_point_amount': 1, 'reward_point_mode': 'unit'})],
|
||
|
'reward_ids': [Command.create({
|
||
|
'discount': 10.0,
|
||
|
'discount_max_amount': 9,
|
||
|
'discount_applicability': 'specific',
|
||
|
'discount_product_ids': [product_a.id],
|
||
|
})],
|
||
|
})
|
||
|
|
||
|
order = self.env['sale.order'].create({
|
||
|
'partner_id': self.partner_a.id,
|
||
|
'order_line': [Command.create({'product_id': product_a.id})],
|
||
|
})
|
||
|
self.assertEqual(order.reward_amount, 0)
|
||
|
|
||
|
self._auto_rewards(order, promotion)
|
||
|
reward_amount_tax_included = sum(l.price_total for l in order.order_line if l.reward_id)
|
||
|
msg = "Max discount amount reached, the reward amount should be the max amount value."
|
||
|
self.assertEqual(reward_amount_tax_included, -9, msg)
|
||
|
|
||
|
order.order_line = [Command.clear(), Command.create({'product_id': product_b.id})]
|
||
|
self._auto_rewards(order, promotion)
|
||
|
reward_amount_tax_included = sum(l.price_total for l in order.order_line if l.reward_id)
|
||
|
msg = "This product is not eligible to the discount."
|
||
|
self.assertEqual(reward_amount_tax_included, 0, msg=msg)
|
||
|
|
||
|
order.order_line = [
|
||
|
Command.clear(),
|
||
|
Command.create({'product_id': product_a.id}), # price_total = 120
|
||
|
Command.create({'product_id': product_b.id}), # price_total = -20
|
||
|
]
|
||
|
self._auto_rewards(order, promotion)
|
||
|
reward_amount_tax_included = sum(l.price_total for l in order.order_line if l.reward_id)
|
||
|
msg = "Reward amount above the max amount, the reward should be the max amount value."
|
||
|
self.assertEqual(reward_amount_tax_included, -9, msg)
|
||
|
|
||
|
order.order_line = [
|
||
|
Command.clear(),
|
||
|
Command.create({'product_id': product_a.id}), # price_total = 120
|
||
|
Command.create({'product_id': product_b.id, 'price_unit': -95}), # price_total = -114
|
||
|
]
|
||
|
self._auto_rewards(order, promotion)
|
||
|
reward_amount_tax_included = sum(l.price_total for l in order.order_line if l.reward_id)
|
||
|
msg = "Reward amount should never surpass the order's current total amount."
|
||
|
self.assertEqual(reward_amount_tax_included, -6, msg)
|
||
|
|
||
|
order.order_line = [
|
||
|
Command.clear(),
|
||
|
Command.create({'product_id': product_a.id, 'price_unit': 50}), # price_total = 60
|
||
|
Command.create({'product_id': product_b.id, 'price_unit': -5}), # price_total = -6
|
||
|
]
|
||
|
self._auto_rewards(order, promotion)
|
||
|
reward_amount_tax_included = sum(l.price_total for l in order.order_line if l.reward_id)
|
||
|
msg = "Reward amount should be the percentage one if under the max amount discount."
|
||
|
self.assertEqual(reward_amount_tax_included, -6, msg)
|
||
|
|
||
|
def test_multiple_discount_specific(self):
|
||
|
"""
|
||
|
Check the discount calculation if it is based on the remaining amount
|
||
|
"""
|
||
|
|
||
|
product_A = self.env['product.product'].create({
|
||
|
'name': 'Product A',
|
||
|
'list_price': 100,
|
||
|
'sale_ok': True,
|
||
|
'taxes_id': [],
|
||
|
})
|
||
|
|
||
|
coupon_program = self.env['loyalty.program'].create([{
|
||
|
'name': 'Coupon Program',
|
||
|
'program_type': 'promotion',
|
||
|
'trigger': 'auto',
|
||
|
'applies_on': 'current',
|
||
|
'rule_ids': [Command.create({
|
||
|
'reward_point_amount': 1,
|
||
|
'reward_point_mode': 'unit',
|
||
|
})],
|
||
|
'reward_ids': [Command.create({
|
||
|
'reward_type': 'discount',
|
||
|
'discount': 10.0,
|
||
|
'discount_applicability': 'specific',
|
||
|
'required_points': 1,
|
||
|
})],
|
||
|
}])
|
||
|
|
||
|
order = self.env['sale.order'].with_user(self.user_salemanager).create({
|
||
|
'partner_id': self.partner_a.id,
|
||
|
'order_line': [Command.create({
|
||
|
'product_id': product_A.id,
|
||
|
'product_uom_qty': 3,
|
||
|
})]
|
||
|
})
|
||
|
|
||
|
self.assertEqual(float_compare(order.amount_total, 300, precision_rounding=3), 0)
|
||
|
|
||
|
order._update_programs_and_rewards()
|
||
|
self._claim_reward(order, coupon_program)
|
||
|
self.assertEqual(float_compare(order.amount_total, 270, precision_rounding=3), 0, "300 * 0.9 = 270")
|
||
|
|
||
|
order._update_programs_and_rewards()
|
||
|
self._claim_reward(order, coupon_program)
|
||
|
self.assertEqual(float_compare(order.amount_total, 243, precision_rounding=3), 0, "300 * 0.9 * 0.9 = 243")
|
||
|
|
||
|
order._update_programs_and_rewards()
|
||
|
self._claim_reward(order, coupon_program)
|
||
|
self.assertEqual(float_compare(order.amount_total, 218.7, precision_rounding=3), 0, "300 * 0.9 * 0.9 * 0.9 = 218.7")
|
||
|
|
||
|
def test_promotion_program_restricted_to_pricelists(self):
|
||
|
self.env['product.pricelist'].search([]).action_archive()
|
||
|
company_currency = self.env.company.currency_id
|
||
|
pricelist_1, pricelist_2 = self.env['product.pricelist'].create([
|
||
|
{'name': 'Basic company_currency pricelist', 'currency_id': company_currency.id},
|
||
|
{'name': 'Other company_currency pricelist', 'currency_id': company_currency.id},
|
||
|
])
|
||
|
self.immediate_promotion_program.active = True
|
||
|
order = self.empty_order.copy()
|
||
|
order.write({'order_line': [
|
||
|
(0, False, {
|
||
|
'product_id': self.product_A.id,
|
||
|
'name': '1 Product A',
|
||
|
'product_uom': self.uom_unit.id,
|
||
|
'product_uom_qty': 1.0,
|
||
|
}),
|
||
|
(0, False, {
|
||
|
'product_id': self.product_B.id,
|
||
|
'name': '2 Product B',
|
||
|
'product_uom': self.uom_unit.id,
|
||
|
'product_uom_qty': 1.0,
|
||
|
}),
|
||
|
]})
|
||
|
|
||
|
applied_message = "The promo offer should have been applied."
|
||
|
not_applied_message = "The promo offer should not have been applied because the order's " \
|
||
|
"pricelist is not eligible to this promotion."
|
||
|
|
||
|
order.pricelist_id = self.env['product.pricelist']
|
||
|
order._update_programs_and_rewards()
|
||
|
self._claim_reward(order, self.immediate_promotion_program)
|
||
|
self.assertEqual(len(order.order_line.ids), 3, applied_message)
|
||
|
|
||
|
order.pricelist_id = pricelist_1
|
||
|
order._update_programs_and_rewards()
|
||
|
self._claim_reward(order, self.immediate_promotion_program)
|
||
|
self.assertEqual(len(order.order_line.ids), 3, applied_message)
|
||
|
|
||
|
self.immediate_promotion_program.pricelist_ids = [pricelist_1.id]
|
||
|
order.pricelist_id = self.env['product.pricelist']
|
||
|
order._update_programs_and_rewards()
|
||
|
self._claim_reward(order, self.immediate_promotion_program)
|
||
|
self.assertEqual(len(order.order_line.ids), 2, not_applied_message)
|
||
|
|
||
|
order.pricelist_id = pricelist_1
|
||
|
order._update_programs_and_rewards()
|
||
|
self._claim_reward(order, self.immediate_promotion_program)
|
||
|
self.assertEqual(len(order.order_line.ids), 3, applied_message)
|
||
|
|
||
|
order.pricelist_id = pricelist_2
|
||
|
order._update_programs_and_rewards()
|
||
|
self._claim_reward(order, self.immediate_promotion_program)
|
||
|
self.assertEqual(len(order.order_line.ids), 2, not_applied_message)
|
||
|
|
||
|
self.immediate_promotion_program.pricelist_ids = [pricelist_1.id, pricelist_2.id]
|
||
|
order.pricelist_id = self.env['product.pricelist']
|
||
|
order._update_programs_and_rewards()
|
||
|
self._claim_reward(order, self.immediate_promotion_program)
|
||
|
self.assertEqual(len(order.order_line.ids), 2, not_applied_message)
|
||
|
|
||
|
order.pricelist_id = pricelist_1
|
||
|
order._update_programs_and_rewards()
|
||
|
self._claim_reward(order, self.immediate_promotion_program)
|
||
|
self.assertEqual(len(order.order_line.ids), 3, applied_message)
|
||
|
|
||
|
def test_coupon_program_restricted_to_pricelists(self):
|
||
|
self.env['product.pricelist'].search([]).action_archive()
|
||
|
company_currency = self.env.company.currency_id
|
||
|
pricelist_1, pricelist_2 = self.env['product.pricelist'].create([
|
||
|
{'name': 'Basic company_currency pricelist', 'currency_id': company_currency.id},
|
||
|
{'name': 'Other company_currency pricelist', 'currency_id': company_currency.id},
|
||
|
])
|
||
|
|
||
|
self.code_promotion_program.active = True
|
||
|
self.env['loyalty.generate.wizard'].with_context(
|
||
|
active_id=self.code_promotion_program.id
|
||
|
).create({'coupon_qty': 7, 'points_granted': 1}).generate_coupons()
|
||
|
coupons = self.code_promotion_program.coupon_ids
|
||
|
|
||
|
order_no_pricelist = self.empty_order.copy()
|
||
|
order_no_pricelist.write({'pricelist_id': None, 'order_line': [
|
||
|
(0, False, {
|
||
|
'product_id': self.product_A.id,
|
||
|
'name': '1 Product A',
|
||
|
'product_uom': self.uom_unit.id,
|
||
|
'product_uom_qty': 1.0,
|
||
|
}),
|
||
|
]})
|
||
|
order_pricelist_1 = order_no_pricelist.copy()
|
||
|
order_pricelist_1.pricelist_id = pricelist_1
|
||
|
order_pricelist_2 = order_no_pricelist.copy()
|
||
|
order_pricelist_2.pricelist_id = pricelist_2
|
||
|
|
||
|
applied_message = "The coupon code should have been applied."
|
||
|
not_applied_message = "The coupon code should not have been applied because the order's " \
|
||
|
"pricelist is not eligible to this promotion."
|
||
|
|
||
|
order_0 = order_no_pricelist.copy()
|
||
|
self._apply_promo_code(order_0, coupons[0].code)
|
||
|
self.assertEqual(len(order_0.order_line.ids), 2, applied_message)
|
||
|
|
||
|
order_1 = order_pricelist_1.copy()
|
||
|
self._apply_promo_code(order_1, coupons[1].code)
|
||
|
self.assertEqual(len(order_1.order_line.ids), 2, applied_message)
|
||
|
|
||
|
self.code_promotion_program.pricelist_ids = [pricelist_1.id]
|
||
|
order_2 = order_no_pricelist.copy()
|
||
|
with self.assertRaises(ValidationError):
|
||
|
self._apply_promo_code(order_2, coupons[2].code)
|
||
|
self.assertEqual(len(order_2.order_line.ids), 1, not_applied_message)
|
||
|
|
||
|
order_3 = order_pricelist_1.copy()
|
||
|
self._apply_promo_code(order_3, coupons[3].code)
|
||
|
self.assertEqual(len(order_3.order_line.ids), 2, applied_message)
|
||
|
|
||
|
order_4 = order_pricelist_2.copy()
|
||
|
with self.assertRaises(ValidationError):
|
||
|
self._apply_promo_code(order_4, coupons[4].code)
|
||
|
self.assertEqual(len(order_4.order_line.ids), 1, not_applied_message)
|
||
|
|
||
|
self.code_promotion_program.pricelist_ids = [pricelist_1.id, pricelist_2.id]
|
||
|
order_5 = order_no_pricelist.copy()
|
||
|
with self.assertRaises(ValidationError):
|
||
|
self._apply_promo_code(order_5, coupons[5].code)
|
||
|
self.assertEqual(len(order_5.order_line.ids), 1, not_applied_message)
|
||
|
|
||
|
order_6 = order_pricelist_1.copy()
|
||
|
self._apply_promo_code(order_6, coupons[6].code)
|
||
|
self.assertEqual(len(order_6.order_line.ids), 2, applied_message)
|
||
|
|
||
|
def test_specific_promotion_on_free_product(self):
|
||
|
|
||
|
product_A = self.env['product.product'].create({
|
||
|
'name': 'Product A',
|
||
|
'list_price': 100,
|
||
|
'sale_ok': True,
|
||
|
'taxes_id': [],
|
||
|
})
|
||
|
|
||
|
promotion_program = self.env['loyalty.program'].create([{
|
||
|
'name': 'Promotion Program',
|
||
|
'program_type': 'promotion',
|
||
|
'trigger': 'auto',
|
||
|
'applies_on': 'current',
|
||
|
'rule_ids': [Command.create({
|
||
|
'reward_point_amount': 1,
|
||
|
'reward_point_mode': 'unit',
|
||
|
})],
|
||
|
'reward_ids': [Command.create({
|
||
|
'reward_type': 'discount',
|
||
|
'discount': 10.0,
|
||
|
'discount_applicability': 'specific',
|
||
|
'discount_product_ids': [product_A.id],
|
||
|
'required_points': 1,
|
||
|
})],
|
||
|
}])
|
||
|
|
||
|
order = self.env['sale.order'].with_user(self.user_salemanager).create({
|
||
|
'partner_id': self.partner_a.id,
|
||
|
'order_line': [
|
||
|
Command.create({
|
||
|
'product_id': product_A.id,
|
||
|
}),
|
||
|
Command.create({
|
||
|
'product_id': product_A.id,
|
||
|
'discount': 100,
|
||
|
}),
|
||
|
]
|
||
|
})
|
||
|
|
||
|
order._update_programs_and_rewards()
|
||
|
self._claim_reward(order, promotion_program)
|
||
|
self.assertEqual(order.amount_total, 90)
|
||
|
|
||
|
def test_gift_card_program_without_product(self):
|
||
|
product_A = self.env['product.product'].create({
|
||
|
'name': 'Product A',
|
||
|
'list_price': 100,
|
||
|
'sale_ok': True,
|
||
|
'taxes_id': [],
|
||
|
})
|
||
|
|
||
|
giftcard_program = self.env['loyalty.program'].create([{
|
||
|
'name': 'Gift Card Program',
|
||
|
'program_type': 'gift_card',
|
||
|
'trigger': 'auto',
|
||
|
'applies_on': 'current',
|
||
|
'rule_ids': [Command.create({
|
||
|
'reward_point_amount': 1,
|
||
|
'reward_point_mode': 'unit',
|
||
|
})],
|
||
|
}])
|
||
|
|
||
|
order = self.env['sale.order'].with_user(self.user_salemanager).create({
|
||
|
'partner_id': self.partner_a.id,
|
||
|
'order_line': [
|
||
|
Command.create({
|
||
|
'product_id': product_A.id,
|
||
|
}),
|
||
|
]
|
||
|
})
|
||
|
|
||
|
order._update_programs_and_rewards()
|
||
|
self._claim_reward(order, giftcard_program)
|
||
|
|
||
|
self.assertEqual(giftcard_program.coupon_count, 0)
|