[IMP]pms_api_rest: improvements planning performance

This commit is contained in:
Darío Lodeiros
2022-10-25 15:34:42 +02:00
parent da1ac07892
commit ea0745cc40
3 changed files with 209 additions and 170 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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(