Files
pms/pms/tests/test_pms_pricelist.py
2022-11-29 16:06:10 +01:00

1269 lines
53 KiB
Python

import datetime
from freezegun import freeze_time
from odoo import fields
from odoo.exceptions import ValidationError
from odoo.tests import tagged
from .common import TestPms
@tagged("standard", "nice")
class TestPmsPricelist(TestPms):
def setUp(self):
super().setUp()
self.pms_property2 = self.env["pms.property"].create(
{
"name": "Property_2",
"company_id": self.env.ref("base.main_company").id,
"default_pricelist_id": self.env.ref("product.list0").id,
}
)
self.pms_property3 = self.env["pms.property"].create(
{
"name": "Property_3",
"company_id": self.env.ref("base.main_company").id,
"default_pricelist_id": self.env.ref("product.list0").id,
}
)
self.room_type1 = self.env["pms.room.type"].create(
{
"pms_property_ids": [self.pms_property1.id, self.pms_property2.id],
"name": "Single",
"default_code": "SIN",
"class_id": self.room_type_class1.id,
"list_price": 30,
}
)
# pms.room
self.room1 = self.env["pms.room"].create(
{
"pms_property_id": self.pms_property1.id,
"name": "Single 101",
"room_type_id": self.room_type1.id,
"capacity": 2,
}
)
self.pricelist2 = self.env["product.pricelist"].create(
{
"name": "pricelist_2",
"pms_property_ids": [self.pms_property1.id, self.pms_property2.id],
"availability_plan_id": self.availability_plan1.id,
"is_pms_available": True,
}
)
# product.product 1
self.product1 = self.env["product.product"].create({"name": "Test Breakfast"})
# pms.board.service
self.board_service1 = self.env["pms.board.service"].create(
{
"name": "Test Only Breakfast",
"default_code": "CB1",
}
)
# pms.board.service.line
self.board_service_line1 = self.env["pms.board.service.line"].create(
{
"product_id": self.product1.id,
"pms_board_service_id": self.board_service1.id,
}
)
# pms.board.service.room.type
self.board_service_room_type1 = self.env["pms.board.service.room.type"].create(
{
"pms_room_type_id": self.room_type1.id,
"pms_board_service_id": self.board_service1.id,
}
)
self.partner1 = self.env["res.partner"].create({"name": "Carles"})
# create a sale channel
self.sale_channel_direct1 = self.env["pms.sale.channel"].create(
{
"name": "Door",
"channel_type": "direct",
}
)
@freeze_time("2000-01-01")
def test_board_service_pricelist_item_apply_sale_dates(self):
"""
Pricelist item is created to apply on board services at SALE date.
The reservation created take into account the board service
pricelist item created previously according to the SALE date.
"""
# ARRANGE
date_from = fields.date.today()
date_to = fields.date.today()
expected_price = 1000.0
vals = {
"pricelist_id": self.pricelist2.id,
"date_start": datetime.datetime.combine(
date_from, datetime.datetime.min.time()
),
"date_end": datetime.datetime.combine(
date_to, datetime.datetime.max.time()
),
"compute_price": "fixed",
"applied_on": "0_product_variant",
"product_id": self.product1.id,
"board_service_room_type_id": self.board_service_room_type1.id,
"fixed_price": expected_price,
"pms_property_ids": [self.pms_property1.id],
}
self.env["product.pricelist.item"].create(vals)
# ACT
reservation_created = self.env["pms.reservation"].create(
{
"partner_id": self.partner1.id,
"checkin": datetime.datetime.now(),
"checkout": datetime.datetime.now() + datetime.timedelta(days=1),
"preferred_room_id": self.room1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist2.id,
"board_service_room_id": self.board_service_room_type1.id,
"sale_channel_origin_id": self.sale_channel_direct1.id,
}
)
# ASSERT
self.assertEqual(
reservation_created.service_ids.price_subtotal,
expected_price,
"The reservation created should take into account the board service"
" pricelist item created previously according to the SALE date.",
)
@freeze_time("2000-01-01")
def test_board_service_pricelist_item_not_apply_sale_dates(self):
"""
Pricelist item is created to apply on board services at SALE date.
The reservation created DONT take into account the board service pricelist
item created previously according to the SALE date.
"""
# ARRANGE
date_from = fields.date.today() + datetime.timedelta(days=1)
date_to = fields.date.today() + datetime.timedelta(days=1)
not_expected_price = 1000.0
vals = {
"pricelist_id": self.pricelist2.id,
"date_start": datetime.datetime.combine(
date_from, datetime.datetime.min.time()
),
"date_end": datetime.datetime.combine(
date_to, datetime.datetime.max.time()
),
"compute_price": "fixed",
"applied_on": "0_product_variant",
"product_id": self.product1.id,
"board_service_room_type_id": self.board_service_room_type1.id,
"fixed_price": not_expected_price,
"pms_property_ids": [self.pms_property1.id],
}
self.env["product.pricelist.item"].create(vals)
# ACT
reservation_created = self.env["pms.reservation"].create(
{
"partner_id": self.partner1.id,
"checkin": datetime.datetime.now(),
"checkout": datetime.datetime.now() + datetime.timedelta(days=1),
"preferred_room_id": self.room1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist2.id,
"board_service_room_id": self.board_service_room_type1.id,
"sale_channel_origin_id": self.sale_channel_direct1.id,
}
)
# ASSERT
self.assertNotEqual(
reservation_created.service_ids.price_subtotal,
not_expected_price,
"The reservation created shouldnt take into account the board service pricelist"
" item created previously according to the SALE date.",
)
@freeze_time("2000-01-01")
def test_board_service_pricelist_item_apply_consumption_dates(self):
"""
Pricelist item is created to apply on board services
at CONSUMPTION date.
The reservation created take into account the board service
pricelist item created previously according to the CONSUMPTION date.
"""
# ARRANGE
date_from = fields.date.today() + datetime.timedelta(days=1)
date_to = fields.date.today() + datetime.timedelta(days=1)
expected_price = 1000.0
vals = {
"pricelist_id": self.pricelist2.id,
"date_start_consumption": date_from,
"date_end_consumption": date_to,
"compute_price": "fixed",
"applied_on": "0_product_variant",
"product_id": self.product1.id,
"board_service_room_type_id": self.board_service_room_type1.id,
"fixed_price": expected_price,
"pms_property_ids": [self.pms_property1.id],
}
self.env["product.pricelist.item"].create(vals)
# ACT
reservation_created = self.env["pms.reservation"].create(
{
"partner_id": self.partner1.id,
"checkin": datetime.datetime.now() + datetime.timedelta(days=1),
"checkout": datetime.datetime.now() + datetime.timedelta(days=2),
"preferred_room_id": self.room1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist2.id,
"board_service_room_id": self.board_service_room_type1.id,
"sale_channel_origin_id": self.sale_channel_direct1.id,
}
)
# ASSERT
self.assertEqual(
reservation_created.service_ids.price_subtotal,
expected_price,
"The reservation created should take into account the board service"
" pricelist item created previously according to the CONSUMPTION date.",
)
@freeze_time("2000-01-01")
def test_board_service_pricelist_item_not_apply_consumption_dates(self):
"""
Pricelist item is created to apply on board services
at CONSUMPTION date.
The reservation created DONT take into account the board service
pricelist item created previously according to the CONSUMPTION date.
"""
# ARRANGE
date_from = fields.date.today() + datetime.timedelta(days=2)
date_to = fields.date.today() + datetime.timedelta(days=2)
not_expected_price = 1000.0
vals = {
"pricelist_id": self.pricelist2.id,
"date_start": datetime.datetime.combine(
date_from, datetime.datetime.min.time()
),
"date_end": datetime.datetime.combine(
date_to, datetime.datetime.max.time()
),
"compute_price": "fixed",
"applied_on": "0_product_variant",
"product_id": self.product1.id,
"board_service_room_type_id": self.board_service_room_type1.id,
"fixed_price": not_expected_price,
"pms_property_ids": [self.pms_property1.id],
}
self.env["product.pricelist.item"].create(vals)
# ACT
reservation_created = self.env["pms.reservation"].create(
{
"partner_id": self.partner1.id,
"checkin": datetime.datetime.now(),
"checkout": datetime.datetime.now() + datetime.timedelta(days=1),
"preferred_room_id": self.room1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist2.id,
"board_service_room_id": self.board_service_room_type1.id,
"sale_channel_origin_id": self.sale_channel_direct1.id,
}
)
# ASSERT
self.assertNotEqual(
reservation_created.service_ids.price_subtotal,
not_expected_price,
"The reservation created shouldnt take into account the board service"
" pricelist item created previously according to the CONSUMPTION date.",
)
@freeze_time("2000-01-01")
def test_room_type_pricelist_item_apply_sale_dates(self):
"""
Pricelist item is created to apply on room types
at SALE date.
The reservation created take into account the room type
pricelist item created previously according to the SALE date.
"""
# ARRANGE
date_from = fields.date.today()
date_to = fields.date.today()
expected_price = 1000.0
vals = {
"pricelist_id": self.pricelist2.id,
"date_start": datetime.datetime.combine(
date_from, datetime.datetime.min.time()
),
"date_end": datetime.datetime.combine(
date_to, datetime.datetime.max.time()
),
"compute_price": "fixed",
"applied_on": "0_product_variant",
"product_id": self.room_type1.product_id.id,
"fixed_price": expected_price,
"pms_property_ids": [self.pms_property1.id],
}
self.env["product.pricelist.item"].create(vals)
# ACT
reservation_created = self.env["pms.reservation"].create(
{
"partner_id": self.partner1.id,
"checkin": datetime.datetime.now(),
"checkout": datetime.datetime.now() + datetime.timedelta(days=1),
"preferred_room_id": self.room1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist2.id,
"sale_channel_origin_id": self.sale_channel_direct1.id,
}
)
# ASSERT
self.assertEqual(
reservation_created.price_subtotal,
expected_price,
"The reservation created should take into account the room type"
" pricelist item created previously according to the SALE date.",
)
@freeze_time("2000-01-01")
def test_room_type_pricelist_item_not_apply_sale_dates(self):
"""
Pricelist item is created to apply on room types
at SALE date.
The reservation created DONT take into account the room type
pricelist item created previously according to the SALE date.
"""
# ARRANGE
date_from = fields.date.today() + datetime.timedelta(days=1)
date_to = fields.date.today() + datetime.timedelta(days=1)
not_expected_price = 1000.0
vals = {
"pricelist_id": self.pricelist2.id,
"date_start": datetime.datetime.combine(
date_from, datetime.datetime.min.time()
),
"date_end": datetime.datetime.combine(
date_to, datetime.datetime.max.time()
),
"compute_price": "fixed",
"applied_on": "0_product_variant",
"product_id": self.room_type1.product_id.id,
"fixed_price": not_expected_price,
"pms_property_ids": [self.pms_property1.id],
}
self.env["product.pricelist.item"].create(vals)
# ACT
reservation_created = self.env["pms.reservation"].create(
{
"partner_id": self.partner1.id,
"checkin": datetime.datetime.now(),
"checkout": datetime.datetime.now() + datetime.timedelta(days=1),
"preferred_room_id": self.room1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist2.id,
"sale_channel_origin_id": self.sale_channel_direct1.id,
}
)
# ASSERT
self.assertNotEqual(
reservation_created.price_subtotal,
not_expected_price,
"The reservation created shouldnt take into account the room type"
" pricelist item created previously according to the SALE date.",
)
@freeze_time("2000-01-01")
def test_room_type_pricelist_item_apply_consumption_dates(self):
"""
Pricelist item is created to apply on room types
at CONSUMPTION date.
The reservation created take into account the room type
pricelist item created previously according to the CONSUMPTION date.
"""
# ARRANGE
date_from = fields.date.today() + datetime.timedelta(days=1)
date_to = fields.date.today() + datetime.timedelta(days=1)
expected_price = 1000.0
vals = {
"pricelist_id": self.pricelist2.id,
"date_start_consumption": date_from,
"date_end_consumption": date_to,
"compute_price": "fixed",
"applied_on": "0_product_variant",
"product_id": self.room_type1.product_id.id,
"fixed_price": expected_price,
"pms_property_ids": [self.pms_property1.id],
}
self.env["product.pricelist.item"].create(vals)
# ACT
reservation_created = self.env["pms.reservation"].create(
{
"partner_id": self.partner1.id,
"checkin": datetime.datetime.now() + datetime.timedelta(days=1),
"checkout": datetime.datetime.now() + datetime.timedelta(days=2),
"preferred_room_id": self.room1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist2.id,
"sale_channel_origin_id": self.sale_channel_direct1.id,
}
)
# ASSERT
self.assertEqual(
reservation_created.price_subtotal,
expected_price,
"The reservation created should take into account the room type"
" pricelist item created previously according to the CONSUMPTION date.",
)
@freeze_time("2000-01-01")
def test_room_type_pricelist_item_not_apply_consumption_dates(self):
"""
Pricelist item is created to apply on room types
at CONSUMPTION date.
The reservation created DONT take into account the room type
pricelist item created previously according to the CONSUMPTION date.
"""
# ARRANGE
date_from = fields.date.today() + datetime.timedelta(days=2)
date_to = fields.date.today() + datetime.timedelta(days=2)
not_expected_price = 1000.0
vals = {
"pricelist_id": self.pricelist2.id,
"date_start": datetime.datetime.combine(
date_from, datetime.datetime.min.time()
),
"date_end": datetime.datetime.combine(
date_to, datetime.datetime.max.time()
),
"compute_price": "fixed",
"applied_on": "0_product_variant",
"product_id": self.room_type1.product_id.id,
"fixed_price": not_expected_price,
"pms_property_ids": [self.pms_property1.id],
}
self.env["product.pricelist.item"].create(vals)
# ACT
reservation_created = self.env["pms.reservation"].create(
{
"partner_id": self.partner1.id,
"checkin": datetime.datetime.now(),
"checkout": datetime.datetime.now() + datetime.timedelta(days=1),
"preferred_room_id": self.room1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist2.id,
"sale_channel_origin_id": self.sale_channel_direct1.id,
}
)
# ASSERT
self.assertNotEqual(
reservation_created.price_subtotal,
not_expected_price,
"The reservation created shouldnt take into account the room type"
" pricelist item created previously according to the CONSUMPTION date.",
)
@freeze_time("2000-01-01")
def test_service_pricelist_item_apply_sale_dates(self):
"""
Pricelist item is created to apply on services at SALE date.
The reservation created take into account the service
pricelist item created previously according to the SALE date.
"""
# ARRANGE
date_from = fields.date.today()
date_to = fields.date.today()
expected_price = 1000.0
vals = {
"pricelist_id": self.pricelist2.id,
"date_start": datetime.datetime.combine(
date_from, datetime.datetime.min.time()
),
"date_end": datetime.datetime.combine(
date_to, datetime.datetime.max.time()
),
"compute_price": "fixed",
"applied_on": "0_product_variant",
"product_id": self.product1.id,
"fixed_price": expected_price,
"pms_property_ids": [self.pms_property1.id],
}
self.env["product.pricelist.item"].create(vals)
# ACT
reservation_created = self.env["pms.reservation"].create(
{
"partner_id": self.partner1.id,
"checkin": datetime.datetime.now(),
"checkout": datetime.datetime.now() + datetime.timedelta(days=1),
"preferred_room_id": self.room1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist2.id,
"service_ids": [(0, 0, {"product_id": self.product1.id})],
"sale_channel_origin_id": self.sale_channel_direct1.id,
}
)
# ASSERT
self.assertEqual(
reservation_created.service_ids.price_subtotal,
expected_price,
"The reservation created should take into account the service"
" pricelist item created previously according to the SALE date.",
)
@freeze_time("2000-01-01")
def test_service_pricelist_item_not_apply_sale_dates(self):
"""
Pricelist item is created to apply on services at SALE date.
The reservation created DONT take into account the service pricelist
item created previously according to the SALE date.
"""
# ARRANGE
date_from = fields.date.today() + datetime.timedelta(days=1)
date_to = fields.date.today() + datetime.timedelta(days=1)
not_expected_price = 1000.0
vals = {
"pricelist_id": self.pricelist2.id,
"date_start": datetime.datetime.combine(
date_from, datetime.datetime.min.time()
),
"date_end": datetime.datetime.combine(
date_to, datetime.datetime.max.time()
),
"compute_price": "fixed",
"applied_on": "0_product_variant",
"product_id": self.product1.id,
"fixed_price": not_expected_price,
"pms_property_ids": [self.pms_property1.id],
}
self.env["product.pricelist.item"].create(vals)
# ACT
reservation_created = self.env["pms.reservation"].create(
{
"partner_id": self.partner1.id,
"checkin": datetime.datetime.now(),
"checkout": datetime.datetime.now() + datetime.timedelta(days=1),
"preferred_room_id": self.room1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist2.id,
"service_ids": [(0, 0, {"product_id": self.product1.id})],
"sale_channel_origin_id": self.sale_channel_direct1.id,
}
)
# ASSERT
self.assertNotEqual(
reservation_created.service_ids.price_subtotal,
not_expected_price,
"The reservation created shouldnt take into account the service pricelist"
" item created previously according to the SALE date.",
)
@freeze_time("2000-01-01")
def test_service_pricelist_item_apply_consumption_dates(self):
"""
Pricelist item is created to apply on services at CONSUMPTION date.
The reservation created take into account the service
pricelist item created previously according to the CONSUMPTION date.
"""
# ARRANGE
date_from = fields.date.today() + datetime.timedelta(days=1)
date_to = fields.date.today() + datetime.timedelta(days=1)
expected_price = 1000.0
vals = {
"pricelist_id": self.pricelist2.id,
"date_start_consumption": date_from,
"date_end_consumption": date_to,
"compute_price": "fixed",
"applied_on": "0_product_variant",
"product_id": self.product1.id,
"fixed_price": expected_price,
"pms_property_ids": [self.pms_property1.id],
}
self.env["product.pricelist.item"].create(vals)
# ACT
reservation_created = self.env["pms.reservation"].create(
{
"partner_id": self.partner1.id,
"checkin": datetime.datetime.now() + datetime.timedelta(days=1),
"checkout": datetime.datetime.now() + datetime.timedelta(days=2),
"preferred_room_id": self.room1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist2.id,
"service_ids": [(0, 0, {"product_id": self.product1.id})],
"sale_channel_origin_id": self.sale_channel_direct1.id,
}
)
# ASSERT
self.assertEqual(
reservation_created.service_ids.price_subtotal,
expected_price,
"The reservation created should take into account the service"
" pricelist item created previously according to the CONSUMPTION date.",
)
@freeze_time("2000-01-01")
def test_service_pricelist_item_not_apply_consumption_dates(self):
"""
Pricelist item is created to apply on services at CONSUMPTION date.
The reservation created DONT take into account the service pricelist
item created previously according to the CONSUMPTION date.
"""
# ARRANGE
date_from = fields.date.today() + datetime.timedelta(days=2)
date_to = fields.date.today() + datetime.timedelta(days=2)
not_expected_price = 1000.0
vals = {
"pricelist_id": self.pricelist2.id,
"date_start": datetime.datetime.combine(
date_from, datetime.datetime.min.time()
),
"date_end": datetime.datetime.combine(
date_to, datetime.datetime.max.time()
),
"compute_price": "fixed",
"applied_on": "0_product_variant",
"product_id": self.product1.id,
"fixed_price": not_expected_price,
"pms_property_ids": [self.pms_property1.id],
}
self.env["product.pricelist.item"].create(vals)
# ACT
reservation_created = self.env["pms.reservation"].create(
{
"partner_id": self.partner1.id,
"checkin": datetime.datetime.now(),
"checkout": datetime.datetime.now() + datetime.timedelta(days=1),
"preferred_room_id": self.room1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist2.id,
"service_ids": [(0, 0, {"product_id": self.product1.id})],
"sale_channel_origin_id": self.sale_channel_direct1.id,
}
)
# ASSERT
self.assertNotEqual(
reservation_created.service_ids.price_subtotal,
not_expected_price,
"The reservation created shouldnt take into account the service pricelist "
"item created previously according to the CONSUMPTION date.",
)
@freeze_time("2000-01-01")
def test_inconsistencies_pricelist_daily(self):
"""
Test cases to verify that a daily pricelist cannot be created because:
(Test case1): item has two properties and a items daily pricelist only
can has a one property.
(Test case2): item has all properties(pms_property_ids = False indicates
all properties)and a items daily pricelist only can has a one property.
(Test case3): item compute_price is 'percentage' and only can be 'fixed'
for items daily pricelist.
(Test case4): item compute_price is 'percentage' and has two properties
but compute_price can only be fixed and can only have one
property for items daily pricelist.
(Test case5): item compute_price is 'percentage' and has all properties
(pms_property_ids = False indicates all properties)but
compute_pricecan only be fixed and can only have one property for
items daily pricelist.
(Test case6): The difference of days between date_start_consumption and
date_end_consumption is three and the items of a daily pricelist
can only be one.
"""
test_cases = [
{
"compute_price": "fixed",
"pms_property_ids": [self.pms_property1.id, self.pms_property2.id],
"date_start_consumption": datetime.datetime.now(),
"date_end_consumption": datetime.datetime.today()
+ datetime.timedelta(days=1),
},
{
"compute_price": "fixed",
"pms_property_ids": False,
"date_start_consumption": datetime.datetime.now(),
"date_end_consumption": datetime.datetime.today()
+ datetime.timedelta(days=1),
},
{
"compute_price": "percentage",
"pms_property_ids": [self.pms_property1.id],
"date_start_consumption": datetime.datetime.now(),
"date_end_consumption": datetime.datetime.today()
+ datetime.timedelta(days=1),
},
{
"compute_price": "percentage",
"pms_property_ids": [self.pms_property1.id, self.pms_property2.id],
"date_start_consumption": datetime.datetime.now(),
"date_end_consumption": datetime.datetime.today()
+ datetime.timedelta(days=1),
},
{
"compute_price": "percentage",
"pms_property_ids": False,
"date_start_consumption": datetime.datetime.now(),
"date_end_consumption": datetime.datetime.today()
+ datetime.timedelta(days=1),
},
{
"compute_price": "fixed",
"pms_property_ids": [self.pms_property1.id],
"date_start_consumption": datetime.datetime.now(),
"date_end_consumption": datetime.datetime.today()
+ datetime.timedelta(days=3),
},
]
for tc in test_cases:
with self.subTest(k=tc):
with self.assertRaises(
ValidationError,
msg="Item only can has one property, the compute price only can"
"be fixed and the difference between date_start_consumption"
"and date_end_consumption only can be 1",
):
self.room_type1.pms_property_ids = tc["pms_property_ids"]
item = self.env["product.pricelist.item"].create(
{
"pms_property_ids": tc["pms_property_ids"],
"compute_price": tc["compute_price"],
"applied_on": "0_product_variant",
"product_id": self.room_type1.product_id.id,
"date_start_consumption": tc["date_start_consumption"],
"date_end_consumption": tc["date_end_consumption"],
}
)
self.pricelist_test = self.env["product.pricelist"].create(
{
"name": "Pricelist test",
"pricelist_type": "daily",
"pms_property_ids": tc["pms_property_ids"],
"item_ids": [item.id],
"availability_plan_id": self.availability_plan1.id,
"is_pms_available": True,
}
)
@freeze_time("2020-01-01")
def test_consistency_pricelist_daily(self):
"""
Test to verify that a daily pricelist is created.
Create a pricelist item with a property, the value of compute_price is
fixed and date_start_consumption date_end_consumption has the same value
"""
self.room_type1.pms_property_ids = (self.pms_property1.id,)
item = self.env["product.pricelist.item"].create(
{
"pms_property_ids": [self.pms_property1.id],
"compute_price": "fixed",
"applied_on": "0_product_variant",
"product_id": self.room_type1.product_id.id,
"date_start_consumption": datetime.date.today(),
"date_end_consumption": datetime.date.today(),
}
)
self.pricelist_test = self.env["product.pricelist"].create(
{
"name": "Pricelist test",
"pricelist_type": "daily",
"pms_property_ids": [self.pms_property1.id],
"item_ids": [item.id],
"availability_plan_id": self.availability_plan1.id,
"is_pms_available": True,
}
)
self.assertTrue(self.pricelist_test, "Pricelist not created.")
@freeze_time("2000-01-01")
def test_simple_price_without_items(self):
"""
Test case for no items applied in a reservation.
"""
# ARRANGE
self.room_type = self.env["pms.room.type"].create(
{
"pms_property_ids": [self.pms_property1.id, self.pms_property2.id],
"name": "Single",
"default_code": "S",
"class_id": self.room_type_class1.id,
"list_price": 30,
}
)
self.room = self.env["pms.room"].create(
{
"pms_property_id": self.pms_property1.id,
"name": "Single 1",
"room_type_id": self.room_type.id,
}
)
reservation = self.env["pms.reservation"].create(
{
"checkin": datetime.datetime.today(),
"checkout": datetime.datetime.today() + datetime.timedelta(days=3),
"preferred_room_id": self.room.id,
"pms_property_id": self.pms_property1.id,
"partner_id": self.partner1.id,
"sale_channel_origin_id": self.sale_channel_direct1.id,
}
)
# ACT
n_days = (reservation.checkout - reservation.checkin).days
expected_price = self.room.room_type_id.list_price * n_days
# ASSERT
self.assertEqual(
expected_price, reservation.price_subtotal, "The price is not as expected"
)
@freeze_time("2022-01-01")
def test_items_sort(self):
"""
Test cases to verify the order for each field considered individually
Test cases to prioritize fields over other fields:
1. applied_on
2. date
3. date consumption
4. num. properties
5. id
- tie
- no [date_start|date_end|date_start_consumption|date_end_consumption]
"""
# ARRANGE
self.product_category = self.env["product.category"].create(
{"name": "Category1"}
)
self.product_template = self.env["product.template"].create(
{"name": "Template1"}
)
self.room_type = self.env["pms.room.type"].create(
{
"pms_property_ids": [self.pms_property1.id, self.pms_property2.id],
"name": "Single",
"default_code": "SGL",
"class_id": self.room_type_class1.id,
"list_price": 30,
}
)
self.room = self.env["pms.room"].create(
{
"pms_property_id": self.pms_property1.id,
"name": "101",
"room_type_id": self.room_type.id,
}
)
properties = self.room_type.product_id.pms_property_ids.ids
test_cases = [
{
"name": "sorting applied_on",
"expected_price": 50 * 3,
"items": [
{
"pricelist_id": self.pricelist1.id,
"applied_on": "2_product_category",
"categ_id": self.product_category.id,
"fixed_price": 60.0,
},
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"fixed_price": 50.0,
"pms_property_ids": properties,
},
{
"pricelist_id": self.pricelist1.id,
"applied_on": "1_product",
"product_id": self.room_type.product_id.id,
"product_tmpl_id": self.product_template.id,
"fixed_price": 40.0,
"pms_property_ids": properties,
},
],
},
{
"name": "sorting SALE date min range",
"expected_price": 50.0 * 3,
"items": [
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start": datetime.datetime.now(),
"date_end": datetime.datetime.now()
+ datetime.timedelta(days=2),
"fixed_price": 60.0,
"pms_property_ids": properties,
},
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start": datetime.datetime.now(),
"date_end": datetime.datetime.now()
+ datetime.timedelta(days=1),
"fixed_price": 50.0,
"pms_property_ids": properties,
},
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start": datetime.datetime.now(),
"date_end": datetime.datetime.now()
+ datetime.timedelta(days=3),
"fixed_price": 40.0,
"pms_property_ids": properties,
},
],
},
{
"name": "sorting CONSUMPTION date min range",
"expected_price": 40.0 * 3,
"items": [
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start_consumption": datetime.datetime.now(),
"date_end_consumption": datetime.datetime.now()
+ datetime.timedelta(days=6),
"fixed_price": 60.0,
"pms_property_ids": properties,
},
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start_consumption": datetime.datetime.now(),
"date_end_consumption": datetime.datetime.now()
+ datetime.timedelta(days=10),
"fixed_price": 50.0,
"pms_property_ids": properties,
},
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start_consumption": datetime.datetime.now(),
"date_end_consumption": datetime.datetime.now()
+ datetime.timedelta(days=3),
"fixed_price": 40.0,
"pms_property_ids": properties,
},
],
},
{
"name": "sorting num. properties",
"expected_price": 50.0 * 3,
"items": [
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"fixed_price": 60.0,
"pms_property_ids": properties,
},
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"pms_property_ids": [self.pms_property1.id],
"fixed_price": 50.0,
},
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"pms_property_ids": [
self.pms_property1.id,
self.pms_property2.id,
],
"fixed_price": 40.0,
},
],
},
{
"name": "sorting by item id",
"expected_price": 40.0 * 3,
"items": [
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"fixed_price": 60.0,
"pms_property_ids": properties,
},
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"fixed_price": 50.0,
"pms_property_ids": properties,
},
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"fixed_price": 40.0,
"pms_property_ids": properties,
},
],
},
{
"name": "prioritize applied_on over SALE date",
"expected_price": 60.0 * 3,
"items": [
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start": datetime.datetime.now(),
"date_end": datetime.datetime.now()
+ datetime.timedelta(days=2),
"fixed_price": 60.0,
"pms_property_ids": properties,
},
{
"pricelist_id": self.pricelist1.id,
"product_id": self.room_type.product_id.id,
"product_tmpl_id": self.product_template.id,
"applied_on": "1_product",
"date_start": datetime.datetime.now(),
"date_end": datetime.datetime.now()
+ datetime.timedelta(days=1),
"fixed_price": 50.0,
"pms_property_ids": properties,
},
],
},
{
"name": "prioritize SALE date over CONSUMPTION date",
"expected_price": 120.0 * 3,
"items": [
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start": datetime.datetime.now(),
"date_end": datetime.datetime.now()
+ datetime.timedelta(days=10),
"fixed_price": 120.0,
"pms_property_ids": properties,
},
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start_consumption": datetime.datetime.now(),
"date_end_consumption": datetime.datetime.now()
+ datetime.timedelta(days=3),
"fixed_price": 50.0,
"pms_property_ids": properties,
},
],
},
{
"name": "prioritize CONSUMPTION date over min. num. properties",
"expected_price": 50.0 * 3,
"items": [
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start_consumption": datetime.datetime.now(),
"date_end_consumption": datetime.datetime.now()
+ datetime.timedelta(days=3),
"fixed_price": 120.0,
"pms_property_ids": properties,
},
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start_consumption": datetime.datetime.now(),
"date_end_consumption": datetime.datetime.now()
+ datetime.timedelta(days=3),
"pms_property_ids": [
self.pms_property1.id,
self.pms_property2.id,
],
"fixed_price": 50.0,
},
],
},
{
"name": "prioritize min. num. properties over item id",
"expected_price": 50.0 * 3,
"items": [
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start_consumption": datetime.datetime.now(),
"date_end_consumption": datetime.datetime.now()
+ datetime.timedelta(days=3),
"fixed_price": 120.0,
"pms_property_ids": properties,
},
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start_consumption": datetime.datetime.now(),
"date_end_consumption": datetime.datetime.now()
+ datetime.timedelta(days=3),
"pms_property_ids": [
self.pms_property1.id,
self.pms_property2.id,
],
"fixed_price": 50.0,
},
],
},
{
"name": "tie => order by item id",
"expected_price": 50.0 * 3,
"items": [
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start_consumption": datetime.datetime.now(),
"date_end_consumption": datetime.datetime.now()
+ datetime.timedelta(days=3),
"date_start": datetime.datetime.now(),
"date_end": datetime.datetime.now()
+ datetime.timedelta(days=3),
"pms_property_ids": [
self.pms_property1.id,
self.pms_property2.id,
],
"fixed_price": 120.0,
},
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start_consumption": datetime.datetime.now(),
"date_end_consumption": datetime.datetime.now()
+ datetime.timedelta(days=3),
"date_start": datetime.datetime.now(),
"date_end": datetime.datetime.now()
+ datetime.timedelta(days=3),
"pms_property_ids": [
self.pms_property1.id,
self.pms_property2.id,
],
"fixed_price": 50.0,
},
],
},
{
"name": "no SALE DATE START",
"expected_price": 40.0 * 3,
"items": [
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_end": datetime.datetime.now()
+ datetime.timedelta(days=1),
"fixed_price": 40.0,
"pms_property_ids": properties,
},
],
},
{
"name": "no SALE DATE END",
"expected_price": 40.0 * 3,
"items": [
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start": datetime.datetime.now(),
"fixed_price": 40.0,
"pms_property_ids": properties,
},
],
},
{
"name": "no consumption DATE START",
"expected_price": 40.0 + self.room_type.list_price * 2,
"items": [
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_end_consumption": datetime.datetime.now(),
"fixed_price": 40.0,
"pms_property_ids": properties,
},
],
},
{
"name": "no consumption DATE END",
"expected_price": 40.0 * 3,
"items": [
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start_consumption": datetime.datetime.now(),
"fixed_price": 40.0,
"pms_property_ids": properties,
},
],
},
{
"name": "only applied consumption in one night",
"expected_price": 40.0 + self.room_type.list_price * 2,
"items": [
{
"pricelist_id": self.pricelist1.id,
"applied_on": "0_product_variant",
"product_id": self.room_type.product_id.id,
"date_start_consumption": datetime.datetime.now(),
"date_end_consumption": datetime.datetime.now(),
"fixed_price": 40.0,
"pms_property_ids": properties,
},
],
},
]
for tc in test_cases:
with self.subTest(k=tc):
# ARRANGE
items = []
for item in tc["items"]:
item = self.env["product.pricelist.item"].create(item)
items.append(item.id)
# ACT
reservation = self.env["pms.reservation"].create(
{
"partner_id": self.partner1.id,
"checkin": datetime.datetime.now(),
"checkout": datetime.datetime.now()
+ datetime.timedelta(days=3),
"preferred_room_id": self.room.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist1.id,
"sale_channel_origin_id": self.sale_channel_direct1.id,
}
)
reservation_price = reservation.price_subtotal
self.env["pms.reservation"].browse(reservation.id).unlink()
self.env["product.pricelist.item"].browse(items).unlink()
# ASSERT
self.assertEqual(tc["expected_price"], reservation_price, tc["name"])