mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[RFC] Availability and free rooms
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user