Merge PR #36 into 14.0

Signed-off-by DarioLodeiros
This commit is contained in:
OCA-git-bot
2021-07-07 14:36:33 +00:00
10 changed files with 328 additions and 258 deletions

View File

@@ -1,9 +1,9 @@
# Copyright 2017 Alexandre Díaz # Copyright 2017 Alexandre Díaz
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import datetime import datetime
from odoo import _, api, fields, models from odoo import api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
@@ -58,6 +58,14 @@ class PmsAvailabilityPlan(models.Model):
@classmethod @classmethod
def any_rule_applies(cls, checkin, checkout, item): def any_rule_applies(cls, checkin, checkout, item):
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()
reservation_len = (checkout - checkin).days reservation_len = (checkout - checkin).days
return any( return any(
[ [
@@ -72,204 +80,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 @api.model
def update_quota(self, pricelist_id, room_type_id, date, line): def update_quota(self, pricelist_id, room_type_id, date, line):
if pricelist_id and room_type_id and date: if pricelist_id and room_type_id and date:

View File

@@ -2,12 +2,14 @@
# Copyright 2019 Dario Lodeiros # Copyright 2019 Dario Lodeiros
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import datetime
import time import time
import pytz import pytz
from odoo import _, api, fields, models from odoo import _, api, fields, models
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
from odoo.addons.base.models.res_partner import _tz_get from odoo.addons.base.models.res_partner import _tz_get
@@ -97,6 +99,248 @@ class PmsProperty(models.Model):
"charge a day's stay according to current rate that day", "charge a day's stay according to current rate that day",
help="Notice under the signature on the traveler's ticket.", 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, ubication_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, ubication_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",
"ubication_id",
"capacity",
"amenity_ids",
"pricelist_id",
"current_lines",
)
def _compute_free_room_ids(self):
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"]
target_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:
target_rooms = target_rooms.filtered(
lambda r: r.room_type_id.id == room_type_id
)
capacity = self.env.context.get("capacity", False)
if capacity:
target_rooms = target_rooms.filtered(lambda r: r.capacity >= capacity)
ubication_id = self.env.context.get("ubication_id", False)
if ubication_id:
target_rooms = target_rooms.filtered(
lambda r: r.ubication_id.id == ubication_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]
target_rooms = target_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", target_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",
"ubication_id",
"capacity",
"amenity_ids",
"pricelist_id",
"current_lines",
)
def _compute_availability(self):
self.ensure_one()
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()
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 = self.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)
self.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") @api.constrains("default_arrival_hour")
def _check_arrival_hour(self): def _check_arrival_hour(self):

View File

@@ -736,15 +736,16 @@ class PmsReservation(models.Model):
[("active", "=", True)] [("active", "=", True)]
) )
return 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, checkin=reservation.checkin,
checkout=reservation.checkout, checkout=reservation.checkout,
room_type_id=False, # Allows to choose any available room room_type_id=False, # Allows to choose any available room
current_lines=reservation.reservation_line_ids.ids, current_lines=reservation.reservation_line_ids.ids,
pricelist_id=reservation.pricelist_id.id, 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: else:
reservation.allowed_room_ids = False reservation.allowed_room_ids = False
@@ -1502,13 +1503,15 @@ class PmsReservation(models.Model):
return self.folio_id.action_pay() return self.folio_id.action_pay()
def open_reservation_wizard(self): 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, checkin=self.checkin,
checkout=self.checkout, checkout=self.checkout,
current_lines=self.reservation_line_ids.ids, current_lines=self.reservation_line_ids.ids,
pricelist_id=self.pricelist_id.id, 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 # REVIEW: check capacity room
return { return {
"view_type": "form", "view_type": "form",
@@ -1544,21 +1547,6 @@ class PmsReservation(models.Model):
result.append((res.id, name)) result.append((res.id, name))
return result 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 @api.model
def create(self, vals): def create(self, vals):
if vals.get("folio_id"): 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 free_room_select = True if reservation.preferred_room_id else False
# we get the rooms available for the entire stay # 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, checkin=reservation.checkin,
checkout=reservation.checkout, checkout=reservation.checkout,
room_type_id=reservation.room_type_id.id room_type_id=reservation.room_type_id.id
@@ -183,8 +184,9 @@ class PmsReservationLine(models.Model):
else False, else False,
current_lines=reservation.reservation_line_ids.ids, current_lines=reservation.reservation_line_ids.ids,
pricelist_id=reservation.pricelist_id.id, 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 # Check if the room assigment is manual or automatic to set the
# to_assign value on reservation # to_assign value on reservation
manual_assigned = False manual_assigned = False
@@ -228,7 +230,7 @@ class PmsReservationLine(models.Model):
else: else:
line.room_id = rooms_available[0] line.room_id = rooms_available[0]
# check that the reservation cannot be allocated even by dividing it # 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, checkin=reservation.checkin,
checkout=reservation.checkout, checkout=reservation.checkout,
room_type_id=reservation.room_type_id.id, room_type_id=reservation.room_type_id.id,

View File

@@ -70,6 +70,16 @@ class PmsRoom(models.Model):
required=True, required=True,
default="0", 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( description_sale = fields.Text(
string="Sale Description", string="Sale Description",
help="A description of the Product that you want to communicate to " 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: for room_type in self:
name = room_type.name name = room_type.name
if self._context.get("checkin") and self._context.get("checkout"): 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"), checkin=self._context.get("checkin"),
checkout=self._context.get("checkout"), checkout=self._context.get("checkout"),
room_type_id=room_type.id, 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, pricelist_id=self._context.get("pricelist_id") or False,
) )
avail = pms_property.availability
name += " (%s)" % avail name += " (%s)" % avail
result.append((room_type.id, name)) result.append((room_type.id, name))
return result 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 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 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 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. 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)] [("pms_property_id", "=", self.pms_property3.id)]
) )
# ACT # ACT
result = self.env["pms.availability.plan"].rooms_available( pms_property = self.pms_property3.with_context(
checkin=checkin, checkin=checkin,
checkout=checkout, checkout=checkout,
) )
result = pms_property.free_room_ids
# ASSERT # ASSERT
obtained = all(elem.id in result.ids for elem in test_rooms_double_rooms) obtained = all(elem.id in result.ids for elem in test_rooms_double_rooms)
self.assertTrue( self.assertTrue(
@@ -162,7 +164,7 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
----------------- -----------------
The checkin and checkout dates on which the availability will be checked are saved 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 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 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 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 result is saved in another variable with which it is verified that all the rooms have
@@ -185,11 +187,13 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
) )
# ACT # ACT
result = self.env["pms.availability.plan"].rooms_available( pms_property = self.pms_property3.with_context(
checkin=checkin, checkin=checkin,
checkout=checkout, checkout=checkout,
current_lines=test_reservation.reservation_line_ids.ids, current_lines=test_reservation.reservation_line_ids.ids,
) )
result = pms_property.free_room_ids
# ASSERT # ASSERT
obtained = all(elem.id in result.ids for elem in test_rooms_double_rooms) obtained = all(elem.id in result.ids for elem in test_rooms_double_rooms)
self.assertTrue( self.assertTrue(
@@ -202,8 +206,8 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
""" """
Check the availability of a room type for a property. Check the availability of a room type for a property.
---------------- ----------------
Double rooms of a property are saved in a variable. The rooms_available() method Double rooms of a property are saved in a variable. The free_room_ids compute field
is launched giving as parameters checkin, checkout and the type of room (in this 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 case double). Then with the all () function we check that all rooms of this type
were returned. were returned.
""" """
@@ -216,11 +220,12 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
] ]
) )
# ACT # ACT
result = self.env["pms.availability.plan"].rooms_available( pms_property = self.pms_property3.with_context(
checkin=fields.date.today(), checkin=fields.date.today(),
checkout=(fields.datetime.today() + datetime.timedelta(days=4)).date(), checkout=(fields.datetime.today() + datetime.timedelta(days=4)).date(),
room_type_id=self.test_room_type_double.id, room_type_id=self.test_room_type_double.id,
) )
result = pms_property.free_room_ids
# ASSERT # ASSERT
obtained = all(elem.id in result.ids for elem in test_rooms_double_rooms) 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 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 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 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 and checkout dates are between the date of the rule. Then it is verified that
the double rooms are not available. the double rooms are not available.
@@ -255,12 +260,14 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
} }
) )
# ACT # ACT
result = self.env["pms.availability.plan"].rooms_available( pms_property = self.pms_property3.with_context(
checkin=fields.date.today(), checkin=fields.date.today(),
checkout=(fields.datetime.today() + datetime.timedelta(days=4)).date(), checkout=(fields.datetime.today() + datetime.timedelta(days=4)).date(),
# room_type_id=False, # <- (2/2) # room_type_id=False, # <- (2/2)
pricelist_id=self.pricelist2.id, pricelist_id=self.pricelist2.id,
) )
result = pms_property.free_room_ids
# ASSERT # ASSERT
self.assertNotIn( self.assertNotIn(
self.test_room_type_double, self.test_room_type_double,
@@ -283,7 +290,7 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
6. max_stay_arrival = 3 6. max_stay_arrival = 3
7. quota = 0 7. quota = 0
8. max_avail = 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 that double rooms are not available since the rules are applied to this
room type. room type.
""" """
@@ -409,12 +416,13 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
# ACT # ACT
self.test_room_type_availability_rule1.write(test_case) 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, checkin=checkin,
checkout=checkout, checkout=checkout,
room_type_id=self.test_room_type_double.id, room_type_id=self.test_room_type_double.id,
pricelist_id=self.pricelist2.id, pricelist_id=self.pricelist2.id,
) )
result = pms_property.free_room_ids
# ASSERT # ASSERT
self.assertNotIn( self.assertNotIn(
@@ -639,15 +647,17 @@ class TestPmsRoomTypeAvailabilityRules(TestPms):
for p in properties: for p in properties:
with self.subTest(k=p): with self.subTest(k=p):
# ACT # 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(), checkin=fields.date.today(),
checkout=( checkout=(
fields.datetime.today() + datetime.timedelta(days=2) fields.datetime.today() + datetime.timedelta(days=2)
).date(), ).date(),
room_type_id=self.test_room_type_special.id, room_type_id=self.test_room_type_special.id,
pricelist_id=self.pricelist2.id, pricelist_id=self.pricelist2.id,
pms_property_id=p["property"],
) )
rooms_avail = pms_property.free_room_ids
# ASSERT # ASSERT
self.assertEqual( self.assertEqual(
len(rooms_avail) > 0, p["value"], "Availability is not correct" 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, "pms_property_id": self.test_property.id,
} }
) )
# create folio wizard with partner id => pricelist & start-end dates # create folio wizard with partner id => pricelist & start-end dates
booking_engine = self.env["pms.booking.engine"].create( booking_engine = self.env["pms.booking.engine"].create(
{ {
@@ -715,7 +714,6 @@ class TestPmsWizardMassiveChanges(common.SavepointCase):
} }
) )
booking_engine.flush() booking_engine.flush()
room_type_plan_avail = booking_engine.availability_results.filtered( room_type_plan_avail = booking_engine.availability_results.filtered(
lambda r: r.room_type_id.id == self.test_room_type_double.id lambda r: r.room_type_id.id == self.test_room_type_double.id
).num_rooms_available ).num_rooms_available

View File

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

View File

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