Merge pull request #2006 from amitsharma322/gli-3351

Fixed: Optimize performance of Admin Orders and Book Now pages
This commit is contained in:
Rohit Jain
2026-11-05 16:34:28 +05:30
committed by GitHub
3 changed files with 91 additions and 21 deletions

View File

@@ -61,20 +61,20 @@ class AdminOrdersControllerCore extends AdminController
CONCAT(c.`firstname`, \' \', c.`lastname`) AS `customer`,
osl.`name` AS `osname`, os.`color`,
cu.iso_code AS currency,
IF((SELECT so.id_order FROM `'._DB_PREFIX_.'orders` so WHERE so.id_customer = a.id_customer AND so.id_order < a.id_order LIMIT 1) > 0, 0, 1) as new,
IF(fo.`first_order` IS NULL OR fo.`first_order` = a.`id_order`, 1, 0) as new,
IF(a.valid, 1, 0) badge_success,
hbil.`hotel_name`,
(SELECT COUNT(hbd.`id`) FROM `'._DB_PREFIX_.'htl_booking_detail` hbd WHERE hbd.`id_order` = a.`id_order`) as num_rooms,
(SELECT SUM(hbd.`adults`) + SUM(hbd.`children`) FROM `'._DB_PREFIX_.'htl_booking_detail` hbd WHERE hbd.`id_order` = a.`id_order`) as total_guests_count,
(SELECT CONCAT(
SUM(hbd.`adults`),
hba.`num_rooms` AS num_rooms,
hba.`total_guests_count` AS total_guests_count,
CONCAT(
hba.`adults`,
\' '.$this->l('Adult(s)').' \',
IF(SUM(hbd.`children`), CONCAT(SUM(hbd.`children`), \' '.$this->l('Children').'\'), \'\')
) FROM `'._DB_PREFIX_.'htl_booking_detail` hbd WHERE hbd.`id_order` = a.`id_order`) as total_guests,
(SELECT SUM(DATEDIFF(hbd.`date_to`, hbd.`date_from`)) FROM `'._DB_PREFIX_.'htl_booking_detail` hbd WHERE hbd.`id_order` = a.`id_order`) as los,
IF(hba.`children`, CONCAT(hba.`children`, \' '.$this->l('Children').'\'), \'\')
) AS total_guests,
hba.`los` AS los,
hbd.`id_room` AS id_room_information,
(SELECT GROUP_CONCAT(CONCAT(ps.period, \'~\', ps.cnt) ORDER BY ps.period SEPARATOR \'::\') FROM (SELECT CONCAT(hbd.`date_from`, \'|\', hbd.`date_to`) AS period, COUNT(*) AS cnt FROM `'._DB_PREFIX_.'htl_booking_detail` hbd WHERE hbd.`id_order` = a.`id_order` GROUP BY hbd.`date_from`, hbd.`date_to`) AS ps) AS stay_periods,
(SELECT COUNT(spod.`id_service_product_order_detail`) FROM `'._DB_PREFIX_.'service_product_order_detail` spod WHERE spod.`id_order` = a.`id_order` AND spod.`id_htl_booking_detail`=0) as num_products';
hsp.`stay_periods` AS stay_periods,
IFNULL(spn.`num_products`, 0) AS num_products';
$this->_select .= ',
(SELECT sl.`name` FROM `'._DB_PREFIX_.'source` s LEFT JOIN `'._DB_PREFIX_.'source_lang` sl ON (sl.`id_source` = s.`id_source` AND sl.`id_lang` = '.(int)$this->context->language->id.') WHERE s.`id_source` = a.`id_source`) AS `booking_source_name`,
@@ -89,8 +89,36 @@ class AdminOrdersControllerCore extends AdminController
LEFT JOIN `'._DB_PREFIX_.'service_product_order_detail` spod ON (spod.`id_order` = a.`id_order`)
LEFT JOIN `'._DB_PREFIX_.'htl_branch_info_lang` hbil ON (IF(hbd.`id_hotel`, (hbil.`id` = hbd.`id_hotel`), (hbil.`id` = spod.`id_hotel`)))
LEFT JOIN (
SELECT hbd2.`id`, IF(hbd2.`id` IN ('.OrderReturn::getRefundedBookingIdsSubquery().'), 1, 0) AS is_room_refunded
SELECT so.`id_customer`, MIN(so.`id_order`) AS first_order
FROM `'._DB_PREFIX_.'orders` so
GROUP BY so.`id_customer`
) fo ON (fo.`id_customer` = a.`id_customer`)
LEFT JOIN (
SELECT hbd3.`id_order`, COUNT(hbd3.`id`) AS num_rooms, SUM(hbd3.`adults`) AS adults, SUM(hbd3.`children`) AS children,
SUM(hbd3.`adults`) + SUM(hbd3.`children`) AS total_guests_count,
SUM(DATEDIFF(hbd3.`date_to`, hbd3.`date_from`)) AS los
FROM `'._DB_PREFIX_.'htl_booking_detail` hbd3
GROUP BY hbd3.`id_order`
) hba ON (hba.`id_order` = a.`id_order`)
LEFT JOIN (
SELECT sp.`id_order`, GROUP_CONCAT(CONCAT(sp.`period`, \'~\', sp.`cnt`) ORDER BY sp.`period` SEPARATOR \'::\') AS stay_periods
FROM (
SELECT hbd4.`id_order`, CONCAT(hbd4.`date_from`, \'|\', hbd4.`date_to`) AS period, COUNT(*) AS cnt
FROM `'._DB_PREFIX_.'htl_booking_detail` hbd4
GROUP BY hbd4.`id_order`, hbd4.`date_from`, hbd4.`date_to`
) sp
GROUP BY sp.`id_order`
) hsp ON (hsp.`id_order` = a.`id_order`)
LEFT JOIN (
SELECT spod2.`id_order`, COUNT(spod2.`id_service_product_order_detail`) AS num_products
FROM `'._DB_PREFIX_.'service_product_order_detail` spod2
WHERE spod2.`id_htl_booking_detail` = 0
GROUP BY spod2.`id_order`
) spn ON (spn.`id_order` = a.`id_order`)
LEFT JOIN (
SELECT hbd2.`id`, IF(rb.`id_htl_booking` IS NULL, 0, 1) AS is_room_refunded
FROM `'._DB_PREFIX_.'htl_booking_detail` hbd2
LEFT JOIN ('.OrderReturn::getRefundedBookingIdsSubquery().' GROUP BY ord.`id_htl_booking`) rb ON (rb.`id_htl_booking` = hbd2.`id`)
) rrb ON (rrb.`id` = hbd.`id`)';
$this->_orderBy = 'id_order';

View File

@@ -1919,8 +1919,14 @@ class HotelBookingDetail extends ObjectModel
return $bookingData;
}
public function getAvailableRoomsForReallocation($dateFrom, $dateTo, $idRoomType, $idHotel, $roomTypesToUpgrade = 0)
public function getAvailableRoomsForReallocation($dateFrom, $dateTo, $idRoomType, $idHotel, $roomTypesToUpgrade = 0, $cache = false)
{
// When $cache is true, reuse the result for bookings sharing the same dates and hotel
$cacheKey = 'HotelBookingDetail::getAvailableRoomsForReallocation_'.(int) $idHotel.'_'.(int) $idRoomType.'_'.(int) $roomTypesToUpgrade.'_'.$dateFrom.'_'.$dateTo;
if ($cache && Cache::isStored($cacheKey)) {
return Cache::retrieve($cacheKey);
}
$context = Context::getContext();
$bookingParams = array(
'date_from' => $dateFrom,
@@ -1938,6 +1944,10 @@ class HotelBookingDetail extends ObjectModel
$searchRoomsInfo = $this->getBookingData($bookingParams);
if (empty($searchRoomsInfo['rm_data']) || !is_array($searchRoomsInfo['rm_data'])) {
if ($cache) {
Cache::store($cacheKey, false);
}
return false;
}
@@ -1974,11 +1984,13 @@ class HotelBookingDetail extends ObjectModel
}
}
if ($roomTypesToUpgrade) {
return $availableRoomTypes ? $availableRoomTypes : false;
$result = $roomTypesToUpgrade ? $availableRoomTypes : $availableRooms;
$result = $result ? $result : false;
if ($cache) {
Cache::store($cacheKey, $result);
}
return $availableRooms ? $availableRooms : false;
return $result;
}
/**
@@ -1990,15 +2002,26 @@ class HotelBookingDetail extends ObjectModel
*
* @return [array|false] [Returs array of the available rooms for swapping if rooms found else returnss false]
*/
public function getAvailableRoomsForSwapping($date_from, $date_to, $id_room_type, $hotel_id, $id_room)
public function getAvailableRoomsForSwapping($date_from, $date_to, $id_room_type, $hotel_id, $id_room, $cache = false)
{
// When $cache is true, reuse the result for the same room, dates and hotel
$cacheKey = 'HotelBookingDetail::getAvailableRoomsForSwapping_'.(int) $hotel_id.'_'.(int) $id_room_type.'_'.(int) $id_room.'_'.$date_from.'_'.$date_to;
if ($cache && Cache::isStored($cacheKey)) {
return Cache::retrieve($cacheKey);
}
$sql = 'SELECT `id` as `id_hotel_booking`, `id_room`, `id_product`, `id_hotel`, `room_num`, `comment` AS `room_comment`
FROM `'._DB_PREFIX_.'htl_booking_detail`
WHERE `id_hotel` = '.(int)$hotel_id.' AND `id_product` = '.(int)$id_room_type.'
AND `date_from` = \''.pSQL($date_from).'\' AND `date_to` = \''.pSQL($date_to).'\'
AND `id_room`!='.(int)$id_room.' AND `id` NOT IN ('.OrderReturn::getRefundedBookingIdsSubquery().') AND `id_status` NOT IN ('.HotelBookingDetail::STATUS_CANCELLED.', '.HotelBookingDetail::STATUS_NO_SHOW.') AND `is_back_order` = 0';
return Db::getInstance()->executeS($sql);
$result = Db::getInstance()->executeS($sql);
if ($cache) {
Cache::store($cacheKey, $result);
}
return $result;
}
/**
@@ -2039,6 +2062,8 @@ class HotelBookingDetail extends ObjectModel
*/
public function reallocateBooking($idHotelBooking, $idRoom, $priceDiffTaxExcl = 0)
{
// Rooms availability changes with this, so remove the cached availability lists
Cache::clean('HotelBookingDetail::getAvailableRoomsFor*');
$result = true;
$reallocatedBookingId = 0;
// get the cart booking data for the given booking
@@ -2551,10 +2576,13 @@ class HotelBookingDetail extends ObjectModel
AND id_room = '.(int) $objOldHotelBooking->id_room.' AND `id_order` = '.(int) $objOldHotelBooking->id_order
);
$objCartBookingData = new HotelCartBookingData($idHotelCartBookingData);
$objCartBookingData->id_room = $idRoom;
// update only the existing row, else saving would insert an empty cart booking row
if (Validate::isLoadedObject($objCartBookingData)) {
$objCartBookingData->id_room = $idRoom;
$objCartBookingData->save();
}
// set backorder to 0 as available reallocate rooms will always be free
$objOldHotelBooking->is_back_order = 0;
$objCartBookingData->save();
// update in the hotel booking detail table
$objOldHotelBooking->id_room = $idRoom;
@@ -2633,6 +2661,8 @@ class HotelBookingDetail extends ObjectModel
public function swapBooking($idHotelBookingFrom, $idHotelBookingTo)
{
// Rooms availability changes with this, so remove the cached availability lists
Cache::clean('HotelBookingDetail::getAvailableRoomsFor*');
$result = true;
// get the cart booking data for the given booking
if (Validate::isLoadedObject($objHotelBookingFrom = new HotelBookingDetail($idHotelBookingFrom))

View File

@@ -971,6 +971,8 @@ public function ajaxProcessGetCalenderData()
if ($booking_data) {
$objHotelRoomType = new HotelRoomType();
$availRoomTypesToRealloc = array();
$availRoomsToSwap = array();
foreach ($booking_data['rm_data'] as $key_bk_data => $value_bk_data) {
$booking_data['rm_data'][$key_bk_data]['room_type_info'] = $objHotelRoomType->getRoomTypeInfoByIdProduct($value_bk_data['id_product']);
if (isset($value_bk_data['data']['booked']) && $value_bk_data['data']['booked']) {
@@ -997,8 +999,18 @@ public function ajaxProcessGetCalenderData()
$booking_data['rm_data'][$key_bk_data]['data']['booked'][$booked_k1]['detail'][$kDtl]['currency_sign'] = (new Currency($objOrder->id_currency))->sign;
}
$booking_data['rm_data'][$key_bk_data]['data']['booked'][$booked_k1]['detail'][$kDtl]['avail_room_types_to_realloc'] = $obj_booking_dtl->getAvailableRoomsForReallocation($booked_v1['detail'][$kDtl]['date_from'], $booked_v1['detail'][$kDtl]['date_to'], 0, $booked_v1['id_hotel'], 1);
$booking_data['rm_data'][$key_bk_data]['data']['booked'][$booked_k1]['detail'][$kDtl]['avail_rooms_to_swap'] = $obj_booking_dtl->getAvailableRoomsForSwapping($booked_v1['detail'][$kDtl]['date_from'], $booked_v1['detail'][$kDtl]['date_to'], $booked_v1['id_product'], $booked_v1['id_hotel'], $booked_v1['id_room']);
// rooms available for reallocation are same for the same dates and hotel, so get them only once
$reallocKey = $booked_v1['detail'][$kDtl]['date_from'].'_'.$booked_v1['detail'][$kDtl]['date_to'].'_0_'.$booked_v1['id_hotel'];
if (!isset($availRoomTypesToRealloc[$reallocKey])) {
$availRoomTypesToRealloc[$reallocKey] = $obj_booking_dtl->getAvailableRoomsForReallocation($booked_v1['detail'][$kDtl]['date_from'], $booked_v1['detail'][$kDtl]['date_to'], 0, $booked_v1['id_hotel'], 1, true);
}
$booking_data['rm_data'][$key_bk_data]['data']['booked'][$booked_k1]['detail'][$kDtl]['avail_room_types_to_realloc'] = !empty($availRoomTypesToRealloc[$reallocKey]) ? $availRoomTypesToRealloc[$reallocKey] : false;
// rooms available for swapping are same for the same room, dates and hotel, so get them only once
$swapKey = $booked_v1['detail'][$kDtl]['date_from'].'_'.$booked_v1['detail'][$kDtl]['date_to'].'_'.$booked_v1['id_product'].'_'.$booked_v1['id_hotel'].'_'.$booked_v1['id_room'];
if (!isset($availRoomsToSwap[$swapKey])) {
$availRoomsToSwap[$swapKey] = $obj_booking_dtl->getAvailableRoomsForSwapping($booked_v1['detail'][$kDtl]['date_from'], $booked_v1['detail'][$kDtl]['date_to'], $booked_v1['id_product'], $booked_v1['id_hotel'], $booked_v1['id_room'], true);
}
$booking_data['rm_data'][$key_bk_data]['data']['booked'][$booked_k1]['detail'][$kDtl]['avail_rooms_to_swap'] = !empty($availRoomsToSwap[$swapKey]) ? $availRoomsToSwap[$swapKey] : false;
}
}
}