mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[IMP]pms_api_rest: improvements planning performance
This commit is contained in:
@@ -80,15 +80,21 @@ class PmsAvailabilityPlanService(Component):
|
||||
def get_availability_plan_rules(
|
||||
self, availability_plan_id, availability_plan_rule_search_param
|
||||
):
|
||||
result = []
|
||||
date_from = datetime.strptime(
|
||||
availability_plan_rule_search_param.dateFrom, "%Y-%m-%d"
|
||||
).date()
|
||||
date_to = datetime.strptime(
|
||||
availability_plan_rule_search_param.dateTo, "%Y-%m-%d"
|
||||
).date()
|
||||
count_nights = (date_to - date_from).days + 1
|
||||
target_dates = [date_from + timedelta(days=x) for x in range(count_nights)]
|
||||
pms_property_id = availability_plan_rule_search_param.pmsPropertyId
|
||||
record_availability_plan_id = self.env["pms.availability.plan"].browse(
|
||||
availability_plan_id
|
||||
)
|
||||
if not record_availability_plan_id:
|
||||
raise MissingError
|
||||
PmsAvailabilityPlanRuleInfo = self.env.datamodels[
|
||||
"pms.availability.plan.rule.info"
|
||||
]
|
||||
|
||||
rooms = self.env["pms.room"].search(
|
||||
[
|
||||
(
|
||||
@@ -98,50 +104,78 @@ class PmsAvailabilityPlanService(Component):
|
||||
)
|
||||
]
|
||||
)
|
||||
date_from = datetime.strptime(
|
||||
availability_plan_rule_search_param.dateFrom, "%Y-%m-%d"
|
||||
).date()
|
||||
date_to = datetime.strptime(
|
||||
availability_plan_rule_search_param.dateTo, "%Y-%m-%d"
|
||||
).date()
|
||||
room_type_ids = rooms.mapped("room_type_id").ids
|
||||
selected_fields = [
|
||||
"id",
|
||||
"date",
|
||||
"room_type_id",
|
||||
"min_stay",
|
||||
"min_stay_arrival",
|
||||
"max_stay",
|
||||
"max_stay_arrival",
|
||||
"closed",
|
||||
"closed_departure",
|
||||
"closed_arrival",
|
||||
"quota",
|
||||
"max_avail",
|
||||
]
|
||||
sql_select = "SELECT %s" % ", ".join(selected_fields)
|
||||
self.env.cr.execute(
|
||||
f"""
|
||||
{sql_select}
|
||||
FROM pms_availability_plan_rule rule
|
||||
WHERE (pms_property_id = %s)
|
||||
AND (date in %s)
|
||||
AND (availability_plan_id = %s)
|
||||
AND (room_type_id in %s)
|
||||
""",
|
||||
(
|
||||
pms_property_id,
|
||||
tuple(target_dates),
|
||||
record_availability_plan_id.id,
|
||||
tuple(room_type_ids),
|
||||
),
|
||||
)
|
||||
result_sql = self.env.cr.fetchall()
|
||||
rules = []
|
||||
for res in result_sql:
|
||||
rules.append(
|
||||
{field: res[selected_fields.index(field)] for field in selected_fields}
|
||||
)
|
||||
|
||||
for date in (
|
||||
date_from + timedelta(d) for d in range((date_to - date_from).days + 1)
|
||||
):
|
||||
for room_type in self.env["pms.room.type"].search(
|
||||
[("id", "in", rooms.mapped("room_type_id").ids)]
|
||||
):
|
||||
rule = self.env["pms.availability.plan.rule"].search(
|
||||
[
|
||||
("date", "=", date),
|
||||
(
|
||||
"availability_plan_id",
|
||||
"=",
|
||||
record_availability_plan_id.id,
|
||||
),
|
||||
("room_type_id", "=", room_type.id),
|
||||
(
|
||||
"pms_property_id",
|
||||
"=",
|
||||
availability_plan_rule_search_param.pmsPropertyId,
|
||||
),
|
||||
]
|
||||
result = []
|
||||
PmsAvailabilityPlanRuleInfo = self.env.datamodels[
|
||||
"pms.availability.plan.rule.info"
|
||||
]
|
||||
|
||||
for date in target_dates:
|
||||
for room_type_id in room_type_ids:
|
||||
rule = next(
|
||||
(
|
||||
rule
|
||||
for rule in rules
|
||||
if rule["room_type_id"] == room_type_id and rule["date"] == date
|
||||
),
|
||||
False,
|
||||
)
|
||||
|
||||
if rule:
|
||||
availability_plan_rule_info = PmsAvailabilityPlanRuleInfo(
|
||||
roomTypeId=room_type.id,
|
||||
roomTypeId=rule["room_type_id"],
|
||||
date=datetime.combine(date, datetime.min.time()).isoformat(),
|
||||
availabilityRuleId=rule.id,
|
||||
minStay=rule.min_stay,
|
||||
minStayArrival=rule.min_stay_arrival,
|
||||
maxStay=rule.max_stay,
|
||||
maxStayArrival=rule.max_stay_arrival,
|
||||
closed=rule.closed,
|
||||
closedDeparture=rule.closed_departure,
|
||||
closedArrival=rule.closed_arrival,
|
||||
quota=rule.quota if rule.quota != -1 else 0,
|
||||
maxAvailability=rule.max_avail,
|
||||
availabilityPlanId=rule.availability_plan_id,
|
||||
availabilityRuleId=rule["id"],
|
||||
minStay=rule["min_stay"],
|
||||
minStayArrival=rule["min_stay_arrival"],
|
||||
maxStay=rule["max_stay"],
|
||||
maxStayArrival=rule["max_stay_arrival"],
|
||||
closed=rule["closed"],
|
||||
closedDeparture=rule["closed_departure"],
|
||||
closedArrival=rule["closed_arrival"],
|
||||
quota=rule["quota"] if rule["quota"] != -1 else 0,
|
||||
maxAvailability=rule["max_avail"]
|
||||
if rule["max_avail"] != -1
|
||||
else 0,
|
||||
availabilityPlanId=availability_plan_id,
|
||||
)
|
||||
result.append(availability_plan_rule_info)
|
||||
|
||||
|
||||
@@ -30,14 +30,33 @@ class PmsCalendarService(Component):
|
||||
count_nights = (date_to - date_from).days + 1
|
||||
target_dates = [date_from + timedelta(days=x) for x in range(count_nights)]
|
||||
pms_property_id = calendar_search_param.pmsPropertyId
|
||||
|
||||
selected_fields_mapper = {
|
||||
"id": "night.id",
|
||||
"state": "night.state",
|
||||
"date": "DATE(night.date)",
|
||||
"room_id": "night.room_id",
|
||||
"room_type_name": "pms_room_type.default_code",
|
||||
"to_assign": "reservation.to_assign",
|
||||
"splitted": "reservation.splitted",
|
||||
"partner_id": "reservation.partner_id",
|
||||
"partner_name": "reservation.partner_name",
|
||||
"folio_id": "folio.id",
|
||||
"reservation_id": "reservation.id",
|
||||
"reservation_name": "reservation.name",
|
||||
"reservation_type": "reservation.reservation_type",
|
||||
"checkin": "reservation.checkin",
|
||||
"checkout": "reservation.checkout",
|
||||
"price_total": "reservation.price_total",
|
||||
"folio_pending_amount": "folio.pending_amount",
|
||||
"adults": "reservation.adults",
|
||||
}
|
||||
selected_fields_sql = list(selected_fields_mapper.values())
|
||||
selected_fields = list(selected_fields_mapper.keys())
|
||||
sql_select = "SELECT %s" % ", ".join(selected_fields_sql)
|
||||
self.env.cr.execute(
|
||||
"""
|
||||
SELECT night.id as id, night.state, DATE(night.date), night.room_id,
|
||||
pms_room_type.default_code, reservation.to_assign, reservation.splitted,
|
||||
reservation.partner_id, reservation.partner_name, folio.id, reservation.id,
|
||||
reservation.name, reservation.reservation_type, reservation.checkin,
|
||||
reservation.checkout, reservation.price_total, folio.pending_amount,
|
||||
reservation.adults
|
||||
f"""
|
||||
{sql_select}
|
||||
FROM pms_reservation_line night
|
||||
LEFT JOIN pms_reservation reservation
|
||||
ON reservation.id = night.reservation_id
|
||||
@@ -54,30 +73,12 @@ class PmsCalendarService(Component):
|
||||
tuple(target_dates),
|
||||
),
|
||||
)
|
||||
SQL_FIELDS = [
|
||||
"id",
|
||||
"state",
|
||||
"date",
|
||||
"room_id",
|
||||
"room_type_name",
|
||||
"to_assign",
|
||||
"splitted",
|
||||
"partner_id",
|
||||
"partner_name",
|
||||
"folio_id",
|
||||
"reservation_id",
|
||||
"reservation_name",
|
||||
"reservation_type",
|
||||
"checkin",
|
||||
"checkout",
|
||||
"price_total",
|
||||
"folio_pending_amount",
|
||||
"adults",
|
||||
]
|
||||
result_sql = self.env.cr.fetchall()
|
||||
lines = []
|
||||
for res in result_sql:
|
||||
lines.append({field: res[SQL_FIELDS.index(field)] for field in SQL_FIELDS})
|
||||
lines.append(
|
||||
{field: res[selected_fields.index(field)] for field in selected_fields}
|
||||
)
|
||||
|
||||
PmsCalendarInfo = self.env.datamodels["pms.calendar.info"]
|
||||
result_lines = []
|
||||
@@ -290,59 +291,64 @@ class PmsCalendarService(Component):
|
||||
auth="jwt_api_pms",
|
||||
)
|
||||
def get_free_rooms(self, pms_calendar_search_param):
|
||||
|
||||
date_from = datetime.strptime(
|
||||
pms_calendar_search_param.dateFrom, "%Y-%m-%d"
|
||||
).date()
|
||||
date_to = datetime.strptime(pms_calendar_search_param.dateTo, "%Y-%m-%d").date()
|
||||
result = []
|
||||
count_nights = (date_to - date_from).days + 1
|
||||
target_dates = [date_from + timedelta(days=x) for x in range(count_nights)]
|
||||
pms_property_id = pms_calendar_search_param.pmsPropertyId
|
||||
|
||||
self.env.cr.execute(
|
||||
"""
|
||||
SELECT night.date AS date, room.room_type_id AS room_type, COUNT(night.id) AS count
|
||||
FROM pms_reservation_line night
|
||||
LEFT JOIN pms_room room
|
||||
ON night.room_id = room.id
|
||||
WHERE (night.pms_property_id = %s)
|
||||
AND (night.date in %s)
|
||||
AND (night.occupies_availability = True)
|
||||
GROUP BY night.date, room.room_type_id
|
||||
""",
|
||||
(
|
||||
pms_property_id,
|
||||
tuple(target_dates),
|
||||
),
|
||||
)
|
||||
result_sql = self.env.cr.fetchall()
|
||||
rooms = self.env["pms.room"].search([("pms_property_id", "=", pms_property_id)])
|
||||
room_types = rooms.mapped("room_type_id")
|
||||
total_rooms_by_room_type = [
|
||||
{
|
||||
"room_type_id": room_type.id,
|
||||
"rooms_total": len(
|
||||
self.env["pms.room"].search([("room_type_id", "=", room_type.id)])
|
||||
),
|
||||
}
|
||||
for room_type in room_types
|
||||
]
|
||||
PmsCalendarFreeDailyRoomsByType = self.env.datamodels[
|
||||
"pms.calendar.free.daily.rooms.by.type"
|
||||
]
|
||||
for date in (
|
||||
date_from + timedelta(d) for d in range((date_to - date_from).days + 1)
|
||||
):
|
||||
rooms = self.env["pms.room"].search(
|
||||
[("pms_property_id", "=", pms_calendar_search_param.pmsPropertyId)]
|
||||
)
|
||||
for room_type_iterator in self.env["pms.room.type"].search(
|
||||
[("id", "in", rooms.mapped("room_type_id").ids)]
|
||||
):
|
||||
reservation_lines_room_type = self.env["pms.reservation.line"].search(
|
||||
[
|
||||
("date", "=", date),
|
||||
("occupies_availability", "=", True),
|
||||
("room_id.room_type_id", "=", room_type_iterator.id),
|
||||
(
|
||||
"pms_property_id",
|
||||
"=",
|
||||
pms_calendar_search_param.pmsPropertyId,
|
||||
),
|
||||
]
|
||||
result = []
|
||||
for day in target_dates:
|
||||
for total_room_type in total_rooms_by_room_type:
|
||||
count_occupied_night_by_room_type = next(
|
||||
(
|
||||
item[2]
|
||||
for item in result_sql
|
||||
if item[0] == day and item[1] == total_room_type["room_type_id"]
|
||||
),
|
||||
0,
|
||||
)
|
||||
num_rooms_room_type = self.env["pms.room"].search_count(
|
||||
[
|
||||
(
|
||||
"pms_property_id",
|
||||
"=",
|
||||
pms_calendar_search_param.pmsPropertyId,
|
||||
),
|
||||
("room_type_id", "=", room_type_iterator.id),
|
||||
]
|
||||
)
|
||||
if not reservation_lines_room_type:
|
||||
free_rooms_room_type = num_rooms_room_type
|
||||
else:
|
||||
free_rooms_room_type = num_rooms_room_type - len(
|
||||
reservation_lines_room_type
|
||||
)
|
||||
result.append(
|
||||
PmsCalendarFreeDailyRoomsByType(
|
||||
date=str(
|
||||
datetime.combine(date, datetime.min.time()).isoformat()
|
||||
datetime.combine(day, datetime.min.time()).isoformat()
|
||||
),
|
||||
roomTypeId=room_type_iterator.id,
|
||||
freeRooms=free_rooms_room_type,
|
||||
roomTypeId=total_room_type["room_type_id"],
|
||||
freeRooms=total_room_type["rooms_total"]
|
||||
- count_occupied_night_by_room_type,
|
||||
)
|
||||
)
|
||||
return result
|
||||
@@ -361,26 +367,37 @@ class PmsCalendarService(Component):
|
||||
auth="jwt_api_pms",
|
||||
)
|
||||
def get_alerts_per_day(self, pms_calendar_search_param):
|
||||
PmsCalendarAlertsPerDay = self.env.datamodels["pms.calendar.alerts.per.day"]
|
||||
date_from = datetime.strptime(
|
||||
pms_calendar_search_param.dateFrom, "%Y-%m-%d"
|
||||
).date()
|
||||
date_to = datetime.strptime(pms_calendar_search_param.dateTo, "%Y-%m-%d").date()
|
||||
count_nights = (date_to - date_from).days + 1
|
||||
target_dates = [date_from + timedelta(days=x) for x in range(count_nights)]
|
||||
pms_property_id = pms_calendar_search_param.pmsPropertyId
|
||||
|
||||
self.env.cr.execute(
|
||||
"""
|
||||
SELECT night.date AS date, COUNT(night.id) AS count
|
||||
FROM pms_reservation_line night
|
||||
WHERE (night.pms_property_id = %s)
|
||||
AND (night.date in %s)
|
||||
AND (night.overbooking = True)
|
||||
GROUP BY night.date
|
||||
""",
|
||||
(
|
||||
pms_property_id,
|
||||
tuple(target_dates),
|
||||
),
|
||||
)
|
||||
result_sql = self.env.cr.fetchall()
|
||||
PmsCalendarAlertsPerDay = self.env.datamodels["pms.calendar.alerts.per.day"]
|
||||
result = []
|
||||
for day in (
|
||||
date_from + timedelta(d) for d in range((date_to - date_from).days + 1)
|
||||
):
|
||||
lines = self.env["pms.reservation.line"].search_count(
|
||||
[
|
||||
("date", "=", day),
|
||||
("pms_property_id", "=", pms_calendar_search_param.pmsPropertyId),
|
||||
("overbooking", "=", True),
|
||||
]
|
||||
)
|
||||
for day in target_dates:
|
||||
overbooking_lines = next((item for item in result_sql if item[0] == day), 0)
|
||||
result.append(
|
||||
PmsCalendarAlertsPerDay(
|
||||
date=str(datetime.combine(day, datetime.min.time()).isoformat()),
|
||||
overbooking=True if lines > 0 else False,
|
||||
overbooking=True if overbooking_lines > 0 else False,
|
||||
)
|
||||
)
|
||||
return result
|
||||
|
||||
@@ -89,15 +89,8 @@ class PmsPricelistService(Component):
|
||||
auth="jwt_api_pms",
|
||||
)
|
||||
def get_pricelists_items(self, pricelist_id, pricelist_item_search_param):
|
||||
result = []
|
||||
record_pricelist_id = self.env["product.pricelist"].search(
|
||||
[("id", "=", pricelist_id)]
|
||||
)
|
||||
if not record_pricelist_id:
|
||||
raise MissingError
|
||||
PmsPricelistItemInfo = self.env.datamodels["pms.pricelist.item.info"]
|
||||
rooms = self.env["pms.room"].search(
|
||||
[("pms_property_id", "=", pricelist_item_search_param.pmsPropertyId)]
|
||||
pms_property = self.env["pms.property"].browse(
|
||||
pricelist_item_search_param.pmsPropertyId
|
||||
)
|
||||
date_from = datetime.strptime(
|
||||
pricelist_item_search_param.dateFrom, "%Y-%m-%d"
|
||||
@@ -105,44 +98,39 @@ class PmsPricelistService(Component):
|
||||
date_to = datetime.strptime(
|
||||
pricelist_item_search_param.dateTo, "%Y-%m-%d"
|
||||
).date()
|
||||
|
||||
for date in (
|
||||
date_from + timedelta(d) for d in range((date_to - date_from).days + 1)
|
||||
):
|
||||
for room_type in self.env["pms.room.type"].search(
|
||||
[("id", "in", rooms.mapped("room_type_id").ids)]
|
||||
):
|
||||
item = self.env["product.pricelist.item"].search(
|
||||
[
|
||||
("pricelist_id", "=", pricelist_id),
|
||||
("applied_on", "=", "0_product_variant"),
|
||||
("product_id", "=", room_type.product_id.id),
|
||||
(
|
||||
"date_start_consumption",
|
||||
">=",
|
||||
date,
|
||||
),
|
||||
(
|
||||
"date_end_consumption",
|
||||
"<=",
|
||||
date,
|
||||
),
|
||||
]
|
||||
count_nights = (date_to - date_from).days + 1
|
||||
target_dates = [date_from + timedelta(days=x) for x in range(count_nights)]
|
||||
record_pricelist = self.env["product.pricelist"].search(
|
||||
[("id", "=", pricelist_id)]
|
||||
)
|
||||
if not record_pricelist:
|
||||
raise MissingError
|
||||
rooms = self.env["pms.room"].search(
|
||||
[("pms_property_id", "=", pricelist_item_search_param.pmsPropertyId)]
|
||||
)
|
||||
room_types = rooms.mapped("room_type_id")
|
||||
result = []
|
||||
PmsPricelistItemInfo = self.env.datamodels["pms.pricelist.item.info"]
|
||||
for date in target_dates:
|
||||
products = [(product, 1, False) for product in room_types.product_id]
|
||||
date_prices = record_pricelist.with_context(
|
||||
quantity=1,
|
||||
consumption_date=date,
|
||||
property=pms_property.id,
|
||||
)._compute_price_rule(products, datetime.today())
|
||||
for product_id, v in date_prices.items():
|
||||
room_type_id = (
|
||||
self.env["product.product"].browse(product_id).room_type_id.id
|
||||
)
|
||||
|
||||
if item:
|
||||
pricelist_info = PmsPricelistItemInfo(
|
||||
roomTypeId=room_type.id,
|
||||
date=str(
|
||||
datetime.combine(date, datetime.min.time()).isoformat()
|
||||
),
|
||||
)
|
||||
|
||||
pricelist_info.pricelistItemId = item[0].id
|
||||
pricelist_info.price = item[0].fixed_price
|
||||
|
||||
result.append(pricelist_info)
|
||||
|
||||
if not v[1]:
|
||||
continue
|
||||
pricelist_info = PmsPricelistItemInfo(
|
||||
roomTypeId=room_type_id,
|
||||
date=str(datetime.combine(date, datetime.min.time()).isoformat()),
|
||||
pricelistItemId=v[1],
|
||||
price=v[0],
|
||||
)
|
||||
result.append(pricelist_info)
|
||||
return result
|
||||
|
||||
@restapi.method(
|
||||
|
||||
Reference in New Issue
Block a user