[RFC] Availability and free rooms

This commit is contained in:
Dario Lodeiros
2021-07-06 20:04:53 +02:00
parent 17b7921787
commit ff41cad50c
10 changed files with 314 additions and 260 deletions

View File

@@ -1,10 +1,7 @@
# Copyright 2017 Alexandre Díaz
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import datetime
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
from odoo import api, fields, models
class PmsAvailabilityPlan(models.Model):
@@ -72,204 +69,6 @@ class PmsAvailabilityPlan(models.Model):
]
)
@api.model
def rooms_available(
self,
checkin,
checkout,
room_type_id=False,
current_lines=False,
pricelist_id=False,
pms_property_id=False,
):
if current_lines and not isinstance(current_lines, list):
current_lines = [current_lines]
free_rooms = self.get_real_free_rooms(
checkin, checkout, room_type_id, current_lines, pms_property_id
)
domain_rules = [
("date", ">=", checkin),
(
"date",
"<=",
checkout,
), # TODO: only closed_departure take account checkout date!
]
if pms_property_id:
domain_rules.append(("pms_property_id", "=", pms_property_id))
if room_type_id:
domain_rules.append(("room_type_id", "=", room_type_id))
if pricelist_id:
pricelist = self.env["product.pricelist"].browse(pricelist_id)
if pricelist and pricelist.availability_plan_id:
domain_rules.append(
("availability_plan_id", "=", pricelist.availability_plan_id.id)
)
rule_items = self.env["pms.availability.plan.rule"].search(domain_rules)
if len(rule_items) > 0:
room_types_to_remove = []
for item in rule_items:
if self.any_rule_applies(checkin, checkout, item):
room_types_to_remove.append(item.room_type_id.id)
free_rooms = free_rooms.filtered(
lambda x: x.room_type_id.id not in room_types_to_remove
)
elif not pricelist:
raise ValidationError(_("Pricelist not found"))
return free_rooms.sorted(key=lambda r: r.sequence)
def get_real_free_rooms(
self,
checkin,
checkout,
room_type_id=False,
current_lines=False,
pms_property_id=False,
):
Avail = self.env["pms.availability"]
if isinstance(checkin, str):
checkin = datetime.datetime.strptime(
checkin, DEFAULT_SERVER_DATE_FORMAT
).date()
if isinstance(checkout, str):
checkout = datetime.datetime.strptime(
checkout, DEFAULT_SERVER_DATE_FORMAT
).date()
domain = [
("date", ">=", checkin),
("date", "<=", checkout - datetime.timedelta(1)),
]
if not current_lines:
current_lines = []
rooms_not_avail = (
Avail.search(domain)
.reservation_line_ids.filtered(
lambda l: l.occupies_availability and l.id and l.id not in current_lines
)
.room_id.ids
)
domain_rooms = []
if rooms_not_avail:
domain_rooms = [
("id", "not in", rooms_not_avail),
]
if pms_property_id:
domain_rooms.append(("pms_property_id", "=", pms_property_id))
if room_type_id:
domain_rooms.append(("room_type_id", "=", room_type_id))
return self.env["pms.room"].search(domain_rooms)
@api.model
def get_count_rooms_available(
self,
checkin,
checkout,
room_type_id,
pms_property_id,
current_lines=False,
pricelist_id=False,
):
if current_lines and not isinstance(current_lines, list):
current_lines = [current_lines]
avail = self.get_count_real_free_rooms(
checkin, checkout, room_type_id, pms_property_id, current_lines
)
domain_rules = [
("date", ">=", checkin),
(
"date",
"<=",
checkout,
), # TODO: only closed_departure take account checkout date!
("room_type_id", "=", room_type_id),
("pms_property_id", "=", pms_property_id),
]
pricelist = False
if pricelist_id:
pricelist = self.env["product.pricelist"].browse(pricelist_id)
if pricelist and pricelist.availability_plan_id:
domain_rules.append(
("availability_plan_id", "=", pricelist.availability_plan_id.id)
)
rule_items = self.env["pms.availability.plan.rule"].search(domain_rules)
if len(rule_items) > 0:
for item in rule_items:
if self.any_rule_applies(checkin, checkout, item):
return 0
avail = min(rule_items.mapped("plan_avail"))
return avail
def get_count_real_free_rooms(
self,
checkin,
checkout,
room_type_id,
pms_property_id,
current_lines=False,
):
Avail = self.env["pms.availability"]
count_free_rooms = len(
self.env["pms.room.type"]
.browse(room_type_id)
.room_ids.filtered(lambda r: r.pms_property_id.id == pms_property_id)
)
if isinstance(checkin, str):
checkin = datetime.datetime.strptime(
checkin, DEFAULT_SERVER_DATE_FORMAT
).date()
if isinstance(checkout, str):
checkout = datetime.datetime.strptime(
checkout, DEFAULT_SERVER_DATE_FORMAT
).date()
for avail in Avail.search(
[
("date", ">=", checkin),
("date", "<=", checkout - datetime.timedelta(1)),
("room_type_id", "=", room_type_id),
("pms_property_id", "=", pms_property_id),
]
):
if avail.real_avail < count_free_rooms:
count_free_rooms = avail.real_avail
return count_free_rooms
@api.model
def splitted_availability(
self,
checkin,
checkout,
room_type_id=False,
current_lines=False,
pricelist=False,
pms_property_id=False,
):
if isinstance(checkin, str):
checkin = datetime.datetime.strptime(
checkin, DEFAULT_SERVER_DATE_FORMAT
).date()
if isinstance(checkout, str):
checkout = datetime.datetime.strptime(
checkout, DEFAULT_SERVER_DATE_FORMAT
).date()
for date_iterator in [
checkin + datetime.timedelta(days=x)
for x in range(0, (checkout - checkin).days)
]:
rooms_avail = self.rooms_available(
checkin=date_iterator,
checkout=date_iterator + datetime.timedelta(1),
room_type_id=room_type_id,
current_lines=current_lines,
pricelist_id=pricelist.id,
pms_property_id=pms_property_id,
)
if len(rooms_avail) < 1:
return False
return True
@api.model
def update_quota(self, pricelist_id, room_type_id, date, line):
if pricelist_id and room_type_id and date:

View File

@@ -2,12 +2,14 @@
# Copyright 2019 Dario Lodeiros
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import datetime
import time
import pytz
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
from odoo.addons.base.models.res_partner import _tz_get
@@ -97,6 +99,243 @@ class PmsProperty(models.Model):
"charge a day's stay according to current rate that day",
help="Notice under the signature on the traveler's ticket.",
)
free_room_ids = fields.One2many(
string="Rooms available",
help="allows you to send different parameters in the context "
"(checkin(required), checkout(required), room_type_id, location_id, capacity, "
"amenity_ids and / or pricelist_id) and return rooms available",
comodel_name="pms.room",
compute="_compute_free_room_ids",
)
availability = fields.Integer(
string="Number of rooms available",
help="allows you to send different parameters in the context "
"(checkin(required), checkout(required), room_type_id, location_id, capacity,"
"amenity_ids and / or pricelist_id) check the availability for the hotel",
compute="_compute_availability",
)
@api.depends_context(
"checkin",
"checkout",
"room_type_id",
"location_id",
"capacity",
"amenity_ids",
"pricelist_id",
"current_lines",
)
def _compute_free_room_ids(self):
self.free_room_ids = False
checkin = self._context["checkin"]
checkout = self._context["checkout"]
if isinstance(checkin, str):
checkin = datetime.datetime.strptime(
checkin, DEFAULT_SERVER_DATE_FORMAT
).date()
if isinstance(checkout, str):
checkout = datetime.datetime.strptime(
checkout, DEFAULT_SERVER_DATE_FORMAT
).date()
current_lines = self.env.context.get("current_lines", False)
if current_lines and not isinstance(current_lines, list):
current_lines = [current_lines]
pricelist_id = self.env.context.get("pricelist_id", False)
room_type_id = self.env.context.get("room_type_id", False)
for pms_property in self:
free_rooms = pms_property.get_real_free_rooms(
checkin, checkout, current_lines
)
if pricelist_id:
# TODO: only closed_departure take account checkout date!
domain_rules = [
("date", ">=", checkin),
("date", "<=", checkout),
("pms_property_id", "=", pms_property.id),
]
if room_type_id:
domain_rules.append(("room_type_id", "=", room_type_id))
pricelist = self.env["product.pricelist"].browse(pricelist_id)
if pricelist.availability_plan_id:
domain_rules.append(
("availability_plan_id", "=", pricelist.availability_plan_id.id)
)
rule_items = self.env["pms.availability.plan.rule"].search(
domain_rules
)
if len(rule_items) > 0:
room_types_to_remove = []
for item in rule_items:
if pricelist.availability_plan_id.any_rule_applies(
checkin, checkout, item
):
room_types_to_remove.append(item.room_type_id.id)
free_rooms = free_rooms.filtered(
lambda x: x.room_type_id.id not in room_types_to_remove
)
if len(free_rooms) > 0:
pms_property.free_room_ids = free_rooms.ids
else:
pms_property.free_room_ids = False
def get_real_free_rooms(self, checkin, checkout, current_lines=False):
self.ensure_one()
Avail = self.env["pms.availability"]
tarjet_rooms = self.env["pms.room"].search([("pms_property_id", "=", self.id)])
room_type_id = self.env.context.get("room_type_id", False)
if room_type_id:
tarjet_rooms = tarjet_rooms.filtered(
lambda r: r.room_type_id.id == room_type_id
)
capacity = self.env.context.get("capacity", False)
if capacity:
tarjet_rooms = tarjet_rooms.filtered(lambda r: r.capacity >= capacity)
location_id = self.env.context.get("location_id", False)
if location_id:
tarjet_rooms = tarjet_rooms.filtered(
lambda r: r.location_id.id == location_id
)
amenity_ids = self.env.context.get("amenity_ids", False)
if amenity_ids:
if amenity_ids and not isinstance(amenity_ids, list):
amenity_ids = [amenity_ids]
tarjet_rooms = tarjet_rooms.filtered(
lambda r: len(set(amenity_ids) - set(r.room_amenity_ids.ids)) == 0
)
domain_avail = [
("date", ">=", checkin),
("date", "<=", checkout - datetime.timedelta(1)),
("pms_property_id", "=", self.id),
]
if not current_lines:
current_lines = []
rooms_not_avail = (
Avail.search(domain_avail)
.reservation_line_ids.filtered(
lambda l: l.occupies_availability and l.id and l.id not in current_lines
)
.room_id.ids
)
domain_rooms = [("id", "in", tarjet_rooms.ids)]
if rooms_not_avail:
domain_rooms.append(
("id", "not in", rooms_not_avail),
)
return self.env["pms.room"].search(domain_rooms)
@api.depends_context(
"checkin",
"checkout",
"room_type_id",
"location_id",
"capacity",
"amenity_ids",
"pricelist_id",
"current_lines",
)
def _compute_availability(self):
self.availability = 0
for pms_property in self:
checkin = self._context["checkin"]
checkout = self._context["checkout"]
room_type_id = self.env.context.get("room_type_id", False)
pricelist_id = self.env.context.get("pricelist_id", False)
current_lines = self.env.context.get("current_lines", False)
pms_property = pms_property.with_context(
checkin=checkin,
checkout=checkout,
room_type_id=room_type_id,
current_lines=current_lines,
pricelist_id=pricelist_id,
)
count_free_rooms = len(pms_property.free_room_ids)
if current_lines and not isinstance(current_lines, list):
current_lines = [current_lines]
domain_rules = [
("date", ">=", checkin),
("date", "<=", checkout),
("pms_property_id", "=", pms_property.id),
]
if room_type_id:
domain_rules.append(("room_type_id", "=", room_type_id))
pricelist = False
if pricelist_id:
pricelist = self.env["product.pricelist"].browse(pricelist_id)
if pricelist and pricelist.availability_plan_id:
domain_rules.append(
("availability_plan_id", "=", pricelist.availability_plan_id.id)
)
rule_groups = self.env["pms.availability.plan.rule"].read_group(
domain_rules,
["plan_avail:sum"],
["date:day"],
lazy=False,
)
if len(rule_groups) > 0:
# If in the group per day, some room type has the sale blocked,
# we must subtract from that day the availability of that room type
for group in rule_groups:
items = self.env["pms.availability.plan.rule"].search(
group["__domain"]
)
for item in items:
if pricelist.availability_plan_id.any_rule_applies(
checkin, checkout, item
):
group["plan_avail"] -= item.plan_avail
count_free_rooms = min(i["plan_avail"] for i in rule_groups)
pms_property.availability = count_free_rooms
@api.model
def splitted_availability(
self,
checkin,
checkout,
pms_property_id,
room_type_id=False,
current_lines=False,
pricelist=False,
):
if isinstance(checkin, str):
checkin = datetime.datetime.strptime(
checkin, DEFAULT_SERVER_DATE_FORMAT
).date()
if isinstance(checkout, str):
checkout = datetime.datetime.strptime(
checkout, DEFAULT_SERVER_DATE_FORMAT
).date()
for date_iterator in [
checkin + datetime.timedelta(days=x)
for x in range(0, (checkout - checkin).days)
]:
pms_property = self.env["pms.property"].browse(pms_property_id)
pms_property = pms_property.with_context(
checkin=date_iterator,
checkout=date_iterator + datetime.timedelta(1),
room_type_id=room_type_id,
current_lines=current_lines,
pricelist_id=pricelist.id,
)
if len(pms_property.free_room_ids) < 1:
return False
return True
@api.constrains("default_arrival_hour")
def _check_arrival_hour(self):

View File

@@ -736,15 +736,16 @@ class PmsReservation(models.Model):
[("active", "=", True)]
)
return
rooms_available = self.env["pms.availability.plan"].rooms_available(
pms_property = reservation.pms_property_id
pms_property = pms_property.with_context(
checkin=reservation.checkin,
checkout=reservation.checkout,
room_type_id=False, # Allows to choose any available room
current_lines=reservation.reservation_line_ids.ids,
pricelist_id=reservation.pricelist_id.id,
pms_property_id=reservation.pms_property_id.id,
)
reservation.allowed_room_ids = rooms_available
reservation.allowed_room_ids = pms_property.free_room_ids
else:
reservation.allowed_room_ids = False
@@ -1502,13 +1503,15 @@ class PmsReservation(models.Model):
return self.folio_id.action_pay()
def open_reservation_wizard(self):
rooms_available = self.env["pms.availability.plan"].rooms_available(
pms_property = self.pms_property_id
pms_property = pms_property.with_context(
checkin=self.checkin,
checkout=self.checkout,
current_lines=self.reservation_line_ids.ids,
pricelist_id=self.pricelist_id.id,
pms_property_id=self.pms_property_id.id,
)
rooms_available = pms_property.free_room_ids
# REVIEW: check capacity room
return {
"view_type": "form",
@@ -1544,21 +1547,6 @@ class PmsReservation(models.Model):
result.append((res.id, name))
return result
# REVIEW: Is it necessary?
def copy_data(self, default=None):
rooms_available = self.env["pms.availability.plan"].rooms_available(
self.checkin,
self.checkout,
room_type_id=self.room_type_id.id,
pricelist_id=self.pricelist_id.id,
pms_property_id=self.pms_property_id.id,
)
if self.preferred_room_id.id in rooms_available.ids:
default["preferred_room_id"] = self.preferred_room_id.id
if self.room_type_id.id in rooms_available.mapped("room_type_id.id"):
default["room_type_id"] = self.room_type_id.id
return super(PmsReservation, self).copy_data(default)
@api.model
def create(self, vals):
if vals.get("folio_id"):

View File

@@ -175,7 +175,8 @@ class PmsReservationLine(models.Model):
free_room_select = True if reservation.preferred_room_id else False
# we get the rooms available for the entire stay
rooms_available = self.env["pms.availability.plan"].rooms_available(
pms_property = line.pms_property_id
pms_property = pms_property.with_context(
checkin=reservation.checkin,
checkout=reservation.checkout,
room_type_id=reservation.room_type_id.id
@@ -183,8 +184,9 @@ class PmsReservationLine(models.Model):
else False,
current_lines=reservation.reservation_line_ids.ids,
pricelist_id=reservation.pricelist_id.id,
pms_property_id=line.pms_property_id.id,
)
rooms_available = pms_property.free_room_ids
# Check if the room assigment is manual or automatic to set the
# to_assign value on reservation
manual_assigned = False
@@ -228,7 +230,7 @@ class PmsReservationLine(models.Model):
else:
line.room_id = rooms_available[0]
# check that the reservation cannot be allocated even by dividing it
elif not self.env["pms.availability.plan"].splitted_availability(
elif not self.env["pms.property"].splitted_availability(
checkin=reservation.checkin,
checkout=reservation.checkout,
room_type_id=reservation.room_type_id.id,

View File

@@ -70,6 +70,16 @@ class PmsRoom(models.Model):
required=True,
default="0",
)
room_amenity_ids = fields.Many2many(
string="Room Amenities",
help="List of amenities included in room",
comodel_name="pms.amenity",
relation="pms_room_amenity_rel",
column1="room_id",
column2="amenity_id",
check_pms_properties=True,
)
description_sale = fields.Text(
string="Sale Description",
help="A description of the Product that you want to communicate to "

View File

@@ -98,13 +98,16 @@ class PmsRoomType(models.Model):
for room_type in self:
name = room_type.name
if self._context.get("checkin") and self._context.get("checkout"):
avail = self.env["pms.availability.plan"].get_count_rooms_available(
pms_property = self.env["pms.property"].browse(
self._context.get("pms_property_id")
)
pms_property = pms_property.with_context(
checkin=self._context.get("checkin"),
checkout=self._context.get("checkout"),
room_type_id=room_type.id,
pms_property_id=self._context.get("pms_property_id") or False,
pricelist_id=self._context.get("pricelist_id") or False,
)
avail = pms_property.availability
name += " (%s)" % avail
result.append((room_type.id, name))
return result

View File

@@ -130,7 +130,7 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
---------------------
The checkin and checkout dates on which the availability will be checked are saved
in a variable and in another all the rooms of the property are also saved. Then the
rooms_available() method is launched which should return the number of available rooms
free_room_ids compute field is called which should return the number of available rooms
of the property and they are saved in another variable with which it is verified that
all the rooms have been returned because there are no availability rules for that plan.
"""
@@ -142,10 +142,12 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
[("pms_property_id", "=", self.pms_property3.id)]
)
# ACT
result = self.env["pms.availability.plan"].rooms_available(
pms_property = self.pms_property3.with_context(
checkin=checkin,
checkout=checkout,
)
result = pms_property.free_room_ids
# ASSERT
obtained = all(elem.id in result.ids for elem in test_rooms_double_rooms)
self.assertTrue(
@@ -162,7 +164,7 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
-----------------
The checkin and checkout dates on which the availability will be checked are saved
in a variable and in another all the rooms of the property are also saved. Then create
a reservation for this property and the rooms_available() method is launched with the
a reservation for this property and the free_room_ids compute field is called with the
parameters checkin, checkout and the reservation lines of the reservation as a curent
lines, this method should return the number of available rooms of the property. Then the
result is saved in another variable with which it is verified that all the rooms have
@@ -185,11 +187,13 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
)
# ACT
result = self.env["pms.availability.plan"].rooms_available(
pms_property = self.pms_property3.with_context(
checkin=checkin,
checkout=checkout,
current_lines=test_reservation.reservation_line_ids.ids,
)
result = pms_property.free_room_ids
# ASSERT
obtained = all(elem.id in result.ids for elem in test_rooms_double_rooms)
self.assertTrue(
@@ -202,8 +206,8 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
"""
Check the availability of a room type for a property.
----------------
Double rooms of a property are saved in a variable. The rooms_available() method
is launched giving as parameters checkin, checkout and the type of room (in this
Double rooms of a property are saved in a variable. The free_room_ids compute field
is called giving as parameters checkin, checkout and the type of room (in this
case double). Then with the all () function we check that all rooms of this type
were returned.
"""
@@ -216,11 +220,12 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
]
)
# ACT
result = self.env["pms.availability.plan"].rooms_available(
pms_property = self.pms_property3.with_context(
checkin=fields.date.today(),
checkout=(fields.datetime.today() + datetime.timedelta(days=4)).date(),
room_type_id=self.test_room_type_double.id,
)
result = pms_property.free_room_ids
# ASSERT
obtained = all(elem.id in result.ids for elem in test_rooms_double_rooms)
@@ -237,7 +242,7 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
--------------------
Create an availability rule for double rooms with the field closed = true
and the date from today until tomorrow. Then the availability is saved in a
variable through the rooms_available() method, passing it the pricelist that
variable through the free_room_ids computed field, passing it the pricelist that
it contains the availability plan where the rule is included, and the checkin
and checkout dates are between the date of the rule. Then it is verified that
the double rooms are not available.
@@ -255,12 +260,14 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
}
)
# ACT
result = self.env["pms.availability.plan"].rooms_available(
pms_property = self.pms_property3.with_context(
checkin=fields.date.today(),
checkout=(fields.datetime.today() + datetime.timedelta(days=4)).date(),
# room_type_id=False, # <- (2/2)
pricelist_id=self.pricelist2.id,
)
result = pms_property.free_room_ids
# ASSERT
self.assertNotIn(
self.test_room_type_double,
@@ -283,7 +290,7 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
6. max_stay_arrival = 3
7. quota = 0
8. max_avail = 0
For each test case, it is verified through the rooms_available() method,
For each test case, it is verified through the free_room_ids compute field,
that double rooms are not available since the rules are applied to this
room type.
"""
@@ -409,12 +416,13 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
# ACT
self.test_room_type_availability_rule1.write(test_case)
result = self.env["pms.availability.plan"].rooms_available(
pms_property = self.pms_property3.with_context(
checkin=checkin,
checkout=checkout,
room_type_id=self.test_room_type_double.id,
pricelist_id=self.pricelist2.id,
)
result = pms_property.free_room_ids
# ASSERT
self.assertNotIn(
@@ -639,15 +647,17 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
for p in properties:
with self.subTest(k=p):
# ACT
rooms_avail = self.env["pms.availability.plan"].rooms_available(
pms_property = self.env["pms.property"].browse(p["property"])
pms_property = pms_property.with_context(
checkin=fields.date.today(),
checkout=(
fields.datetime.today() + datetime.timedelta(days=2)
).date(),
room_type_id=self.test_room_type_special.id,
pricelist_id=self.pricelist2.id,
pms_property_id=p["property"],
)
rooms_avail = pms_property.free_room_ids
# ASSERT
self.assertEqual(
len(rooms_avail) > 0, p["value"], "Availability is not correct"

View File

@@ -703,7 +703,6 @@ class TestPmsWizardMassiveChanges(common.SavepointCase):
"pms_property_id": self.test_property.id,
}
)
# create folio wizard with partner id => pricelist & start-end dates
booking_engine = self.env["pms.booking.engine"].create(
{
@@ -715,7 +714,6 @@ class TestPmsWizardMassiveChanges(common.SavepointCase):
}
)
booking_engine.flush()
room_type_plan_avail = booking_engine.availability_results.filtered(
lambda r: r.room_type_id.id == self.test_room_type_double.id
).num_rooms_available

View File

@@ -177,15 +177,15 @@ class BookingEngine(models.TransientModel):
("pms_property_ids", "in", record.pms_property_id.id),
]
):
num_rooms_available = self.env[
"pms.availability.plan"
].get_count_rooms_available(
pms_property = record.pms_property_id
pms_property = pms_property.with_context(
checkin=record.start_date,
checkout=record.end_date,
room_type_id=room_type_iterator.id,
pricelist_id=record.pricelist_id.id,
pms_property_id=record.pms_property_id.id,
)
num_rooms_available = pms_property.availability
cmds.append(
(
0,
@@ -338,15 +338,14 @@ class AvailabilityWizard(models.TransientModel):
@api.depends("room_type_id", "checkin", "checkout")
def _compute_num_rooms_available(self):
for record in self:
record.num_rooms_available = self.env[
"pms.availability.plan"
].get_count_rooms_available(
record.checkin,
record.checkout,
pms_property = record.booking_engine_id.pms_property_id
pms_property = pms_property.with_context(
checkin=record.checkin,
checkout=record.checkout,
room_type_id=record.room_type_id.id,
pricelist_id=record.booking_engine_id.pricelist_id.id,
pms_property_id=record.booking_engine_id.pms_property_id.id,
)
record.num_rooms_available = pms_property.availability
@api.depends("num_rooms_available")
def _compute_num_rooms_selected(self):

View File

@@ -172,14 +172,16 @@ class ReservationSplitJoinSwapWizard(models.TransientModel):
record.allowed_rooms_target = False
record.room_target = False
if record.checkin and record.checkout:
rooms_available = self.env["pms.availability.plan"].rooms_available(
pms_property = record.reservation_id.pms_property_id
pms_property = pms_property.with_context(
checkin=record.checkin,
checkout=record.checkout,
room_type_id=False, # Allows to choose any available room
current_lines=record.reservation_id.reservation_line_ids.ids,
pricelist_id=record.reservation_id.pricelist_id.id,
pms_property_id=record.reservation_id.pms_property_id.id,
)
rooms_available = pms_property.free_room_ids
domain = [("capacity", ">=", record.reservation_id.adults)]
if record.room_source:
domain.append(("id", "!=", record.room_source.id))
@@ -214,7 +216,7 @@ class ReservationSplitJoinSwapWizard(models.TransientModel):
if not self.browse(room.id):
raise UserError(_("The room does not exist"))
rooms_available = self.env["pms.availability.plan"].rooms_available(
pms_property = reservation.pms_property_id.with_context(
checkin=date,
checkout=(
datetime.datetime(year=date.year, month=date.month, day=date.day)
@@ -222,8 +224,9 @@ class ReservationSplitJoinSwapWizard(models.TransientModel):
).date(),
current_lines=reservation.reservation_line_ids.ids,
pricelist_id=reservation.pricelist_id.id,
pms_property_id=reservation.pms_property_id.id,
)
rooms_available = pms_property.free_room_ids
if room not in rooms_available:
raise UserError(_("The room is not available"))
@@ -233,13 +236,15 @@ class ReservationSplitJoinSwapWizard(models.TransientModel):
@api.model
def reservation_join(self, reservation, room):
rooms_available = self.env["pms.availability.plan"].rooms_available(
pms_property = reservation.pms_property_id
pms_property = pms_property.with_context(
checkin=reservation.checkin,
checkout=reservation.checkout,
current_lines=reservation.reservation_line_ids.ids,
pricelist_id=reservation.pricelist_id.id,
pms_property_id=reservation.pms_property_id.id,
)
rooms_available = pms_property.free_room_ids
if room in rooms_available:
for line in (
self.env["pms.reservation"]
@@ -347,13 +352,14 @@ class ReservationLinesToSplit(models.TransientModel):
[("active", "=", True)]
)
return
rooms_available = self.env["pms.availability.plan"].rooms_available(
pms_property = reservation.pms_property_id
pms_property = pms_property.with_context(
checkin=line.date,
checkout=line.date + datetime.timedelta(days=1),
room_type_id=False, # Allows to choose any available room
pricelist_id=reservation.pricelist_id.id,
pms_property_id=reservation.pms_property_id.id,
)
rooms_available = pms_property.free_room_ids
rooms_available += line.room_id
line.allowed_room_ids = rooms_available
else: