532 lines
24 KiB
PHP
532 lines
24 KiB
PHP
<?php
|
||
/**
|
||
* NOTICE OF LICENSE
|
||
*
|
||
* This source file is subject to the Open Software License version 3.0
|
||
* that is bundled with this package in the file LICENSE.md
|
||
* It is also available through the world-wide-web at this URL:
|
||
* https://opensource.org/license/osl-3-0-php
|
||
* If you did not receive a copy of the license and are unable to
|
||
* obtain it through the world-wide-web, please send an email
|
||
* to support@qloapps.com so we can send you a copy immediately.
|
||
*
|
||
* DISCLAIMER
|
||
*
|
||
* Do not edit or add to this file if you wish to upgrade this module to a newer
|
||
* versions in the future. If you wish to customize this module for your needs
|
||
* please refer to https://store.webkul.com/customisation-guidelines for more information.
|
||
*
|
||
* @author Webkul IN
|
||
* @copyright Since 2010 Webkul
|
||
* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0
|
||
*/
|
||
|
||
class HotelRoomInformation extends ObjectModel
|
||
{
|
||
public $id;
|
||
public $id_product;
|
||
public $id_hotel;
|
||
public $room_num;
|
||
public $id_status;
|
||
public $floor;
|
||
public $comment;
|
||
public $date_add;
|
||
public $date_upd;
|
||
|
||
const STATUS_ACTIVE = 1;
|
||
const STATUS_INACTIVE = 2;
|
||
|
||
const STATUS_SEARCH_LOS_UNSATISFIED = 4;
|
||
const STATUS_SEARCH_OCCUPANCY_UNSATISFIED = 5;
|
||
|
||
public static $definition = array(
|
||
'table' => 'htl_room_information',
|
||
'primary' => 'id',
|
||
'fields' => array(
|
||
'id_product' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
|
||
'id_hotel' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
|
||
'room_num' => array('type' => self::TYPE_STRING),
|
||
'id_status' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
|
||
'floor' => array('type' => self::TYPE_STRING),
|
||
'comment' => array('type' => self::TYPE_STRING),
|
||
'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
|
||
'date_upd' => array('type' => self::TYPE_DATE, 'validate' => 'isDate')
|
||
),
|
||
);
|
||
|
||
protected $webserviceParameters = array(
|
||
'objectMethods' => array(
|
||
'add' => 'addWs',
|
||
'update' => 'updateWs',
|
||
'delete' => 'deleteWs',
|
||
),
|
||
'objectsNodeName' => 'rooms',
|
||
'objectNodeName' => 'room',
|
||
'fields' => array(
|
||
'id_product' => array(
|
||
'xlink_resource' => array(
|
||
'resourceName' => 'products',
|
||
)
|
||
),
|
||
'id_hotel' => array(
|
||
'setter' => false,
|
||
'xlink_resource' => array(
|
||
'resourceName' => 'hotels',
|
||
)
|
||
),
|
||
),
|
||
);
|
||
|
||
public function update($null_values = false)
|
||
{
|
||
if ($idRoom = $this->id) {
|
||
// delete rooms from cart which are set inactive
|
||
if ($this->id_status == HotelRoomInformation::STATUS_INACTIVE) {
|
||
$objCartBookingData = new HotelCartBookingData();
|
||
if (!$objCartBookingData->deleteCartBookingData(0, 0, $idRoom)) {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
return parent::update();
|
||
}
|
||
|
||
//Overrided ObjectModel::delete()
|
||
public function delete()
|
||
{
|
||
if ($idRoom = $this->id) {
|
||
$objCartBookingData = new HotelCartBookingData();
|
||
if (!$this->deleteRoomDisableDates()
|
||
|| !$objCartBookingData->deleteCartBookingData(0, 0, $idRoom)
|
||
|| !parent::delete()
|
||
) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
public function deleteRoomDisableDates($idRoom = false)
|
||
{
|
||
if (!$idRoom) {
|
||
$idRoom = $this->id;
|
||
if (!$idRoom) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
$objRoomDisableDates = new HotelRoomDisableDates();
|
||
$objRoomDisableDates->deleteRoomDisableDates((int)$idRoom);
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* [deleteByProductId :: To delete all rooms information which belongs to a room type(which is a product in real) By product id]
|
||
* @param [int] $id_product [Id of the product form which all rooms information to be deleted]
|
||
* @return [Boolean] [Returns true if deleted successfully else returns false]
|
||
*/
|
||
public function deleteByProductId($idProduct)
|
||
{
|
||
if ($rooms = Db::getInstance()->executeS(
|
||
'SELECT * FROM `'._DB_PREFIX_.'htl_room_information` WHERE `id_product`='.(int) $idProduct
|
||
)) {
|
||
foreach ($rooms as $room) {
|
||
$objRoomInfo = new HotelRoomInformation($room['id']);
|
||
if (!$objRoomInfo->delete()) {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
public function getAllRoomStatus()
|
||
{
|
||
$status = array(
|
||
'STATUS_ACTIVE' => array(
|
||
'id' => HotelRoomInformation::STATUS_ACTIVE,
|
||
'status' => self::getRoomStatusTitle(HotelRoomInformation::STATUS_ACTIVE)
|
||
),
|
||
'STATUS_INACTIVE' => array(
|
||
'id' => HotelRoomInformation::STATUS_INACTIVE,
|
||
'status' => self::getRoomStatusTitle(HotelRoomInformation::STATUS_INACTIVE)
|
||
),
|
||
);
|
||
|
||
Hook::exec('actionAdminRoomStatusModifier', array('status' => &$status));
|
||
|
||
return $status;
|
||
}
|
||
|
||
public static function getRoomStatusTitle($idStatus)
|
||
{
|
||
$moduleInstance = Module::getInstanceByName('hotelreservationsystem');
|
||
$status = array(
|
||
HotelRoomInformation::STATUS_ACTIVE => $moduleInstance->l('Active', 'hotelreservationsystem'),
|
||
HotelRoomInformation::STATUS_INACTIVE => $moduleInstance->l('Inactive', 'hotelreservationsystem'),
|
||
HotelRoomInformation::STATUS_SEARCH_LOS_UNSATISFIED => $moduleInstance->l('Length of stay restriction not satisfied', 'hotelreservationsystem'),
|
||
HotelRoomInformation::STATUS_SEARCH_OCCUPANCY_UNSATISFIED => $moduleInstance->l('Occupancy exceeds room capacity', 'hotelreservationsystem'),
|
||
);
|
||
|
||
Hook::exec('actionAdminRoomStatusTitle', array('status' => &$status, 'id_status' => $idStatus));
|
||
|
||
return isset($status[$idStatus]) ? $status[$idStatus] : '';
|
||
}
|
||
|
||
/**
|
||
* [getHotelRoomInfoByProductId :: To get all rooms information belong to a room type(product) by product id]
|
||
* @param [int] $id_product [Id of the product]
|
||
* @return [array|false] [If data found returns array containing all rooms information belongs to a room type(product) which product id is passed else returns false]
|
||
*/
|
||
public function getHotelRoomInfoByProductId($id_product)
|
||
{
|
||
$result = Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'htl_room_information` WHERE `id_product`='.(int) $id_product);
|
||
if ($result) {
|
||
return $result;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* [getHotelRoomInfo :: To get all rooms information belong to a room type(product) and belongss to a hotel wwhich hotel id is passed]
|
||
* @param [type] $id_product [Id of the room type(product)]
|
||
* @param [type] $id_hotel [Id of the hotel]
|
||
* @param [int] $is_getNum [
|
||
* If $is_getNum is passed
|
||
* then returns number of rooms belong to a room type(product) and belongss to a hotel wwhich hotel id is passed
|
||
* else
|
||
* Returns array containing all rooms information belong to a room type(product) and belongss to a hotel wwhich hotel id is passed
|
||
* ]
|
||
* @return [array|int|boolean] [If $is_getNum is passed
|
||
* then returns number of rooms belong to a room type(product) and belongss to a hotel wwhich hotel id is passed
|
||
* else
|
||
* if data found
|
||
* Returns array containing all rooms information belong to a room type(product) and belongss to a hotel wwhich hotel id is passed
|
||
* else
|
||
* returns false; ]
|
||
*/
|
||
public function getHotelRoomInfo($id_product, $id_hotel, $is_getNum = 0)
|
||
{
|
||
$sql = "SELECT * FROM `"._DB_PREFIX_."htl_room_information` WHERE `id_product` = ".(int) $id_product." AND `id_hotel` = ".(int) $id_hotel;
|
||
|
||
$rm_info = Db::getInstance()->executeS($sql);
|
||
|
||
if ($is_getNum) {
|
||
$no_row = Db::getInstance()->NumRows();
|
||
return $no_row;
|
||
} else {
|
||
if ($rm_info) {
|
||
return $rm_info;
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* [getHotelRoomInfoById :: To get Information of a room by its id(primary key)]
|
||
* @param [int] $id [id of the room in the table(primary key)]
|
||
* @return [array|false] [If data found returns array containing information of the room which id is passed else returns false]
|
||
*/
|
||
public function getHotelRoomInfoById($id)
|
||
{
|
||
$sql = "SELECT `room_num` FROM `"._DB_PREFIX_."htl_room_information` WHERE `id` = ".(int) $id;
|
||
$rm_num = Db::getInstance()->getValue($sql);
|
||
|
||
if ($rm_num) {
|
||
return $rm_num;
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
public static function getHotelRoomsInfo($idHotel = null, $idProduct = null, $idLang = null)
|
||
{
|
||
if (!$idLang) {
|
||
$idLang = Context::getContext()->language->id;
|
||
}
|
||
|
||
$sql = 'SELECT hri.*, hri.`id_product`, hri.`id_hotel`, hrt.`adults`, hrt.`children`, hrt.`max_adults`,
|
||
hrt.`max_children`, hrt.`max_guests`, hrt.`min_los`, hrt.`max_los`, pl.`name` AS room_type_name, hbil.`hotel_name` AS hotel_name
|
||
FROM `'._DB_PREFIX_.'htl_room_information` hri
|
||
INNER JOIN `'._DB_PREFIX_.'htl_room_type` hrt ON (hrt.`id_product` = hri.`id_product`)
|
||
INNER JOIN `'._DB_PREFIX_.'htl_branch_info` hbi ON (hbi.`id` = hri.`id_hotel`)
|
||
INNER JOIN `'._DB_PREFIX_.'htl_branch_info_lang` hbil ON (hbil.`id` = hri.`id_hotel` AND hbil.`id_lang` = '.(int) $idLang.')
|
||
INNER JOIN `'._DB_PREFIX_.'product` p ON (p.`id_product` = hri.`id_product`)
|
||
INNER JOIN `'._DB_PREFIX_.'product_lang` pl ON (pl.`id_product` = p.`id_product` AND pl.`id_lang` = '.(int) $idLang.')
|
||
WHERE 1 '.($idHotel ? ' AND hri.`id_hotel` = '.(int) $idHotel : '').
|
||
($idProduct ? ' AND hri.`id_product` = '.(int) $idProduct : '').'
|
||
ORDER BY hri.`id_product`, hri.`id`';
|
||
|
||
return Db::getInstance()->executeS($sql);
|
||
}
|
||
|
||
/**
|
||
* Deprecated
|
||
* [deleteHotelRoomInfoById :: To delete room information which id is passed]
|
||
* @param [int] $id_room_info [Id of the room which information(row in the table) to be deleted]
|
||
* @return [Boolean] [Returns true if deleted successfully else returns false]
|
||
*/
|
||
public function deleteHotelRoomInfoById($id_room_info)
|
||
{
|
||
$result = Db::getInstance()->delete('htl_room_information', '`id` = '.(int)$id_room_info, 1);
|
||
|
||
return $result;
|
||
}
|
||
|
||
public function getRoomTypeAvailableRoomsForDateRange($id_hotel, $id_product, $date_from, $date_to)
|
||
{
|
||
return Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'htl_room_information` where `id_hotel`='.(int) $id_hotel.' AND `id_product`='.(int) $id_product.' AND `id` NOT IN (SELECT `id_room` from `'._DB_PREFIX_.'htl_booking_detail` where `date_from`< \''.pSQL($date_to).'\' AND `date_to`>\''.pSQL($date_from).'\' AND `id_product`='.(int) $id_product.' AND `id_hotel`='.(int) $id_hotel.')');
|
||
}
|
||
|
||
public function getRoomTypeDisabledRoomsForDateRange($id_hotel, $id_product, $date_from, $date_to)
|
||
{
|
||
return Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'htl_room_information` where `id_hotel`='.(int) $id_hotel.' AND `id_product`='.(int) $id_product.' AND `id_status`=3 AND `id` NOT IN (SELECT `id_room` from `'._DB_PREFIX_.'htl_booking_detail` where `date_from`< \''.pSQL($date_to).'\' AND `date_to`>\''.pSQL($date_from).'\' AND `id_product`='.(int) $id_product.' AND `id_hotel`='.(int) $id_hotel.')');
|
||
}
|
||
|
||
public function getRoomTypeBookedRoomsForDateRange($id_hotel, $id_product, $date_from, $date_to)
|
||
{
|
||
return Db::getInstance()->executeS('SELECT * FROM `'._DB_PREFIX_.'htl_booking_detail` where `date_from`< \''.pSQL($date_to).'\' AND `date_to`>\''.pSQL($date_from).'\' AND `id_product`='.(int) $id_product.' AND `id_hotel`='.(int) $id_hotel);
|
||
}
|
||
|
||
public function getFutureBookings($idRoom)
|
||
{
|
||
return Db::getInstance()->executeS('SELECT `id`, `id_order`, `date_from`, `date_to` FROM `'._DB_PREFIX_.'htl_booking_detail` where `date_to` > \''.pSQL(date('Y-m-d')).'\' AND `id` NOT IN ('.OrderReturn::getRefundedBookingIdsSubquery().') AND `id_room`='.(int) $idRoom);
|
||
}
|
||
|
||
// Webservice :: webservice add function
|
||
public function addWs($autodate = true, $null_values = false)
|
||
{
|
||
$objRoomType = new HotelRoomType();
|
||
if ($roomTypeInfo = $objRoomType->getRoomTypeInfoByIdProduct($this->id_product)) {
|
||
$this->id_hotel = $roomTypeInfo['id_hotel'];
|
||
return $this->add($autodate, $null_values);
|
||
} else {
|
||
WebserviceRequest::getInstance()->setError(400, 'Invalid id product', 134);
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
// Webservice :: webservice update function
|
||
public function updateWs($null_values = false)
|
||
{
|
||
$objRoomType = new HotelRoomType();
|
||
if ($roomTypeInfo = $objRoomType->getRoomTypeInfoByIdProduct($this->id_product)) {
|
||
$this->id_hotel = $roomTypeInfo['id_hotel'];
|
||
return $this->update($null_values);
|
||
} else {
|
||
WebserviceRequest::getInstance()->setError(400, 'Invalid id product', 134);
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
// Webservice :: webservice delete function
|
||
public function deleteWs()
|
||
{
|
||
return $this->delete();
|
||
}
|
||
|
||
// ── REPORT METHODS ────────────────────────────────────────────────────────
|
||
|
||
/**
|
||
* Room-type × date grid showing total / booked / available / OOO per row.
|
||
* Used by availability report tab.
|
||
*
|
||
* @param array $params date_from, date_to, id_hotel, id_product, id_lang
|
||
* @return array rows: date, id_product, room_type_name, total_rooms, rooms_booked, out_of_order, available, occupancy_pct
|
||
*/
|
||
public static function getAvailabilityReport(array $params)
|
||
{
|
||
$dateFrom = pSQL($params['date_from']);
|
||
$dateTo = pSQL(isset($params['date_to']) ? $params['date_to'] : $params['date_from']);
|
||
$idsHotel = isset($params['ids_hotel']) ? $params['ids_hotel'] : (isset($params['id_hotel']) ? $params['id_hotel'] : false);
|
||
$idProduct = isset($params['id_product']) ? (int) $params['id_product'] : 0;
|
||
$idLang = isset($params['id_lang']) ? (int) $params['id_lang'] : 0;
|
||
if (!$idLang) {
|
||
$idLang = Context::getContext()->language->id;
|
||
}
|
||
|
||
$roomTypes = Db::getInstance()->executeS(
|
||
'SELECT hri.`id_product`, pl.`name` AS room_type_name,
|
||
COUNT(hri.`id`) AS total_rooms,
|
||
SUM(CASE WHEN hri.`id_status` = '.(int) self::STATUS_INACTIVE.' THEN 1 ELSE 0 END) AS ooo_rooms
|
||
FROM `'._DB_PREFIX_.'htl_room_information` hri
|
||
INNER JOIN `'._DB_PREFIX_.'product` p ON (p.`id_product` = hri.`id_product` AND p.`active` = 1)
|
||
INNER JOIN `'._DB_PREFIX_.'product_lang` pl
|
||
ON (pl.`id_product` = hri.`id_product` AND pl.`id_lang` = '.(int) $idLang.')
|
||
WHERE 1'
|
||
.HotelBranchInformation::addHotelRestriction($idsHotel, 'hri')
|
||
.($idProduct ? ' AND hri.`id_product` = '.$idProduct : '').'
|
||
GROUP BY hri.`id_product`'
|
||
);
|
||
|
||
if (!$roomTypes) {
|
||
return array();
|
||
}
|
||
|
||
$dateToNext = pSQL(date('Y-m-d', strtotime('+1 day', strtotime($dateTo))));
|
||
$bookingsRaw = Db::getInstance()->executeS(
|
||
'SELECT hbd.`id_product`, hbd.`id_room`, hbd.`date_from`, hbd.`date_to`
|
||
FROM `'._DB_PREFIX_.'htl_booking_detail` hbd
|
||
INNER JOIN `'._DB_PREFIX_.'orders` o ON (o.`id_order` = hbd.`id_order` AND o.`valid` = 1)
|
||
WHERE hbd.`id` NOT IN ('.OrderReturn::getRefundedBookingIdsSubquery().')
|
||
AND hbd.`id_status` != '.HotelBookingDetail::STATUS_CANCELLED.'
|
||
AND hbd.`date_from` < "'.$dateToNext.'" AND hbd.`date_to` > "'.$dateFrom.'"'
|
||
.HotelBranchInformation::addHotelRestriction($idsHotel, 'hbd')
|
||
.($idProduct ? ' AND hbd.`id_product` = '.$idProduct : '')
|
||
);
|
||
|
||
$bookingsByProduct = array();
|
||
foreach ($bookingsRaw as $b) {
|
||
$bookingsByProduct[$b['id_product']][] = $b;
|
||
}
|
||
|
||
// Active rooms blocked by a disable date range (inactive rooms are already counted as out of order)
|
||
$disabledRaw = Db::getInstance()->executeS(
|
||
'SELECT hri.`id_product`, hrdd.`id_room`, hrdd.`date_from`, hrdd.`date_to`
|
||
FROM `'._DB_PREFIX_.'htl_room_disable_dates` hrdd
|
||
INNER JOIN `'._DB_PREFIX_.'htl_room_information` hri ON (hri.`id` = hrdd.`id_room`)
|
||
WHERE hri.`id_status` = '.(int) self::STATUS_ACTIVE.'
|
||
AND hrdd.`date_from` < "'.$dateToNext.'" AND hrdd.`date_to` > "'.$dateFrom.'"'
|
||
.HotelBranchInformation::addHotelRestriction($idsHotel, 'hri')
|
||
.($idProduct ? ' AND hri.`id_product` = '.$idProduct : '')
|
||
);
|
||
|
||
$disabledByProduct = array();
|
||
foreach ($disabledRaw as $d) {
|
||
$disabledByProduct[$d['id_product']][] = $d;
|
||
}
|
||
|
||
$result = array();
|
||
$current = $dateFrom;
|
||
while ($current <= $dateTo) {
|
||
$next = date('Y-m-d', strtotime('+1 day', strtotime($current)));
|
||
foreach ($roomTypes as $rt) {
|
||
$idProd = $rt['id_product'];
|
||
$bookedRooms = array();
|
||
if (isset($bookingsByProduct[$idProd])) {
|
||
foreach ($bookingsByProduct[$idProd] as $b) {
|
||
if ($b['date_from'] < $next && $b['date_to'] > $current) {
|
||
$bookedRooms[$b['id_room']] = true;
|
||
}
|
||
}
|
||
}
|
||
$disabledRooms = array();
|
||
if (isset($disabledByProduct[$idProd])) {
|
||
foreach ($disabledByProduct[$idProd] as $d) {
|
||
if ($d['date_from'] < $next && $d['date_to'] > $current) {
|
||
$disabledRooms[$d['id_room']] = true;
|
||
}
|
||
}
|
||
}
|
||
$booked = count($bookedRooms);
|
||
$total = (int) $rt['total_rooms'];
|
||
$ooo = (int) $rt['ooo_rooms'] + count($disabledRooms);
|
||
$available = max(0, $total - $booked - $ooo);
|
||
$result[] = array(
|
||
'date' => $current,
|
||
'id_product' => $idProd,
|
||
'room_type_name' => $rt['room_type_name'],
|
||
'total_rooms' => $total,
|
||
'rooms_booked' => $booked,
|
||
'out_of_order' => $ooo,
|
||
'available' => $available,
|
||
'occupancy_pct' => $total ? round($booked / $total * 100, 1) : 0.0,
|
||
);
|
||
}
|
||
$current = $next;
|
||
}
|
||
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* Per-room status with current guest info for room-status report tab.
|
||
*
|
||
* @param array $params date_from, date_to, id_hotel, id_product, id_lang, housekeeping_installed
|
||
* @return array
|
||
*/
|
||
public static function getRoomStatus(array $params)
|
||
{
|
||
$dateFrom = pSQL($params['date_from']);
|
||
$dateTo = pSQL(isset($params['date_to']) ? $params['date_to'] : $params['date_from']);
|
||
$dateToNext = pSQL(date('Y-m-d', strtotime('+1 day', strtotime($dateTo))));
|
||
$idsHotel = isset($params['ids_hotel']) ? $params['ids_hotel'] : (isset($params['id_hotel']) ? $params['id_hotel'] : false);
|
||
$idProduct = isset($params['id_product']) ? (int) $params['id_product'] : 0;
|
||
$idLang = isset($params['id_lang']) ? (int) $params['id_lang'] : 0;
|
||
$housekeepingInstalled = !empty($params['housekeeping_installed']);
|
||
if (!$idLang) {
|
||
$idLang = Context::getContext()->language->id;
|
||
}
|
||
|
||
return Db::getInstance()->executeS(
|
||
'SELECT hri.`id` AS id_room, hri.`room_num`, hri.`floor`,
|
||
hri.`id_status`,
|
||
IF(hri.`id_status` = '.(int) self::STATUS_ACTIVE.' AND hrdd.`id_room` IS NOT NULL, 1, 0) AS is_disabled,
|
||
hri.`id_product`, hri.`id_hotel`,
|
||
pl.`name` AS room_type_name, hbil.`hotel_name`,
|
||
bkgs.`id_order`, bkgs.`date_from`, bkgs.`date_to`,
|
||
bkgs.`id_status` AS booking_status,
|
||
c.`id_customer`,
|
||
CONCAT(c.`firstname`, " ", c.`lastname`) AS guest_name'
|
||
.($housekeepingInstalled ? ', hri.`id_housekeeping_status`' : '').'
|
||
FROM `'._DB_PREFIX_.'htl_room_information` hri
|
||
INNER JOIN `'._DB_PREFIX_.'product` p ON (p.`id_product` = hri.`id_product`)
|
||
INNER JOIN `'._DB_PREFIX_.'product_lang` pl
|
||
ON (pl.`id_product` = hri.`id_product` AND pl.`id_lang` = '.(int) $idLang.')
|
||
INNER JOIN `'._DB_PREFIX_.'htl_branch_info` hbi ON (hbi.`id` = hri.`id_hotel`)
|
||
INNER JOIN `'._DB_PREFIX_.'htl_branch_info_lang` hbil
|
||
ON (hbil.`id` = hri.`id_hotel` AND hbil.`id_lang` = '.(int) $idLang.')
|
||
LEFT JOIN (
|
||
SELECT `id_room`
|
||
FROM `'._DB_PREFIX_.'htl_room_disable_dates`
|
||
WHERE `date_from` < "'.$dateToNext.'" AND `date_to` > "'.$dateFrom.'"
|
||
GROUP BY `id_room`
|
||
) hrdd ON (hrdd.`id_room` = hri.`id`)
|
||
LEFT JOIN (
|
||
SELECT hbd.`id_room`,
|
||
MIN(hbd.`id_order`) AS `id_order`,
|
||
MIN(hbd.`date_from`) AS `date_from`,
|
||
MAX(hbd.`date_to`) AS `date_to`,
|
||
MIN(hbd.`id_status`) AS `id_status`,
|
||
MIN(hbd.`id_customer`) AS `id_customer`
|
||
FROM `'._DB_PREFIX_.'htl_booking_detail` hbd
|
||
WHERE hbd.`id` NOT IN ('.OrderReturn::getRefundedBookingIdsSubquery().')
|
||
AND hbd.`date_from` < "'.$dateToNext.'" AND hbd.`date_to` > "'.$dateFrom.'"
|
||
GROUP BY hbd.`id_room`
|
||
) bkgs ON (bkgs.`id_room` = hri.`id`)
|
||
LEFT JOIN `'._DB_PREFIX_.'customer` c ON (c.`id_customer` = bkgs.`id_customer`)
|
||
WHERE p.`active` = 1 AND p.`booking_product` = 1'
|
||
.($idProduct ? ' AND hri.`id_product` = '.$idProduct : '')
|
||
.HotelBranchInformation::addHotelRestriction($idsHotel, 'hri').'
|
||
ORDER BY hbil.`hotel_name`, pl.`name`, hri.`room_num`'
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Floor list for filter dropdown in reports.
|
||
*
|
||
* @param array $params id_hotel, id_product
|
||
* @return array rows: floor
|
||
*/
|
||
public static function getDistinctFloors(array $params = array())
|
||
{
|
||
$idsHotel = isset($params['ids_hotel']) ? $params['ids_hotel'] : (isset($params['id_hotel']) ? $params['id_hotel'] : false);
|
||
$idProduct = isset($params['id_product']) ? (int) $params['id_product'] : 0;
|
||
|
||
return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(
|
||
'SELECT DISTINCT hri.`floor`
|
||
FROM `'._DB_PREFIX_.'htl_room_information` hri
|
||
INNER JOIN `'._DB_PREFIX_.'product` p
|
||
ON (p.`id_product` = hri.`id_product` AND p.`active` = 1 AND p.`booking_product` = 1)
|
||
WHERE hri.`floor` != "" AND hri.`floor` IS NOT NULL'
|
||
.($idProduct ? ' AND hri.`id_product` = '.$idProduct : '')
|
||
.HotelBranchInformation::addHotelRestriction($idsHotel, 'hri').'
|
||
ORDER BY hri.`floor`'
|
||
);
|
||
}
|
||
}
|