mirror of
https://github.com/bringout/oca-ocb-sale.git
synced 2026-04-27 00:32:05 +02:00
19.0 vanilla
This commit is contained in:
parent
79f83631d5
commit
73afc09215
6267 changed files with 1534193 additions and 1130106 deletions
|
|
@ -1,13 +1,18 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from datetime import date, timedelta
|
||||
|
||||
from odoo.addons.sale_loyalty.tests.common import TestSaleCouponCommon
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo import Command
|
||||
from freezegun import freeze_time
|
||||
from pytz import timezone
|
||||
|
||||
class TestProgramRules(TestSaleCouponCommon):
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.fields import Command, Datetime
|
||||
|
||||
from odoo.addons.payment.tests.common import PaymentCommon
|
||||
from odoo.addons.sale_loyalty.tests.common import TestSaleCouponCommon
|
||||
|
||||
|
||||
class TestProgramRules(TestSaleCouponCommon, PaymentCommon):
|
||||
# Test all the validity rules to allow a customer to have a reward.
|
||||
# The check based on the products is already done in the basic operations test
|
||||
|
||||
|
|
@ -25,13 +30,11 @@ class TestProgramRules(TestSaleCouponCommon):
|
|||
(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,
|
||||
})
|
||||
]})
|
||||
|
|
@ -39,18 +42,16 @@ class TestProgramRules(TestSaleCouponCommon):
|
|||
self._claim_reward(order, self.immediate_promotion_program)
|
||||
self.assertEqual(len(order.order_line.ids), 2, "The promo offer shouldn't have been applied as the purchased amount is not enough")
|
||||
|
||||
order = self.env['sale.order'].create({'partner_id': self.steve.id})
|
||||
order = self.env['sale.order'].create({'partner_id': self.partner.id})
|
||||
order.write({'order_line': [
|
||||
(0, False, {
|
||||
'product_id': self.product_A.id,
|
||||
'name': '10 Product A',
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 10.0,
|
||||
}),
|
||||
(0, False, {
|
||||
'product_id': self.product_B.id,
|
||||
'name': '2 Product B',
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 1.0,
|
||||
})
|
||||
]})
|
||||
|
|
@ -282,8 +283,8 @@ class TestProgramRules(TestSaleCouponCommon):
|
|||
discounts = set(order.order_line.mapped('name')) - {'Product A'}
|
||||
self.assertEqual(len(discounts), 1, "The order should contains the Product A line and a discount")
|
||||
# The name of the discount is dynamically changed to smth looking like:
|
||||
# "Discount: Get 5% discount if buy at least 2 Product - On product with following tax: Tax 15.00%"
|
||||
self.assertTrue('Discount: 5% on your order' in discounts.pop(), "The discount should be a 5% discount")
|
||||
# "Discount Get 5% discount if buy at least 2 Product - On product with following tax: Tax 15.00%"
|
||||
self.assertTrue('Discount 5% on your order' in discounts.pop(), "The discount should be a 5% discount")
|
||||
|
||||
sol.product_uom_qty = 5
|
||||
order._update_programs_and_rewards()
|
||||
|
|
@ -291,71 +292,215 @@ class TestProgramRules(TestSaleCouponCommon):
|
|||
self._claim_reward(order, p2)
|
||||
discounts = set(order.order_line.mapped('name')) - {'Product A'}
|
||||
self.assertEqual(len(discounts), 1, "The order should contains the Product A line and a discount")
|
||||
self.assertTrue('Discount: 10% on your order' in discounts.pop(), "The discount should be a 10% discount")
|
||||
self.assertTrue('Discount 10% on your order' in discounts.pop(), "The discount should be a 10% discount")
|
||||
|
||||
def test_program_rules_validity_dates_and_uses(self):
|
||||
# Test case: Based on the validity dates and the number of allowed uses
|
||||
@freeze_time('2011-11-02 09:00:21')
|
||||
def test_program_rules_validity_dates(self):
|
||||
# Test date_to (no date_from)
|
||||
today = date.today()
|
||||
past_day = today - timedelta(days=2)
|
||||
future_day = today + timedelta(days=2)
|
||||
self.immediate_promotion_program.write({'date_to': past_day})
|
||||
order = self.empty_order
|
||||
order.write({'order_line': [
|
||||
Command.create({
|
||||
'product_id': self.product_A.id,
|
||||
'name': '1 Product A',
|
||||
'product_uom_qty': 1.0,
|
||||
}),
|
||||
Command.create({
|
||||
'product_id': self.product_B.id,
|
||||
'name': '2 Product B',
|
||||
'product_uom_qty': 1.0,
|
||||
})
|
||||
]})
|
||||
self._auto_rewards(order, self.immediate_promotion_program)
|
||||
msg = "The promo shouldn't have been applied as it is expired."
|
||||
self.assertEqual(len(order.order_line.ids), 2, msg)
|
||||
|
||||
self.immediate_promotion_program.write({'date_to': future_day})
|
||||
self._auto_rewards(order, self.immediate_promotion_program)
|
||||
msg = "The promo should have been applied we're between the validity dates."
|
||||
self.assertEqual(len(order.order_line.ids), 3, msg)
|
||||
|
||||
# Test date_from (no date_to)
|
||||
self.immediate_promotion_program.write({
|
||||
'date_from': future_day, 'date_to': False,
|
||||
})
|
||||
self._auto_rewards(order, self.immediate_promotion_program)
|
||||
msg = "The promo shouldn't have been applied as it is not active yet."
|
||||
self.assertEqual(len(order.order_line.ids), 2, msg)
|
||||
|
||||
self.immediate_promotion_program.write({'date_from': past_day})
|
||||
self._auto_rewards(order, self.immediate_promotion_program)
|
||||
msg = "The promo should have been applied we're between the validity dates."
|
||||
self.assertEqual(len(order.order_line.ids), 3, msg)
|
||||
|
||||
# Test date_from and date_to
|
||||
self.immediate_promotion_program.write({'date_from': past_day, 'date_to': future_day})
|
||||
self._auto_rewards(order, self.immediate_promotion_program)
|
||||
msg = "The promo should have been applied as we're between the validity dates"
|
||||
self.assertEqual(len(order.order_line.ids), 3, msg)
|
||||
|
||||
self.immediate_promotion_program.write({
|
||||
'date_to': date.today() - timedelta(days=2),
|
||||
'date_from': today + timedelta(days=1),
|
||||
'date_to': future_day,
|
||||
})
|
||||
self._auto_rewards(order, self.immediate_promotion_program)
|
||||
msg = "The promo offer shouldn't have been applied as it is not active yet."
|
||||
self.assertEqual(len(order.order_line.ids), 2, msg)
|
||||
|
||||
self.immediate_promotion_program.write({
|
||||
'date_from': past_day,
|
||||
'date_to': today - timedelta(days=1),
|
||||
})
|
||||
self._auto_rewards(order, self.immediate_promotion_program)
|
||||
msg = "The promo offer shouldn't have been applied as it is expired."
|
||||
self.assertEqual(len(order.order_line.ids), 2, msg)
|
||||
|
||||
self.immediate_promotion_program.write({'date_from': today, 'date_to': today})
|
||||
self._auto_rewards(order, self.immediate_promotion_program)
|
||||
msg = "The promo should have been applied as today is a valid starting and ending date."
|
||||
self.assertEqual(len(order.order_line.ids), 3, msg)
|
||||
|
||||
def test_program_rules_number_of_uses(self):
|
||||
# Test case: Based on the number of allowed uses
|
||||
self.immediate_promotion_program.write({
|
||||
'limit_usage': True,
|
||||
'max_usage': 1,
|
||||
})
|
||||
|
||||
order = self.empty_order
|
||||
order.write({'order_line': [
|
||||
(0, False, {
|
||||
Command.create({
|
||||
'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,
|
||||
})
|
||||
]})
|
||||
self._auto_rewards(order, self.immediate_promotion_program)
|
||||
self.assertEqual(len(order.order_line.ids), 2, "The promo offer shouldn't have been applied we're not between the validity dates")
|
||||
self.assertEqual(len(order.order_line.ids), 2, "The promo offer should have been applied")
|
||||
|
||||
self.immediate_promotion_program.write({
|
||||
'date_to': date.today() + timedelta(days=2),
|
||||
order = self.env['sale.order'].create({
|
||||
'partner_id': self.env['res.partner'].create({'name': 'My Partner'}).id
|
||||
})
|
||||
order = self.env['sale.order'].create({'partner_id': self.steve.id})
|
||||
|
||||
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': 10.0,
|
||||
}),
|
||||
(0, False, {
|
||||
Command.create({
|
||||
'product_id': self.product_B.id,
|
||||
'name': '2 Product B',
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 1.0,
|
||||
})
|
||||
]})
|
||||
self._auto_rewards(order, self.immediate_promotion_program)
|
||||
self.assertEqual(len(order.order_line.ids), 3, "The promo offer should have been applied as we're between the validity dates")
|
||||
order = self.env['sale.order'].create({'partner_id': self.env['res.partner'].create({'name': 'My Partner'}).id})
|
||||
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': 10.0,
|
||||
}),
|
||||
(0, False, {
|
||||
'product_id': self.product_B.id,
|
||||
'name': '2 Product B',
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 1.0,
|
||||
})
|
||||
]})
|
||||
# Invalidate total_order_count
|
||||
self.immediate_promotion_program.invalidate_recordset(['order_count', 'total_order_count'])
|
||||
self._auto_rewards(order, self.immediate_promotion_program)
|
||||
self.assertEqual(len(order.order_line.ids), 2, "The promo offer shouldn't have been applied as the number of uses is exceeded")
|
||||
msg = "The promo offer shouldn't have been applied as the number of uses is exceeded"
|
||||
self.assertEqual(len(order.order_line.ids), 1, msg)
|
||||
|
||||
def test_program_rules_validity_date_timezones(self):
|
||||
"""Test that the validity dates are checked according to the company's time zone"""
|
||||
self.env.company.partner_id.tz = 'Europe/London'
|
||||
self.partner.tz = 'America/Los_Angeles'
|
||||
midnight = Datetime.today()
|
||||
yesterday = (midnight - timedelta(days=1)).date()
|
||||
self.immediate_promotion_program.update({
|
||||
'date_to': yesterday,
|
||||
'limit_usage': True,
|
||||
'max_usage': 1,
|
||||
})
|
||||
order = self.empty_order.with_context(tz=self.partner.tz)
|
||||
order.order_line = [
|
||||
Command.create({'product_id': self.product_A.id}),
|
||||
Command.create({'product_id': self.product_B.id}),
|
||||
]
|
||||
|
||||
with freeze_time(midnight):
|
||||
# Try apply reward at UTC midnight with LA time zone in context (expired)
|
||||
self._auto_rewards(order, self.immediate_promotion_program)
|
||||
self.assertFalse(
|
||||
order.order_line.filtered('is_reward_line'),
|
||||
"Promo should not be applied if only valid in the customer's time zone",
|
||||
)
|
||||
|
||||
with freeze_time(timezone(self.env.company.partner_id.tz).localize(midnight)):
|
||||
# Try apply reward at London midnight (expired)
|
||||
self._auto_rewards(order, self.immediate_promotion_program)
|
||||
self.assertFalse(
|
||||
order.order_line.filtered('is_reward_line'),
|
||||
"Promo should not be applied if only valid in the customer's time zone",
|
||||
)
|
||||
|
||||
self.partner.tz = 'Europe/Brussels'
|
||||
with freeze_time(timezone(self.partner.tz).localize(midnight)):
|
||||
# Apply reward at Brussels midnight (still valid in company's time zone)
|
||||
self._auto_rewards(order, self.immediate_promotion_program)
|
||||
self.assertTrue(
|
||||
order.order_line.filtered('is_reward_line'),
|
||||
"Promo should be applied if valid in the company's time zone",
|
||||
)
|
||||
|
||||
def test_program_rules_validity_date_transactions(self):
|
||||
"""Test that the validity dates are checked according to the time of transaction."""
|
||||
today = Datetime.today()
|
||||
tomorrow = today + timedelta(days=1)
|
||||
self.immediate_promotion_program.update({
|
||||
'date_to': today,
|
||||
'limit_usage': True,
|
||||
'max_usage': 1,
|
||||
'reward_ids': [Command.set(self.program_gift_card.reward_ids.ids)],
|
||||
})
|
||||
order = self.empty_order
|
||||
order.order_line = [
|
||||
Command.create({'product_id': self.product_A.id}),
|
||||
Command.create({'product_id': self.product_B.id}),
|
||||
]
|
||||
|
||||
intial_amount = order.amount_total
|
||||
self._auto_rewards(order, self.immediate_promotion_program)
|
||||
self.assertLess(order.amount_total, intial_amount, "A discount should be applied")
|
||||
|
||||
tx = order.transaction_ids = self._create_transaction(
|
||||
flow='redirect',
|
||||
sale_order_ids=[order.id],
|
||||
state='pending',
|
||||
reference=order.name,
|
||||
amount=order.amount_total,
|
||||
)
|
||||
# Our slow provider only gets around to confirming the transaction the next day
|
||||
with freeze_time(tomorrow):
|
||||
tx._set_done()
|
||||
tx._post_process()
|
||||
self.assertAlmostEqual(
|
||||
order.amount_total, tx.amount,
|
||||
msg="Discount should still apply if transaction gets confirmed post-expiration",
|
||||
)
|
||||
|
||||
def test_buy_x_get_y_free_applies_correctly_with_non_unit_uom(self):
|
||||
buy_x_get_y = self.env['loyalty.program'].create({
|
||||
'name': 'Buy 12 Take 6',
|
||||
'program_type': 'buy_x_get_y',
|
||||
'trigger': 'auto',
|
||||
'applies_on': 'current',
|
||||
'rule_ids': [Command.create({
|
||||
'reward_point_mode': 'unit',
|
||||
'product_ids': self.product_A.ids,
|
||||
})],
|
||||
'reward_ids': [Command.create({
|
||||
'reward_type': 'product',
|
||||
'reward_product_id': self.product_A.id,
|
||||
'required_points': 12,
|
||||
'reward_product_qty': 6,
|
||||
})],
|
||||
})
|
||||
order = self.empty_order
|
||||
order.order_line = [
|
||||
Command.create({
|
||||
'product_id': self.product_A.id,
|
||||
'product_uom_id': self.ref('uom.product_uom_dozen'),
|
||||
'product_uom_qty': 1,
|
||||
}),
|
||||
]
|
||||
self._auto_rewards(order, buy_x_get_y)
|
||||
reward_line = order.order_line.filtered('is_reward_line')
|
||||
self.assertTrue(reward_line)
|
||||
self.assertEqual(reward_line.product_uom_qty, 6)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue