[ADD] pms: wizard massive changes on availability plans and pricelists (#28)

* [IMP] pms: wizard massive changes on availability plans

* [TEST] add creation rule based on weeek days

* [REF] pms: model av. plan, rule_ids & inv. name

* [IMP] pms: wizard called from pricelist & availability plans consistently

* [IMP] pms: wizard massive changes on pricelists

* [FIX] pms: fix creation pricelist items

* [FIX] pms: fix timezone on create pricelist items

* [TEST] pms: fix time zone issues in testing
This commit is contained in:
Miguel Padin
2020-12-22 10:53:13 +01:00
committed by GitHub
parent 977feac1e6
commit 5f7bd6b540
24 changed files with 1218 additions and 79 deletions

View File

@@ -26,4 +26,5 @@ from . import test_pms_checkin_partner
from . import test_pms_sale_channel
from . import test_pms_folio
from . import test_pms_room_type_availability_rules
from . import test_pms_room_type
from . import test_pms_room_type
from . import test_pms_wizard_massive_changes

View File

@@ -15,11 +15,11 @@ class TestPmsPricelistRules(common.TransactionCase):
{"name": "Category1"}
)
self.availability = self.env["pms.room.type.availability"].create(
self.availability_plan1 = self.env["pms.room.type.availability.plan"].create(
{"name": "Availability 1"}
)
self.availability2 = self.env["pms.room.type.availability"].create(
self.availability_plan2 = self.env["pms.room.type.availability.plan"].create(
{"name": "Availability"}
)
self.property1 = self.env["pms.property"].create(
@@ -27,7 +27,7 @@ class TestPmsPricelistRules(common.TransactionCase):
"name": "Property_1",
"company_id": self.env.ref("base.main_company").id,
"default_pricelist_id": self.env.ref("product.list0").id,
"default_availability_id": self.availability.id,
"default_availability_plan_id": self.availability_plan1.id,
}
)
@@ -36,7 +36,7 @@ class TestPmsPricelistRules(common.TransactionCase):
"name": "Property_2",
"company_id": self.env.ref("base.main_company").id,
"default_pricelist_id": self.env.ref("product.list0").id,
"default_availability_id": self.availability2.id,
"default_availability_plan_id": self.availability_plan2.id,
}
)

View File

@@ -12,9 +12,9 @@ from .common import TestHotel
class TestPmsReservations(TestHotel):
def create_common_scenario(self):
# create a room type availability
self.room_type_availability = self.env["pms.room.type.availability"].create(
{"name": "Availability plan for TEST"}
)
self.room_type_availability = self.env[
"pms.room.type.availability.plan"
].create({"name": "Availability plan for TEST"})
# create a property
self.property = self.env["pms.property"].create(
@@ -22,7 +22,7 @@ class TestPmsReservations(TestHotel):
"name": "MY PMS TEST",
"company_id": self.env.ref("base.main_company").id,
"default_pricelist_id": self.env.ref("product.list0").id,
"default_availability_id": self.room_type_availability.id,
"default_availability_plan_id": self.room_type_availability.id,
}
)

View File

@@ -15,8 +15,8 @@ class TestRoomType(SavepointCase):
"name": "p2",
"company_id": self.m1.id,
"default_pricelist_id": self.ref("product.list0"),
"default_availability_id": self.ref(
"pms.main_pms_room_type_availability"
"default_availability_plan_id": self.ref(
"pms.main_pms_room_type_availability_plan"
),
}
)
@@ -30,8 +30,8 @@ class TestRoomType(SavepointCase):
"name": "p3",
"company_id": self.m2.id,
"default_pricelist_id": self.ref("product.list0"),
"default_availability_id": self.ref(
"pms.main_pms_room_type_availability"
"default_availability_plan_id": self.ref(
"pms.main_pms_room_type_availability_plan"
),
}
)

View File

@@ -17,9 +17,9 @@ class TestPmsRoomTypeAvailabilityRules(TestHotel):
"name": "test pricelist 1",
}
)
# pms.room.type.availability
# pms.room.type.availability.plan
self.test_room_type_availability1 = self.env[
"pms.room.type.availability"
"pms.room.type.availability.plan"
].create(
{
"name": "Availability plan for TEST",
@@ -32,7 +32,7 @@ class TestPmsRoomTypeAvailabilityRules(TestHotel):
"name": "MY PMS TEST",
"company_id": self.env.ref("base.main_company").id,
"default_pricelist_id": self.test_pricelist1.id,
"default_availability_id": self.test_room_type_availability1.id,
"default_availability_plan_id": self.test_room_type_availability1.id,
}
)
# pms.room.type.class
@@ -127,7 +127,7 @@ class TestPmsRoomTypeAvailabilityRules(TestHotel):
)
# ACT
result = self.env["pms.room.type.availability"].rooms_available(
result = self.env["pms.room.type.availability.plan"].rooms_available(
checkin=checkin,
checkout=checkout,
)
@@ -160,7 +160,7 @@ class TestPmsRoomTypeAvailabilityRules(TestHotel):
)
# ACT
result = self.env["pms.room.type.availability"].rooms_available(
result = self.env["pms.room.type.availability.plan"].rooms_available(
checkin=checkin,
checkout=checkout,
current_lines=test_reservation.reservation_line_ids.ids,
@@ -188,7 +188,7 @@ class TestPmsRoomTypeAvailabilityRules(TestHotel):
)
# ACT
result = self.env["pms.room.type.availability"].rooms_available(
result = self.env["pms.room.type.availability.plan"].rooms_available(
checkin=fields.date.today(),
checkout=(fields.datetime.today() + datetime.timedelta(days=4)).date(),
room_type_id=self.test_room_type_double.id,
@@ -215,14 +215,14 @@ class TestPmsRoomTypeAvailabilityRules(TestHotel):
"pms.room.type.availability.rule"
].create(
{
"availability_id": self.test_room_type_availability1.id,
"availability_plan_id": self.test_room_type_availability1.id,
"room_type_id": self.test_room_type_double.id,
"date": (fields.datetime.today() + datetime.timedelta(days=2)).date(),
"closed": True, # <- (1/2)
}
)
# ACT
result = self.env["pms.room.type.availability"].rooms_available(
result = self.env["pms.room.type.availability.plan"].rooms_available(
checkin=fields.date.today(),
checkout=(fields.datetime.today() + datetime.timedelta(days=4)).date(),
# room_type_id=False, # <- (2/2)
@@ -249,7 +249,7 @@ class TestPmsRoomTypeAvailabilityRules(TestHotel):
"pms.room.type.availability.rule"
].create(
{
"availability_id": self.test_room_type_availability1.id,
"availability_plan_id": self.test_room_type_availability1.id,
"room_type_id": self.test_room_type_double.id,
"date": (fields.datetime.today() + datetime.timedelta(days=0)).date(),
}
@@ -363,7 +363,7 @@ class TestPmsRoomTypeAvailabilityRules(TestHotel):
# ACT
self.test_room_type_availability1_item1.write(test_case)
result = self.env["pms.room.type.availability"].rooms_available(
result = self.env["pms.room.type.availability.plan"].rooms_available(
checkin=checkin,
checkout=checkout,
room_type_id=self.test_room_type_double.id,
@@ -390,7 +390,7 @@ class TestPmsRoomTypeAvailabilityRules(TestHotel):
"pms.room.type.availability.rule"
].create(
{
"availability_id": self.test_room_type_availability1.id,
"availability_plan_id": self.test_room_type_availability1.id,
"room_type_id": self.test_room_type_double.id,
"date": (fields.datetime.today() + datetime.timedelta(days=2)).date(),
"closed": True,
@@ -429,7 +429,7 @@ class TestPmsRoomTypeAvailabilityRules(TestHotel):
"pms.room.type.availability.rule"
].create(
{
"availability_id": self.test_room_type_availability1.id,
"availability_plan_id": self.test_room_type_availability1.id,
"room_type_id": self.test_room_type_double.id,
"date": (fields.datetime.today() + datetime.timedelta(days=2)).date(),
"closed": True,
@@ -491,7 +491,7 @@ class TestPmsRoomTypeAvailabilityRules(TestHotel):
"pms.room.type.availability.rule"
].create(
{
"availability_id": self.test_room_type_availability1.id,
"availability_plan_id": self.test_room_type_availability1.id,
"room_type_id": self.test_room_type_double.id,
"date": datetime.date.today(),
"quota": 1,
@@ -541,7 +541,7 @@ class TestPmsRoomTypeAvailabilityRules(TestHotel):
)
rule = self.env["pms.room.type.availability.rule"].create(
{
"availability_id": self.test_room_type_availability1.id,
"availability_plan_id": self.test_room_type_availability1.id,
"room_type_id": self.test_room_type_double.id,
"date": datetime.date.today(),
"quota": test_quota,

View File

@@ -0,0 +1,414 @@
import datetime
import pytz
from freezegun import freeze_time
from odoo import fields
from .common import TestHotel
class TestPmsWizardMassiveChanges(TestHotel):
def create_common_scenario(self):
# product.pricelist
self.test_pricelist = self.env["product.pricelist"].create(
{
"name": "test pricelist 1",
}
)
# pms.room.type.availability.plan
self.test_availability_plan = self.env[
"pms.room.type.availability.plan"
].create(
{
"name": "Availability plan for TEST",
"pms_pricelist_ids": [(6, 0, [self.test_pricelist.id])],
}
)
# pms.property
self.test_property = self.env["pms.property"].create(
{
"name": "MY PMS TEST",
"company_id": self.env.ref("base.main_company").id,
"default_pricelist_id": self.test_pricelist.id,
"default_availability_plan_id": self.test_availability_plan.id,
}
)
# pms.room.type.class
self.test_room_type_class = self.env["pms.room.type.class"].create(
{"name": "Room"}
)
# pms.room.type
self.test_room_type_single = self.env["pms.room.type"].create(
{
"pms_property_ids": [self.test_property.id],
"name": "Single Test",
"code_type": "SNG_Test",
"class_id": self.test_room_type_class.id,
}
)
# pms.room.type
self.test_room_type_double = self.env["pms.room.type"].create(
{
"pms_property_ids": [self.test_property.id],
"name": "Double Test",
"code_type": "DBL_Test",
"class_id": self.test_room_type_class.id,
}
)
# MASSIVE CHANGE WIZARD TESTS ON AVAILABILITY RULES
@freeze_time("1980-12-01")
def test_num_availability_rules_create(self):
# TEST CASE
# rules should be created consistently for 1,2,3,4 days
# ARRANGE
self.create_common_scenario()
for days in [0, 1, 2, 3]:
with self.subTest(k=days):
num_exp_rules_to_create = days + 1
self.env["pms.massive.changes.wizard"].create(
{
"massive_changes_on": "availability_plan",
"availability_plan_id": self.test_availability_plan.id,
"start_date": fields.date.today(),
"end_date": fields.date.today() + datetime.timedelta(days=days),
"room_type_id": self.test_room_type_double.id,
}
).apply_massive_changes()
self.assertEqual(
len(self.test_availability_plan.rule_ids),
num_exp_rules_to_create,
"the number of rules created by should contains all the "
"days between start and finish (both included)",
)
@freeze_time("1980-12-01")
def test_num_availability_rules_create_no_room_type(self):
# TEST CASE
# (days x room_types) rules should be created
# ARRANGE
self.create_common_scenario()
date_from = fields.date.today()
date_to = fields.date.today() + datetime.timedelta(days=3)
num_room_types = self.env["pms.room.type"].search_count([])
num_exp_rules_to_create = ((date_to - date_from).days + 1) * num_room_types
# ACT
self.env["pms.massive.changes.wizard"].create(
{
"massive_changes_on": "availability_plan",
"availability_plan_id": self.test_availability_plan.id,
"start_date": date_from,
"end_date": date_to,
}
).apply_massive_changes()
# ASSERT
self.assertEqual(
len(self.test_availability_plan.rule_ids),
num_exp_rules_to_create,
"the number of rules created by the wizard should consider all "
"room types",
)
@freeze_time("1980-12-01")
def test_value_availability_rules_create(self):
# TEST CASE
# Rule values should be set correctly
# ARRANGE
self.create_common_scenario()
date_from = fields.date.today()
date_to = fields.date.today()
vals = {
"massive_changes_on": "availability_plan",
"availability_plan_id": self.test_availability_plan.id,
"start_date": date_from,
"end_date": date_to,
"room_type_id": self.test_room_type_double.id,
"quota": 50,
"max_avail": 5,
"min_stay": 10,
"min_stay_arrival": 10,
"max_stay": 10,
"max_stay_arrival": 10,
"closed": True,
"closed_arrival": True,
"closed_departure": True,
}
# ACT
self.env["pms.massive.changes.wizard"].create(vals).apply_massive_changes()
# ASSERT
del vals["massive_changes_on"]
del vals["availability_plan_id"]
del vals["start_date"]
del vals["end_date"]
del vals["room_type_id"]
for key in vals:
with self.subTest(k=key):
self.assertEqual(
self.test_availability_plan.rule_ids[0][key],
vals[key],
"The value of " + key + " is not correctly established",
)
@freeze_time("1980-12-01")
def test_day_of_week_availability_rules_create(self):
# TEST CASE
# rules for each day of week should be created
# ARRANGE
self.create_common_scenario()
test_case_week_days = [
[1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 1],
]
date_from = fields.date.today()
date_to = fields.date.today() + datetime.timedelta(days=6)
wizard = self.env["pms.massive.changes.wizard"].create(
{
"massive_changes_on": "availability_plan",
"availability_plan_id": self.test_availability_plan.id,
"room_type_id": self.test_room_type_double.id,
"start_date": date_from,
"end_date": date_to,
}
)
for index, test_case in enumerate(test_case_week_days):
with self.subTest(k=test_case):
# ARRANGE
wizard.write(
{
"apply_on_monday": test_case[0],
"apply_on_tuesday": test_case[1],
"apply_on_wednesday": test_case[2],
"apply_on_thursday": test_case[3],
"apply_on_friday": test_case[4],
"apply_on_saturday": test_case[5],
"apply_on_sunday": test_case[6],
}
)
# ACT
wizard.apply_massive_changes()
availability_rules = self.test_availability_plan.rule_ids.sorted(
key=lambda s: s.date
)
# ASSERT
self.assertTrue(
availability_rules[index].date.timetuple()[6] == index
and test_case[index],
"Rule not created on correct day of week",
)
# MASSIVE CHANGE WIZARD TESTS ON PRICELIST ITEMS
@freeze_time("1980-12-01")
def test_pricelist_items_create(self):
# TEST CASE
# items should be created consistently for 1,2,3,4 days
# ARRANGE
self.create_common_scenario()
for days in [0, 1, 2, 3]:
with self.subTest(k=days):
# ARRANGE
num_exp_items_to_create = days + 1
self.test_pricelist.item_ids = False
# ACT
self.env["pms.massive.changes.wizard"].create(
{
"massive_changes_on": "pricelist",
"pricelist_id": self.test_pricelist.id,
"start_date": fields.date.today(),
"end_date": fields.date.today() + datetime.timedelta(days=days),
"room_type_id": self.test_room_type_double.id,
}
).apply_massive_changes()
# ASSERT
self.assertEqual(
len(
self.test_pricelist.item_ids
if self.test_pricelist.item_ids
else []
),
num_exp_items_to_create,
"the number of rules created by the wizard should include all the "
"days between start and finish (both included)",
)
@freeze_time("1980-12-01")
def test_num_pricelist_items_create_no_room_type(self):
# TEST CASE
# (days x room_types) items should be created
# ARRANGE
self.create_common_scenario()
date_from = fields.date.today()
date_to = fields.date.today() + datetime.timedelta(days=3)
num_room_types = self.env["pms.room.type"].search_count([])
num_exp_items_to_create = ((date_to - date_from).days + 1) * num_room_types
# ACT
self.env["pms.massive.changes.wizard"].create(
{
"massive_changes_on": "pricelist",
"pricelist_id": self.test_pricelist.id,
"start_date": date_from,
"end_date": date_to,
}
).apply_massive_changes()
# ASSERT
self.assertEqual(
len(self.test_pricelist.item_ids),
num_exp_items_to_create,
"the number of rules created by the wizard should consider all "
"room types when one is not applied",
)
@freeze_time("1980-12-01")
def test_value_pricelist_items_create(self):
# TEST CASE
# Item values should be set correctly
# ARRANGE
self.create_common_scenario()
date_from = fields.date.today()
date_to = fields.date.today()
price = 20
min_quantity = 3
vals = {
"pricelist_id": self.test_pricelist,
"date_start": datetime.datetime.combine(
date_from,
datetime.time.min,
),
"date_end": datetime.datetime.combine(
date_to,
datetime.time.max,
),
"compute_price": "fixed",
"applied_on": "1_product",
"product_tmpl_id": self.test_room_type_double.product_id.product_tmpl_id,
"fixed_price": price,
"min_quantity": min_quantity,
}
# ACT
self.env["pms.massive.changes.wizard"].create(
{
"massive_changes_on": "pricelist",
"pricelist_id": self.test_pricelist.id,
"start_date": date_from,
"end_date": date_to,
"room_type_id": self.test_room_type_double.id,
"price": price,
"min_quantity": min_quantity,
}
).apply_massive_changes()
vals["date_start"] = pytz.timezone("Europe/Madrid").localize(vals["date_start"])
vals["date_end"] = pytz.timezone("Europe/Madrid").localize(vals["date_end"])
# ASSERT
for key in vals:
with self.subTest(k=key):
if key == "date_start" or key == "date_end":
self.assertEqual(
fields.Datetime.context_timestamp(
self.test_pricelist.item_ids[0],
self.test_pricelist.item_ids[0][key],
),
vals[key],
"The value of " + key + " is not correctly established",
)
else:
self.assertEqual(
self.test_pricelist.item_ids[0][key],
vals[key],
"The value of " + key + " is not correctly established",
)
@freeze_time("1980-12-01")
def test_day_of_week_pricelist_items_create(self):
# TEST CASE
# items for each day of week should be created
# ARRANGE
self.create_common_scenario()
test_case_week_days = [
[1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 1],
]
date_from = fields.date.today()
date_to = date_from + datetime.timedelta(days=6)
wizard = self.env["pms.massive.changes.wizard"].create(
{
"massive_changes_on": "pricelist",
"pricelist_id": self.test_pricelist.id,
"room_type_id": self.test_room_type_double.id,
"start_date": date_from,
"end_date": date_to,
}
)
for index, test_case in enumerate(test_case_week_days):
with self.subTest(k=test_case):
# ARRANGE
wizard.write(
{
"apply_on_monday": test_case[0],
"apply_on_tuesday": test_case[1],
"apply_on_wednesday": test_case[2],
"apply_on_thursday": test_case[3],
"apply_on_friday": test_case[4],
"apply_on_saturday": test_case[5],
"apply_on_sunday": test_case[6],
}
)
self.test_pricelist.item_ids = False
# ACT
wizard.apply_massive_changes()
# ASSERT
pricelist_items = self.test_pricelist.item_ids.sorted(
key=lambda s: s.date_start
)
# ASSERT
self.assertTrue(
(
fields.Datetime.context_timestamp(
pricelist_items[index], pricelist_items[index].date_start
)
).timetuple()[6]
== index
and test_case[index],
"Rule not created on correct day of week",
)