diff --git a/admin/themes/default/template/controllers/carts/helpers/view/view.tpl b/admin/themes/default/template/controllers/carts/helpers/view/view.tpl index 41f4ee2fe..09decd44b 100644 --- a/admin/themes/default/template/controllers/carts/helpers/view/view.tpl +++ b/admin/themes/default/template/controllers/carts/helpers/view/view.tpl @@ -109,7 +109,7 @@ {displayWtPriceWithCurrency price=$room['feature_price_tax_excl'] currency=$currency} - {if (isset($room['extra_demands']) && $room['extra_demands']) || (isset($room['additional_service']) && $room['additional_service'])} + {if (isset($room['selected_demands']) && $room['selected_demands']) || (isset($room['selected_services']) && $room['selected_services'])} {displayWtPriceWithCurrency price=($room['demand_price'] + $room['additional_service_price'] + $room['additional_services_auto_add_price'])|escape:'html':'UTF-8' currency=$currency} @@ -118,7 +118,7 @@ {/if} - {if (isset($room['extra_demands']) && $room['extra_demands']) || (isset($room['additional_service']) && $room['additional_service'])} + {if (isset($room['selected_demands']) && $room['selected_demands']) || (isset($room['selected_services']) && $room['selected_services'])} {displayWtPriceWithCurrency price=($room['amt_with_qty'] + $room['additional_services_auto_add_price'] + $room['demand_price'] + $room['additional_service_price'])|escape:'html':'UTF-8' currency=$currency} {else} {displayWtPriceWithCurrency price=$room['amt_with_qty']|escape:'html':'UTF-8' currency=$currency} @@ -166,7 +166,13 @@
-

{if isset($roomDemand['adv_option']) && $roomDemand['adv_option']}{convertPrice price = $roomDemand['adv_option'][$idGlobalDemand]['price']|escape:'html':'UTF-8'}{else}{convertPrice price = $roomDemand['price']|escape:'html':'UTF-8'}{/if}

+

+ {if isset($roomDemand['adv_option']) && $roomDemand['adv_option']} + {convertPrice price = $roomDemand['adv_option'][$demand['id_option']]['price']|escape:'html':'UTF-8'} + {else} + {convertPrice price = $roomDemand['price']|escape:'html':'UTF-8'} + {/if} +

{/if} diff --git a/admin/themes/default/template/controllers/orders/modals/_edit_room_tab_content.tpl b/admin/themes/default/template/controllers/orders/modals/_edit_room_tab_content.tpl index 7df2e26b9..7546e19ca 100644 --- a/admin/themes/default/template/controllers/orders/modals/_edit_room_tab_content.tpl +++ b/admin/themes/default/template/controllers/orders/modals/_edit_room_tab_content.tpl @@ -28,6 +28,15 @@ + {if isset($data.id_status) && ($data.id_status != HotelBookingDetail::STATUS_ALLOTED)} +
+ {if $data.id_status == HotelBookingDetail::STATUS_CHECKED_IN} + {l s='The check-in date cannot be changed as the booking has already been checked in.'} + {else if HotelBookingDetail::STATUS_CHECKED_OUT} + {l s='The check-in and check-out date cannot be changed as the booking has already been checked out.'} + {/if} +
+ {/if}
@@ -37,7 +46,7 @@ {if isset($refundReqBookings) && $refundReqBookings && $data.id|in_array:$refundReqBookings && $data.is_refunded} {dateFormat date=$data.date_from} {else} - +
{/if}
@@ -49,7 +58,7 @@ {if isset($refundReqBookings) && $refundReqBookings && $data.id|in_array:$refundReqBookings && $data.is_refunded} {dateFormat date=$data.date_to} {else} - +
{/if}
diff --git a/admin/themes/default/template/controllers/products/configuration.tpl b/admin/themes/default/template/controllers/products/configuration.tpl index db65db934..20e4e1775 100644 --- a/admin/themes/default/template/controllers/products/configuration.tpl +++ b/admin/themes/default/template/controllers/products/configuration.tpl @@ -63,6 +63,7 @@ + {hook h='displayHotelRoomListTableHeaderColumn'} {l s='--'} @@ -99,6 +100,7 @@ + {hook h='displayHotelRoomListTableRowColumn' index=$key id_room=$room_info['id']} {if isset($room_info['id'])} {if isset($room_info['booked_dates']) && $room_info['booked_dates']} @@ -139,6 +141,7 @@ + {hook h='displayHotelRoomListTableRowColumn' index=$k} {if $k == 1} @@ -417,6 +420,7 @@ html += ''; html += ''; html += ''; + html += '{hook h='displayHotelRoomListTableRowColumn'}'; html += ''; html += ''; html += ''; @@ -1319,4 +1323,4 @@ } }); - \ No newline at end of file + diff --git a/classes/Cart.php b/classes/Cart.php index e826b3f97..02bbd5c78 100644 --- a/classes/Cart.php +++ b/classes/Cart.php @@ -733,11 +733,18 @@ class CartCore extends ObjectModel $totalPriceByProductTaxExcl = 0; $priceDisplay = Group::getPriceDisplayMethod(Group::getCurrent()->id); foreach ($roomTypesByIdProduct as $key => $cartRoomInfo) { + $occupancy = array( + array( + 'adults' => $cartRoomInfo['adults'], + 'children' => $cartRoomInfo['children'], + 'child_ages' => json_decode($cartRoomInfo['child_ages']) + ) + ); $roomTotalPrice = HotelRoomTypeFeaturePricing::getRoomTypeTotalPrice( $cartRoomInfo['id_product'], $cartRoomInfo['date_from'], $cartRoomInfo['date_to'], - 0, + $occupancy, Group::getCurrent()->id, $cartRoomInfo['id_cart'], $cartRoomInfo['id_guest'], @@ -1780,12 +1787,19 @@ class CartCore extends ObjectModel $totalPriceByProduct = 0; $priceDisplay = Group::getPriceDisplayMethod(Group::getCurrent()->id); foreach ($roomTypesByIdProduct as $key => $cartRoomInfo) { + $occupancy = array( + array( + 'adults' => $cartRoomInfo['adults'], + 'children' => $cartRoomInfo['children'], + 'child_ages' => json_decode($cartRoomInfo['child_ages']) + ) + ); // get the real price of the room type $roomTotalPrice = HotelRoomTypeFeaturePricing::getRoomTypeTotalPrice( $cartRoomInfo['id_product'], $cartRoomInfo['date_from'], $cartRoomInfo['date_to'], - 0, + $occupancy, Group::getCurrent()->id, $cartRoomInfo['id_cart'], $cartRoomInfo['id_guest'], @@ -2294,7 +2308,6 @@ class CartCore extends ObjectModel $orderPackage = array(); $serviceProducts = array(); $objRoomType = new HotelRoomType(); - $objHtlCartBookingData = new HotelCartBookingData(); $objRoomTypeServiceProductCartDetail = new RoomTypeServiceProductCartDetail(); $objHotelServiceProductCartDetail = new HotelServiceProductCartDetail(); foreach ($final_package_list as $id_address => $packages) { diff --git a/classes/PaymentModule.php b/classes/PaymentModule.php index 7a32be778..e15ac46d1 100644 --- a/classes/PaymentModule.php +++ b/classes/PaymentModule.php @@ -808,11 +808,18 @@ abstract class PaymentModuleCore extends Module $objBookingDetail->is_back_order = $objCartBookingData->is_back_order; $objBookingDetail->comment = $objCartBookingData->comment; + $occupancy = array( + array( + 'adults' => $objCartBookingData->adults, + 'children' => $objCartBookingData->children, + 'child_ages' => json_decode($objCartBookingData->child_ages) + ) + ); $total_price = HotelRoomTypeFeaturePricing::getRoomTypeTotalPrice( $idProduct, $objCartBookingData->date_from, $objCartBookingData->date_to, - 0, + $occupancy, Group::getCurrent()->id, $objCartBookingData->id_cart, $objCartBookingData->id_guest, @@ -1700,6 +1707,7 @@ abstract class PaymentModuleCore extends Module } else { $cart_bk_data = $obj_htl_bk_dtl->getOnlyOrderBookingData($order->id, $customer->id_guest, $type_value['product_id']); } + if ($cart_bk_data) { $rm_dtl = $obj_rm_type->getRoomTypeInfoByIdProduct($type_value['product_id']); @@ -1720,11 +1728,20 @@ abstract class PaymentModuleCore extends Module $cart_htl_data[$type_key]['date_diff'][$date_join]['adults'] += $data_v['adults']; $cart_htl_data[$type_key]['date_diff'][$date_join]['children'] += $data_v['children']; + $occupancy = array( + array( + 'adults' => $data_v['adults'], + 'children' => $data_v['children'], + 'child_ages' => json_decode($data_v['child_ages']) + ) + ); - - - $roomTypeDateRangePrice = HotelRoomTypeFeaturePricing::getRoomTypeTotalPrice($type_value['id_product'], $data_v['date_from'], $data_v['date_to']); - + $roomTypeDateRangePrice = HotelRoomTypeFeaturePricing::getRoomTypeTotalPrice( + $type_value['id_product'], + $data_v['date_from'], + $data_v['date_to'], + $occupancy + ); $cart_htl_data[$type_key]['date_diff'][$date_join]['amount'] = $roomTypeDateRangePrice['total_price_tax_incl']*$vart_quant; $cart_htl_data[$type_key]['date_diff'][$date_join]['paid_unit_price_tax_incl'] = $data_v['total_price_tax_incl']/$num_days; @@ -1745,9 +1762,7 @@ abstract class PaymentModuleCore extends Module $cart_htl_data[$type_key]['date_diff'][$date_join]['adults'] = $data_v['adults']; $cart_htl_data[$type_key]['date_diff'][$date_join]['children'] = $data_v['children']; - - - // extra demands prices + // extra demands prices $cart_htl_data[$type_key]['date_diff'][$date_join]['extra_demands'] = $objBookingDemand->getRoomTypeBookingExtraDemands( $order->id, $type_value['product_id'], @@ -1831,6 +1846,7 @@ abstract class PaymentModuleCore extends Module } $result['cart_htl_data'] = $cart_htl_data; } + return $result; } } diff --git a/classes/Product.php b/classes/Product.php index ac8f01e6f..19421df19 100644 --- a/classes/Product.php +++ b/classes/Product.php @@ -931,12 +931,21 @@ class ProductCore extends ObjectModel ), 'id_product = '.(int)$id_product); } - public static function getProductPriceCalculation($id_product) { - return Db::getInstance()->getValue( - 'SELECT product_shop.`price_calculation_method` - FROM `'._DB_PREFIX_.'product` p '.Shop::addSqlAssociation('product', 'p').' - WHERE p.`id_product` = '.(int)$id_product - ); + public static function getProductPriceCalculation($id_product) + { + $cache_key = 'Product::getProductPriceCalculation'.(int)$id_product; + if (!Cache::isStored($cache_key)) { + $res = Db::getInstance()->getValue( + 'SELECT product_shop.`price_calculation_method` + FROM `'._DB_PREFIX_.'product` p '.Shop::addSqlAssociation('product', 'p').' + WHERE p.`id_product` = '.(int)$id_product + ); + Cache::store($cache_key, $res); + } else { + $res = Cache::retrieve($cache_key); + } + + return $res; } /** @@ -973,10 +982,18 @@ class ProductCore extends ObjectModel public static function isBookingProduct($id_product) { - return Db::getInstance()->getValue(' - SELECT `booking_product` FROM `'._DB_PREFIX_.'product` p - WHERE p.`id_product` = '.(int)$id_product - ); + $cache_key = 'Product::isBookingProduct_'.(int)$id_product; + if (!Cache::isStored($cache_key)) { + $res = Db::getInstance()->getValue(' + SELECT `booking_product` FROM `'._DB_PREFIX_.'product` p + WHERE p.`id_product` = '.(int)$id_product + ); + Cache::store($cache_key, $res); + } else { + $res = Cache::retrieve($cache_key); + } + + return $res; } public function delete() diff --git a/classes/controller/Controller.php b/classes/controller/Controller.php index e9628c6a8..8908d6159 100644 --- a/classes/controller/Controller.php +++ b/classes/controller/Controller.php @@ -649,8 +649,8 @@ abstract class ControllerCore $method = $bt[1]['function']; } - Hook::exec('actionBeforeAjaxDie', array('controller' => $controller, 'method' => $method, 'value' => $value)); - Hook::exec('actionBeforeAjaxDie'.$controller.$method, array('value' => $value)); + Hook::exec('actionBeforeAjaxDie', array('controller' => $controller, 'method' => $method, 'value' => &$value)); + Hook::exec('actionBeforeAjaxDie'.$controller.$method, array('value' => &$value)); die($value); } diff --git a/classes/pdf/HTMLTemplateInvoice.php b/classes/pdf/HTMLTemplateInvoice.php index e2a82cbf0..2066ae493 100644 --- a/classes/pdf/HTMLTemplateInvoice.php +++ b/classes/pdf/HTMLTemplateInvoice.php @@ -314,10 +314,17 @@ class HTMLTemplateInvoiceCore extends HTMLTemplate $service_product_data = array(); $room_extra_demands = array(); $room_additinal_services = array(); + $formattedHotelAddress = ''; if (Module::isInstalled('hotelreservationsystem')) { $obj_htl_bk_dtl = new HotelBookingDetail(); - $obj_rm_type = new HotelRoomType(); $objRoomTypeServiceProductOrderDetail = new RoomTypeServiceProductOrderDetail(); + $objHotelBranchInfo = new HotelBranchInformation((int) HotelBookingDetail::getIdHotelByIdOrder($order_obj->id), $this->context->language->id); + $invoiceAddressPatternRules['avoid'][] = 'lastname'; + if ($idHotelAddress = $objHotelBranchInfo->getHotelIdAddress()) { + $objHotelAddress = new Address((int) $idHotelAddress); + $objHotelAddress->firstname = $objHotelBranchInfo->hotel_name; + $formattedHotelAddress = AddressFormat::generateAddress($objHotelAddress, $invoiceAddressPatternRules, '
', ' '); + } $customer = new Customer($this->order->id_customer); if (!empty($order_details)) { @@ -591,6 +598,7 @@ class HTMLTemplateInvoiceCore extends HTMLTemplate 'cart_rules' => $cart_rules, 'delivery_address' => $formatted_delivery_address, 'invoice_address' => $formatted_invoice_address, + 'hotel_address' => $formattedHotelAddress, 'addresses' => array('invoice' => $invoice_address, 'delivery' => $delivery_address), 'tax_excluded_display' => $tax_excluded_display, 'display_product_images' => $display_product_images, diff --git a/controllers/admin/AdminAddressesController.php b/controllers/admin/AdminAddressesController.php index afc8f587b..f130c202e 100644 --- a/controllers/admin/AdminAddressesController.php +++ b/controllers/admin/AdminAddressesController.php @@ -380,6 +380,21 @@ class AdminAddressesControllerCore extends AdminController return parent::renderForm(); } + public function processExport($text_delimiter = '"') + { + $this->fields_list = array_merge($this->fields_list, array( + 'email' => array('title' => $this->l('Customer Email')), + 'phone' => array('title' => $this->l('Phone')), + 'phone_mobile' => array('title' => $this->l('Mobile phone')), + 'address1' => array('title' => $this->l('Address (2)')), + 'dni' => array('title' => $this->l('Identification Number')), + 'vat_number' => array('title' => $this->l('VAT number')), + 'other' => array('title' => $this->l('Other')), + )); + + return parent::processExport($text_delimiter); + } + // public function postProcess() // { diff --git a/controllers/admin/AdminCartsController.php b/controllers/admin/AdminCartsController.php index 8f26b9294..4c7ac661a 100644 --- a/controllers/admin/AdminCartsController.php +++ b/controllers/admin/AdminCartsController.php @@ -302,6 +302,31 @@ class AdminCartsControllerCore extends AdminController $product['image'] = (isset($image['id_image']) ? ImageManager::thumbnail(_PS_IMG_DIR_.'p/'.$image_product->getExistingImgPath().'.jpg', 'product_mini_'.(int)$product['id_product'].(isset($product['id_product_attribute']) ? '_'.(int)$product['id_product_attribute'] : '').'.jpg', 45, 'jpg') : '--'); } + // by webkul to show rooms available in the cart + $cartHtlData = array(); + $objHotelCartBookingData = new HotelCartBookingData(); + $objHotelRoomType = new HotelRoomType(); + if ($cartHtlData = $objHotelCartBookingData->getCartFormatedBookinInfoByIdCart((int) $cart->id)) { + foreach ($cartHtlData as $key => $value) { + $cartHtlData[$key]['room_type_info'] = $objHotelRoomType->getRoomTypeInfoByIdProduct($value['id_product']); + if (isset($value['selected_services']) && $value['selected_services']) { + foreach ($value['selected_services'] as $service) { + if ($service['id_cart'] != $value['id_cart']) { + if ($tax_calculation_method == PS_TAX_EXC) { + $total_price += ($service['quantity'] * $service['total_price_tax_excl']); + $total_products += ($service['quantity'] * $service['total_price_tax_excl']); + } else { + $total_price += ($service['quantity'] * $service['total_price_tax_incl']); + $total_products += ($service['quantity'] * $service['total_price_tax_incl']); + } + } + } + } + } + } else { + $cartHtlData = array(); + } + $helper = new HelperKpi(); $helper->id = 'box-kpi-cart'; $helper->icon = 'icon-shopping-cart'; @@ -310,17 +335,6 @@ class AdminCartsControllerCore extends AdminController $helper->subtitle = sprintf($this->l('Cart #%06d', null, null, false), $cart->id); $helper->value = Tools::displayPrice($total_price, $currency); $kpi = $helper->generate(); - // by webkul to show rooms available in the cart - $cartHtlData = array(); - $objHotelCartBookingData = new HotelCartBookingData(); - $objHotelRoomType = new HotelRoomType(); - if ($cartHtlData = $objHotelCartBookingData->getCartFormatedBookinInfoByIdCart((int) $cart->id)) { - foreach ($cartHtlData as $key => $value) { - $cartHtlData[$key]['room_type_info'] = $objHotelRoomType->getRoomTypeInfoByIdProduct($value['id_product']); - } - } else { - $cartHtlData = array(); - } //end $this->tpl_view_vars = array( 'cart_htl_data' => $cartHtlData,//by webkul hotel rooms in order data diff --git a/controllers/admin/AdminCustomersController.php b/controllers/admin/AdminCustomersController.php index 997cb0508..f81342a8f 100644 --- a/controllers/admin/AdminCustomersController.php +++ b/controllers/admin/AdminCustomersController.php @@ -97,13 +97,16 @@ class AdminCustomersControllerCore extends AdminController 'order_key' => 'gl!name' ), 'firstname' => array( - 'title' => $this->l('First name') + 'title' => $this->l('First name'), + 'filter_key' => 'a!firstname' ), 'lastname' => array( - 'title' => $this->l('Last name') + 'title' => $this->l('Last name'), + 'filter_key' => 'a!lastname' ), 'email' => array( - 'title' => $this->l('Email address') + 'title' => $this->l('Email address'), + 'filter_key' => 'a!email' ), ); @@ -143,6 +146,7 @@ class AdminCustomersControllerCore extends AdminController ), 'phone' => array( 'title' => $this->l('Phone'), + 'filter_key' => 'a!phone', 'optional' => true, 'visible_default' => false, ), @@ -152,7 +156,8 @@ class AdminCustomersControllerCore extends AdminController 'active' => 'status', 'type' => 'bool', 'orderby' => false, - 'filter_key' => 'a!active' + 'filter_key' => 'a!active', + 'callback' => 'formatStatusAsLabel', ), 'newsletter' => array( 'title' => $this->l('Newsletter'), @@ -184,6 +189,7 @@ class AdminCustomersControllerCore extends AdminController 'title' => $this->l('Banned'), 'type' => 'bool', 'displayed' => false, + 'callback' => 'getCustomerStatusLabel', ), 'order_date' => array( 'title' => $this->l('Order date'), @@ -235,6 +241,28 @@ class AdminCustomersControllerCore extends AdminController } } + public function formatStatusAsLabel($val, $row) + { + if ($val) { + $str_return = $this->l('Yes'); + } else { + $str_return = $this->l('No'); + } + + return $str_return; + } + + public function getCustomerStatusLabel($deleted, $tr) + { + if ($deleted == Customer::STATUS_DELETED) { + return $this->l('Deleted'); + } else if ($deleted == Customer::STATUS_BANNED) { + return $this->l('Banned'); + } + + return; + } + public function initContent() { if ($this->action == 'select_delete') { @@ -268,8 +296,11 @@ class AdminCustomersControllerCore extends AdminController public function getList($id_lang, $orderBy = null, $orderWay = null, $start = 0, $limit = null, $id_lang_shop = null) { - parent::getList($id_lang, $orderBy, $orderWay, $start, $limit, $id_lang_shop); + if ($this->action == 'export') { + $this->deleted = false; + } + parent::getList($id_lang, $orderBy, $orderWay, $start, $limit, $id_lang_shop); if ($this->_list) { foreach ($this->_list as &$row) { $row['badge_success'] = $row['total_spent'] > 0; @@ -1040,6 +1071,14 @@ class AdminCustomersControllerCore extends AdminController } } + public function processExport($text_delimiter = '"') + { + $this->fields_list['newsletter']['callback'] = 'formatStatusAsLabel'; + $this->fields_list['optin']['callback'] = 'formatStatusAsLabel'; + + return parent::processExport($text_delimiter); + } + protected function processBulkDelete() { // If customer is going to be deleted permanently then if customer has orders the change this customer as an anonymous customer diff --git a/controllers/admin/AdminImportController.php b/controllers/admin/AdminImportController.php index 051625e54..da1ae5c0f 100644 --- a/controllers/admin/AdminImportController.php +++ b/controllers/admin/AdminImportController.php @@ -148,8 +148,8 @@ class AdminImportControllerCore extends AdminController 'policies' => array('label' => $this->l('Hotel Policies')), 'active_refund' => array('label' => $this->l('Allow Refund (0 = No, 1 = Yes)')), 'refund_ids' => array('label' => $this->l('Refund IDs (x,y,z...)')), - 'max_order_date' => array('label' => $this->l('Max Order Date')), - 'preparation_time' => array('label' => $this->l('Prepration Time')), + 'max_checkout_offset' => array('label' => $this->l('Maximum checkout offset')), + 'min_booking_offset' => array('label' => $this->l('Minimum booking offset')), 'image' => array('label' => $this->l('Image URLs (x,y,z...)')), 'delete_existing_images' => array( 'label' => $this->l('Delete existing images (0 = No, 1 = Yes)') @@ -1410,19 +1410,23 @@ class AdminImportControllerCore extends AdminController } $objHotelOrderRestrictDate->id_hotel = $objHotelBranch->id; - $objHotelOrderRestrictDate->use_global_max_order_date = true; - if (isset($info['max_order_date']) - && strtotime('now') < strtotime($info['max_order_date']) + $objHotelOrderRestrictDate->use_global_max_checkout_offset = true; + $objHotelOrderRestrictDate->use_global_min_booking_offset = true; + + if (isset($info['max_checkout_offset']) + && (Configuration::get('PS_MIN_BOOKING_OFFSET') < $info['max_checkout_offset'] + || isset($info['min_booking_offset']) && $info['min_booking_offset'] < $info['max_checkout_offset']) ) { - $objHotelOrderRestrictDate->use_global_max_order_date = false; - $date = date('Y-m-d', strtotime($info['max_order_date'])); - $objHotelOrderRestrictDate->max_order_date = $date; + $objHotelOrderRestrictDate->use_global_max_checkout_offset = false; + $objHotelOrderRestrictDate->max_checkout_offset = $info['max_checkout_offset']; } - $objHotelOrderRestrictDate->use_global_preparation_time = true; - if (isset($info['preparation_time']) && $info['preparation_time']) { - $objHotelOrderRestrictDate->use_global_preparation_time = false; - $objHotelOrderRestrictDate->preparation_time = $info['preparation_time']; + if (isset($info['min_booking_offset']) + && (Configuration::get('PS_MAX_CHECKOUT_OFFSET') > $info['min_booking_offset'] + || isset($info['max_checkout_offset']) && $info['max_checkout_offset'] > $info['min_booking_offset']) + ) { + $objHotelOrderRestrictDate->use_global_min_booking_offset = false; + $objHotelOrderRestrictDate->min_booking_offset = $info['min_booking_offset']; } $objHotelOrderRestrictDate->save(); diff --git a/controllers/admin/AdminNormalProductsController.php b/controllers/admin/AdminNormalProductsController.php index 66dc1c963..08956e267 100644 --- a/controllers/admin/AdminNormalProductsController.php +++ b/controllers/admin/AdminNormalProductsController.php @@ -257,12 +257,14 @@ class AdminNormalProductsControllerCore extends AdminController 'title' => $this->l('Available for order'), 'filter_key' => 'a!available_for_order', 'type' => 'bool', + 'callback' => 'formatStatusAsLabel', ); $this->fields_list['price_addition_type'] = array( 'displayed' => false, 'title' => $this->l('Price display preference'), 'filter_key' => 'a!price_addition_type', 'type' => 'select', + 'callback' => 'getPriceDisplayPreference', 'list' => $priceAdditionType, ); $this->fields_list['price_calculation_method_txt'] = array( @@ -311,7 +313,8 @@ class AdminNormalProductsControllerCore extends AdminController 'title' => $this->l('Base price'), 'type' => 'price', 'align' => 'text-left', - 'filter_key' => 'a!price' + 'filter_key' => 'a!price', + 'callback' => 'displayPrice', ); $this->fields_list['price_final'] = array( 'title' => $this->l('Final price'), @@ -319,7 +322,8 @@ class AdminNormalProductsControllerCore extends AdminController 'align' => 'text-left', 'havingFilter' => true, 'orderby' => false, - 'search' => false + 'search' => false, + 'callback' => 'displayPrice', ); $this->fields_list['active'] = array( @@ -329,6 +333,7 @@ class AdminNormalProductsControllerCore extends AdminController 'align' => 'text-center', 'type' => 'bool', 'class' => 'fixed-width-sm', + 'callback' => 'formatStatusAsLabel', 'orderby' => false ); @@ -342,6 +347,34 @@ class AdminNormalProductsControllerCore extends AdminController } } + public function formatStatusAsLabel($val, $row) + { + if ($val) { + $str_return = $this->l('Yes'); + } else { + $str_return = $this->l('No'); + } + + return $str_return; + } + + public function getPriceDisplayPreference($val, $row) + { + $str_return = $val; + if ($val == Product::PRICE_ADDITION_TYPE_WITH_ROOM) { + $str_return = $this->l('Add price in room price'); + } else if ($val == Product::PRICE_ADDITION_TYPE_INDEPENDENT) { + $str_return = $this->l('Convenience Fee'); + } + + return $str_return; + } + + public static function displayPrice($basePrice, $tr) + { + return Tools::displayPrice($basePrice, (int) Configuration::get('PS_CURRENCY_DEFAULT')); + } + private function buildCategoryOptions($category) { $space = str_repeat(' ', 5 * (($category['level_depth'] - $this->objLocationsCategory->level_depth) - 1)); diff --git a/controllers/admin/AdminOrderPreferencesController.php b/controllers/admin/AdminOrderPreferencesController.php index 241ed1c29..15ea3c8d4 100644 --- a/controllers/admin/AdminOrderPreferencesController.php +++ b/controllers/admin/AdminOrderPreferencesController.php @@ -82,22 +82,19 @@ class AdminOrderPreferencesControllerCore extends AdminController ) ); - $maxOrderDate = Tools::getValue('MAX_GLOBAL_BOOKING_DATE', Configuration::get('MAX_GLOBAL_BOOKING_DATE')); $this->fields_options = array( 'order_restrict' => array( 'title' => $this->l('Order Restrict'), 'icon' => 'icon-cogs', 'fields' => array( - 'MAX_GLOBAL_BOOKING_DATE' => array( - 'title' => $this->l('Maximum Global Check-out Date to book a room'), - 'hint' => $this->l('Maximum date of check-out for which rooms of your hotels can be booked.'), + 'PS_MAX_CHECKOUT_OFFSET' => array( + 'title' => $this->l('Maximum checkout offset'), + 'hint' => $this->l('The maximum checkout offset defines how many days from today checkout is allowed. For example, if this value is set to 10 and someone is booking on March 1st, they can only select a checkout date up to March 11th.'), 'type' => 'text', - 'id' => 'max_global_book_date', - 'auto_value' => false, - 'value' => date('d-m-Y', strtotime($maxOrderDate)), - 'class' => 'fixed-width-xxl readonly', + 'class' => 'fixed-width-xl', + 'suffix' => $this->l('day(s)'), ), - 'GLOBAL_PREPARATION_TIME' => array( + 'PS_MIN_BOOKING_OFFSET' => array( 'title' => $this->l('Minimum booking offset'), 'hint' => $this->l('The minimum booking offset is the minimum number of days before the check-in date that a guest must book a room. For example, if you set this value to 3 and someone is booking on 2nd of March he can only book rooms for dates from and after 3 days, i.e, 5th of March.'), 'desc' => $this->l('Set to 0 to disable this feature.'), @@ -332,24 +329,23 @@ class AdminOrderPreferencesControllerCore extends AdminController $this->errors[] = Tools::displayError('Please assign a valid CMS page for Terms and Conditions.'); } - $_POST['MAX_GLOBAL_BOOKING_DATE'] = date('Y-m-d', strtotime(Tools::getValue('MAX_GLOBAL_BOOKING_DATE'))); - $maxGlobalBookingDate = Tools::getValue('MAX_GLOBAL_BOOKING_DATE'); - $globalPreparationTime = Tools::getValue('GLOBAL_PREPARATION_TIME'); - $maxGlobalBookingDateFormatted = date('Y-m-d', strtotime($maxGlobalBookingDate)); - - if ($maxGlobalBookingDate == '') { - $this->errors[] = Tools::displayError('Field \'Maximum Global Check-out Date to book a room\' can not be empty.'); - } elseif (!Validate::isDate($maxGlobalBookingDateFormatted)) { - $this->errors[] = Tools::displayError('Field \'Maximum Global Check-out Date to book a room\' is invalid.'); - } elseif (strtotime($maxGlobalBookingDateFormatted) < strtotime(date('Y-m-d'))) { - $this->errors[] = Tools::displayError('Field \'Maximum Global Check-out Date to book a room\' can not be a past date. Please use a future date.'); + $maxCheckoutOffset = Tools::getValue('PS_MAX_CHECKOUT_OFFSET'); + $minBookingOffset = Tools::getValue('PS_MIN_BOOKING_OFFSET'); + if ($maxCheckoutOffset === '') { + $this->errors[] = Tools::displayError('Field \'Maximum checkout offset\' can not be empty.'); + } elseif (!$maxCheckoutOffset || !Validate::isUnsignedInt($maxCheckoutOffset)) { + $this->errors[] = Tools::displayError('Field \'Maximum checkout offset\' is invalid.'); } - if ($globalPreparationTime === '') { + if ($minBookingOffset === '') { $this->errors[] = Tools::displayError('Field \'Minimum booking offset\' can not be empty.'); - } elseif ($globalPreparationTime !== '0' && !Validate::isUnsignedInt($globalPreparationTime)) { + } elseif ($minBookingOffset != 0 && !Validate::isUnsignedInt($minBookingOffset)) { $this->errors[] = Tools::displayError('Field \'Minimum booking offset\' is invalid.'); } + + if ($maxCheckoutOffset && $maxCheckoutOffset <= $minBookingOffset) { + $this->errors[] = Tools::displayError('Field \'Maximum checkout offset\' cannot be be less than or equal to \'Minimum booking offset\'.'); + } } public function setMedia() diff --git a/controllers/admin/AdminOrdersController.php b/controllers/admin/AdminOrdersController.php index bb32323e3..4b4749c20 100644 --- a/controllers/admin/AdminOrdersController.php +++ b/controllers/admin/AdminOrdersController.php @@ -79,8 +79,7 @@ class AdminOrdersControllerCore extends AdminController LEFT JOIN `'._DB_PREFIX_.'order_state` os ON (os.`id_order_state` = a.`current_state`) LEFT JOIN `'._DB_PREFIX_.'order_state_lang` osl ON (os.`id_order_state` = osl.`id_order_state` AND osl.`id_lang` = '.(int) $this->context->language->id.') LEFT JOIN `'._DB_PREFIX_.'htl_booking_detail` hbd ON (hbd.`id_order` = a.`id_order`) - LEFT JOIN `'._DB_PREFIX_.'htl_branch_info_lang` hbil ON (hbil.`id` = hbd.`id_hotel`)'; - + LEFT JOIN `'._DB_PREFIX_.'htl_branch_info_lang` hbil ON (hbil.`id` = hbd.`id_hotel` AND osl.`id_lang` = hbil.`id_lang`)'; $this->_orderBy = 'id_order'; $this->_orderWay = 'DESC'; @@ -1194,6 +1193,127 @@ class AdminOrdersControllerCore extends AdminController return parent::renderList(); } + public function getList( + $id_lang, + $order_by = null, + $order_way = null, + $start = 0, + $limit = null, + $id_lang_shop = false + ){ + if ($this->action == 'export' && empty($this->_listsql)) { + $this->_select .= ', c.`email`, cgd.`phone`, a.`total_paid_real`, + orf.`cancellation_date`, orf.`cancellation_fee`, + cy.`iso_code` AS country, st.`iso_code` as state, ad.`city`, + CONCAT(ad.`address1`, \', \', ad.`postcode`) AS `cus_address`, hbdtl.*'; + + $this->_join .= ' LEFT JOIN `'._DB_PREFIX_.'cart_customer_guest_detail` cgd ON cgd.`email` = c.`email` AND cgd.`id_cart` = 0 + LEFT JOIN `'._DB_PREFIX_.'address` ad ON a.`id_customer`= ad.`id_customer` AND ad.`id_customer`!=0 + LEFT JOIN `'._DB_PREFIX_.'country` cy ON cy.`id_country`= ad.`id_country` + LEFT JOIN `'._DB_PREFIX_.'state` st ON st.`id_state`= ad.`id_state` + LEFT JOIN ( + SELECT ref.`id_order`, IF(refst.refunded = 1, GROUP_CONCAT(ref.`date_upd`), NULL) AS `cancellation_date`, + IF(refst.refunded = 1, SUM(ref.`refunded_amount`), NULL) AS `cancellation_fee` + FROM `'._DB_PREFIX_.'order_return` ref + LEFT JOIN `'._DB_PREFIX_.'order_return_state` refst + ON refst.`id_order_return_state` = ref.`state` AND refst.`refunded` = 1 + GROUP BY ref.`id_order` + ) AS orf ON orf.`id_order` = a.`id_order` + LEFT JOIN ( + SELECT GROUP_CONCAT( + CASE + WHEN `id_status`='.HotelBookingDetail::STATUS_ALLOTED.' THEN \''.$this->l('Alloted').'\' + WHEN `id_status`='.HotelBookingDetail::STATUS_CHECKED_IN.' THEN \''.$this->l('Checked in').'\' + WHEN `id_status`='.HotelBookingDetail::STATUS_CHECKED_OUT.' THEN \''.$this->l('Checked out').'\' + ELSE \''.$this->l('Invalid status').'\' + END + ) AS `room_status`, `id_order`, + GROUP_CONCAT(DISTINCT(`room_type_name`)) AS `room_types`, + GROUP_CONCAT(`date_from`) AS `date_from`, + GROUP_CONCAT(`date_to`) AS `date_to`, + GROUP_CONCAT(`room_num`) AS `rooms`, + GROUP_CONCAT(`check_in`) AS `check_in_dates`, + GROUP_CONCAT(`check_out`) AS `check_out_dates` + FROM `'._DB_PREFIX_.'htl_booking_detail` + GROUP BY `id_order` + ) AS hbdtl ON hbdtl.`id_order` = a.`id_order`'; + + $this->fields_list = array_merge($this->fields_list, array( + 'email' => array( + 'title' => $this->l('Email') + ), + 'phone' => array( + 'title' => $this->l('Phone') + ), + 'room_types' => array( + 'title' => $this->l('Room Types') + ), + 'rooms' => array( + 'title' => $this->l('Rooms') + ), + 'currency' => array( + 'title' => $this->l('Currency') + ), + 'total_paid_real' => array( + 'title' => $this->l('Amount Paid') + ), + 'check_in_dates' => array( + 'title' => $this->l('Check In') + ), + 'check_out_dates' => array( + 'title' => $this->l('Check Out') + ), + 'date_from' => array( + 'title' => $this->l('Date From'), + 'filter_key' => 'hbd!date_from', + ), + 'date_to' => array( + 'title' => $this->l('Date To'), + 'filter_key' => 'hbd!date_to', + ), + 'date_add' => array( + 'title' => $this->l('Reservation Date'), + 'filter_key' => 'a!date_add', + ), + 'room_status' => array( + 'title' => $this->l('Room Status'), + ), + 'country' => array( + 'title' => $this->l('Country'), + ), + 'state' => array( + 'title' => $this->l('State'), + ), + 'city' => array( + 'title' => $this->l('City'), + ), + 'cus_address' => array( + 'title' => $this->l('Address'), + ), + 'cancellation_date' => array( + 'title' => $this->l('Cancellation date'), + ), + 'cancellation_fee' => array( + 'title' => $this->l('Cancellation fee'), + ), + )); + + unset($this->fields_list['id_status']); + unset($this->fields_list['id_room_information']); + unset($this->fields_list['room_type_name']); + unset($this->fields_list['id_currency']); + } + + parent::getList( + $id_lang, + $order_by, + $order_way, + $start, + $limit, + $id_lang_shop + ); + } + public function postProcess() { // Process reallocation of rooms @@ -3508,7 +3628,7 @@ class AdminOrdersControllerCore extends AdminController } } } - $this->content = json_encode($to_return); + $this->ajaxDie(json_encode($to_return)); } // public function ajaxProcessSearchProducts() @@ -4581,11 +4701,19 @@ class AdminOrdersControllerCore extends AdminController $objBookingDetail->children = $objCartBookingData->children; $objBookingDetail->child_ages = $objCartBookingData->child_ages; + $occupancy = array( + array( + 'adults' => $objCartBookingData->adults, + 'children' => $objCartBookingData->children, + 'child_ages' => json_decode($objCartBookingData->child_ages) + ) + ); + $total_price = HotelRoomTypeFeaturePricing::getRoomTypeTotalPrice( $idProduct, $objCartBookingData->date_from, $objCartBookingData->date_to, - 0, + $occupancy, Group::getCurrent()->id, $this->context->cart->id, $this->context->cookie->id_guest, @@ -5454,6 +5582,15 @@ class AdminOrdersControllerCore extends AdminController $idHotelBooking ); + //This is added to remove the services from the cart along with room deletion process. + $objHotelCartBookingData = new HotelCartBookingData(); + $roomHtlCartInfo = $objHotelCartBookingData->getRoomRowByIdProductIdRoomInDateRange( + $objBookingDetail->id_cart, + $objBookingDetail->id_product, + $objBookingDetail->date_from, + $objBookingDetail->date_to, + $objBookingDetail->id_room + ); /*$totalProductPriceBeforeTE = $order_detail->total_price_tax_excl; $totalProductPriceBeforeTI = $order_detail->total_price_tax_incl;*/ @@ -5488,6 +5625,7 @@ class AdminOrdersControllerCore extends AdminController $res &= $order_detail->update(); } // update order detail for selected aditional services + $objRoomTypeServiceProductCartDetail = new RoomTypeServiceProductCartDetail(); foreach ($selectedAdditonalServices['additional_services'] as $service) { $serviceOrderDetail = new OrderDetail($service['id_order_detail']); @@ -5508,6 +5646,21 @@ class AdminOrdersControllerCore extends AdminController // Save order detail $res &= $serviceOrderDetail->update(); } + + if (isset($roomHtlCartInfo['id'])) { + if ($idRoomTypServiceProductCartDetail = $objRoomTypeServiceProductCartDetail->alreadyExists( + $service['id_product'], + $service['id_cart'], + $roomHtlCartInfo['id'] + )) { + $objRoomTypeServiceProductCartDetail = new RoomTypeServiceProductCartDetail((int) $idRoomTypServiceProductCartDetail); + $serviceQuantity = $objRoomTypeServiceProductCartDetail->quantity; + if ($objRoomTypeServiceProductCartDetail->delete()) { + $objCart = new Cart($service['id_cart']); + $objCart->updateQty((int)abs($serviceQuantity), $service['id_product'], null, false, 'down'); + } + } + } } /*End*/ @@ -5586,7 +5739,9 @@ class AdminOrdersControllerCore extends AdminController $objBookingDetail->id_product, $objBookingDetail->id_room, $objBookingDetail->date_from, - $objBookingDetail->date_to + $objBookingDetail->date_to, + 1, + $objBookingDetail->id_order ); $objBookingDetail->delete(); @@ -5790,8 +5945,8 @@ class AdminOrdersControllerCore extends AdminController // If order is refunded, the validate changes which are not allowed $objOrderReturn = new OrderReturn(); $refundReqBookings = $objOrderReturn->getOrderRefundRequestedBookings($order->id, 0, 1); + $objBookingDetail = new HotelBookingDetail($id_hotel_booking); if ($refundReqBookings && (in_array($id_hotel_booking, $refundReqBookings))) { - $objBookingDetail = new HotelBookingDetail($id_hotel_booking); // If order is cancelled, we can't edit order if ($objBookingDetail->is_refunded && $objBookingDetail->is_cancelled) { die(json_encode(array( @@ -5809,6 +5964,22 @@ class AdminOrdersControllerCore extends AdminController } } + if ($objBookingDetail->id_status != HotelBookingDetail::STATUS_ALLOTED + && strtotime($old_date_from) != strtotime($new_date_from) + ) { + die(json_encode(array( + 'result' => false, + 'error' => Tools::displayError('You cannot update the start date for a booking that has already been checked in.'), + ))); + } else if ($objBookingDetail->id_status == HotelBookingDetail::STATUS_CHECKED_OUT + && strtotime($old_date_to) != strtotime($new_date_to) + ) { + die(json_encode(array( + 'result' => false, + 'error' => Tools::displayError('You cannot update the end date for a booking that has already been checked out.'), + ))); + } + if (!Validate::isPrice($product_price_tax_incl) || !Validate::isPrice($product_price_tax_excl)) { die(json_encode(array( 'result' => false, @@ -6148,24 +6319,17 @@ class AdminOrdersControllerCore extends AdminController $del_id = Tools::getValue('del_id'); $room_id = Tools::getValue('id_room'); $obj_hotel_cart_detail = new HotelCartBookingData(); - $deleted = $obj_hotel_cart_detail->deleteCartBookingData($cart_id, $id_product, $room_id, $dt_frm, $dt_to); - if ($deleted) { + if ($obj_hotel_cart_detail->deleteCartBookingData($cart_id, $id_product, $room_id, $dt_frm, $dt_to)) { $obj_product_process = new HotelCartBookingData(); $num_cart_rooms = 0; + $dt_to = date('Y-m-d H:i:s', strtotime($dt_to) - _TIME_1_DAY_); + HotelRoomTypeFeaturePricing::deleteFeaturePrices($cart_id, $id_product, $room_id, $dt_frm, $dt_to); if ($rooms = $obj_hotel_cart_detail->getCartCurrentDataByCartId($cart_id)) { $num_cart_rooms = count($rooms); } - $numDays = HotelHelper::getNumberOfDays($dt_frm, $dt_to); - $dt_to = date('Y-m-d H:i:s', strtotime($dt_to) - _TIME_1_DAY_); - HotelRoomTypeFeaturePricing::deleteFeaturePrices($cart_id, $id_product, $room_id, $dt_frm, $dt_to); - $changed = $obj_product_process->changeProductDataByRoomId($room_id, $id_product, $numDays, $cart_id); - if ($changed) { - $result['status'] = 'deleted'; - $result['cart_rooms'] = $num_cart_rooms; - } else { - $result['status'] = 'failed'; - } + $result['status'] = 'deleted'; + $result['cart_rooms'] = $num_cart_rooms; } else { $result['status'] = 'failed'; } @@ -6506,8 +6670,31 @@ class AdminOrdersControllerCore extends AdminController $quantity = $objRoomTypeServiceProductOrderDetail->quantity; $res = true; $objHotelBookingDetail = new HotelBookingDetail($objRoomTypeServiceProductOrderDetail->id_htl_booking_detail); + $idServiceProduct = $objRoomTypeServiceProductOrderDetail->id_product; + $objHotelCartBookingData = new HotelCartBookingData(); + $roomHtlCartInfo = $objHotelCartBookingData->getRoomRowByIdProductIdRoomInDateRange( + $objHotelBookingDetail->id_cart, + $objHotelBookingDetail->id_product, + $objHotelBookingDetail->date_from, + $objHotelBookingDetail->date_to, + $objHotelBookingDetail->id_room + ); + $objRoomTypeServiceProductCartDetail = new RoomTypeServiceProductCartDetail(); if ($res &= $objRoomTypeServiceProductOrderDetail->delete()) { + if (isset($roomHtlCartInfo['id'])) { + if ($idRoomTypServiceProductCartDetail = $objRoomTypeServiceProductCartDetail->alreadyExists( + $idServiceProduct, + $objRoomTypeServiceProductOrderDetail->id_cart, + $roomHtlCartInfo['id'] + )) { + $objRoomTypeServiceProductCartDetail = new RoomTypeServiceProductCartDetail($idRoomTypServiceProductCartDetail); + if ($objRoomTypeServiceProductCartDetail->delete()) { + $objCart = new Cart($objRoomTypeServiceProductOrderDetail->id_cart); + $objCart->updateQty((int)abs($quantity), $objRoomTypeServiceProductOrderDetail->id_product, null, false, 'down'); + } + } + } $order = new Order($objRoomTypeServiceProductOrderDetail->id_order); if ($quantity >= $objOrderDetail->product_quantity) { $objOrderDetail->delete(); @@ -6705,12 +6892,12 @@ class AdminOrdersControllerCore extends AdminController $unitPriceTaxExcl = 0; foreach ($productList as &$product) { // This is used to get the actual quanity of the service as it is calculated incorrectly if the service is per night - if ($id_room_type_service_product_cart_detail = $objRoomTypeServiceProductCartDetail->alreadyExists( + if ($idRoomTypServiceProductCartDetail = $objRoomTypeServiceProductCartDetail->alreadyExists( $service['id'], $cart->id, $roomHtlCartInfo['id']) ) { - $objRoomTypeServiceProductCartDetail = new RoomTypeServiceProductCartDetail((int) $id_room_type_service_product_cart_detail); + $objRoomTypeServiceProductCartDetail = new RoomTypeServiceProductCartDetail((int) $idRoomTypServiceProductCartDetail); $unitPriceTaxExcl = $objRoomTypeServiceProductPrice->getServicePrice( (int)$product['id_product'], @@ -7131,6 +7318,17 @@ class AdminOrdersControllerCore extends AdminController $this->errors[] = Tools::displayError('Date should be between booking from date and to date.'); } } + + if ($objHotelBookingDetail->id_status == HotelBookingDetail::STATUS_CHECKED_OUT + && (date('Y-m-d', strtotime($objHotelBookingDetail->check_out)) != date('Y-m-d', strtotime($objHotelBookingDetail->date_to))) + && ($booking = $objHotelBookingDetail->chechRoomBooked($objHotelBookingDetail->id_room, $objHotelBookingDetail->check_out, $objHotelBookingDetail->date_to)) + ) { + if ($booking['id_status'] != HotelBookingDetail::STATUS_CHECKED_OUT + || date('Y-m-d', strtotime($booking['check_out'])) > date('Y-m-d', strtotime($objHotelBookingDetail->date_from)) + ) { + $this->errors[] = Tools::displayError('You cannot update this room\'s booking status as a new booking has been created for this room. Please change the room to update the status.'); + } + } if ($newStatus == HotelBookingDetail::STATUS_CHECKED_OUT) { if ($objHotelBookingDetail->check_in == '0000-00-00 00:00:00') { $this->errors[] = Tools::displayError('Room status must be set to Check-In before setting the room status to Check-Out.'); @@ -7196,6 +7394,13 @@ class AdminOrdersControllerCore extends AdminController // set context currency So that we can get prices in the order currency $objOrder = new Order($objHotelBooking->id_order); $this->context->currency = new Currency($objOrder->id_currency); + $occupancy = array( + array( + 'adults' => $objHotelBooking->adults, + 'children' => $objHotelBooking->children, + 'child_ages' => json_decode($objHotelBooking->child_ages) + ) + ); $newRoomTotalPrice = HotelRoomTypeFeaturePricing::getRoomTypeTotalPrice( $idNewRoomType, $objHotelBooking->date_from, diff --git a/controllers/admin/AdminProductsController.php b/controllers/admin/AdminProductsController.php index 4fb551c0b..7f7a473b9 100644 --- a/controllers/admin/AdminProductsController.php +++ b/controllers/admin/AdminProductsController.php @@ -201,7 +201,13 @@ class AdminProductsControllerCore extends AdminController LEFT JOIN `'._DB_PREFIX_.'address` aa ON (aa.`id_hotel` = hb.`id`) LEFT JOIN `'._DB_PREFIX_.'feature_product` fp ON (fp.`id_product` = a.`id_product`) LEFT JOIN `'._DB_PREFIX_.'htl_room_type_demand` hrtd ON (hrtd.`id_product` = a.`id_product`) - LEFT JOIN `'._DB_PREFIX_.'htl_room_type_service_product` hrtsp ON ((hrtsp.`element_type` = '.(int) RoomTypeServiceProduct::WK_ELEMENT_TYPE_HOTEL.' AND hrtsp.`id_element` = hrt.`id_hotel`) OR (hrtsp.`element_type` = '.(int) RoomTypeServiceProduct::WK_ELEMENT_TYPE_ROOM_TYPE.' AND hrtsp.`id_element` = a.`id_product`)) + LEFT JOIN ( + SELECT rsp.*, GROUP_CONCAT(pl.`name`) AS service_products + FROM `'._DB_PREFIX_.'htl_room_type_service_product` rsp + LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (pl.`id_product` = rsp.`id_product`) + WHERE pl.`id_lang`='.$this->context->language->id.' + GROUP BY rsp.`id_element`) + AS hrtsp ON ((hrtsp.`element_type` = '.(int) RoomTypeServiceProduct::WK_ELEMENT_TYPE_HOTEL.' AND hrtsp.`id_element` = hrt.`id_hotel`) OR (hrtsp.`element_type` = '.(int) RoomTypeServiceProduct::WK_ELEMENT_TYPE_ROOM_TYPE.' AND hrtsp.`id_element` = a.`id_product`)) LEFT JOIN `'._DB_PREFIX_.'htl_advance_payment` hap ON (hap.`id_product` = a.`id_product`)'; $this->_select .= ' a.`show_at_front`, (SELECT COUNT(hri.`id`) FROM `'._DB_PREFIX_.'htl_room_information` hri WHERE hri.`id_product` = a.`id_product`) as num_rooms, '; @@ -213,7 +219,7 @@ class AdminProductsControllerCore extends AdminController if ($join_category) { $this->_join .= ' INNER JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_product` = a.`id_product` AND cp.`id_category` = '.(int)$this->_category->id.') '; - $this->_select .= ' , cp.`position`, '; + $this->_select .= ' , cp.`position` '; } // show the list of the product according to the booking or service products @@ -277,6 +283,13 @@ class AdminProductsControllerCore extends AdminController 'type' => 'range', 'align' => 'center', ); + $this->fields_list['max_guests'] = array( + 'title' => $this->l('Maximum Occupancy'), + 'filter_key' => 'hrt!max_guests', + 'type' => 'range', + 'align' => 'center', + 'optional' => true, + ); // use it for total rooms $this->fields_list['num_rooms'] = array( 'title' => $this->l('Total Rooms'), @@ -290,7 +303,7 @@ class AdminProductsControllerCore extends AdminController 'validation' => 'isFloat', 'align' => 'text-left', 'filter_key' => 'a!price', - 'callback' => 'displayBasePrice', + 'callback' => 'displayPrice', ); $this->fields_list['price_final'] = array( 'title' => $this->l('Final price'), @@ -298,7 +311,8 @@ class AdminProductsControllerCore extends AdminController 'align' => 'text-left', 'havingFilter' => true, 'orderby' => false, - 'search' => false + 'search' => false, + 'callback' => 'displayPrice', ); $this->fields_list['active'] = array( @@ -307,25 +321,18 @@ class AdminProductsControllerCore extends AdminController 'filter_key' => $alias.'!active', 'align' => 'text-center', 'type' => 'select', + 'callback' => 'formatStatusAsLabel', 'list' => array(1 => $this->l('Yes'), 0 => $this->l('No')), 'optional' => true, 'visible_default' => true, 'orderby' => false ); - - $this->fields_list['max_guests'] = array( - 'title' => $this->l('Maximum Occupancy'), - 'filter_key' => 'hrt!max_guests', - 'type' => 'range', - 'align' => 'center', - 'optional' => true, - ); - $this->fields_list['show_at_front'] = array( 'title' => $this->l('Show at front'), 'align' => 'text-center', 'type' => 'bool', 'active' => 'show_at_front', + 'callback' => 'formatStatusAsLabel', 'optional' => true, 'havingFilter' => true, 'visible_default' => true, @@ -335,7 +342,7 @@ class AdminProductsControllerCore extends AdminController if (Configuration::get('WK_ALLOW_ADVANCED_PAYMENT')) { $this->fields_list['advance_payment'] = array( 'title' => $this->l('Advance Payment'), - 'callback' => 'getAdvancePaymentStatus', + 'callback' => 'formatStatusAsLabel', 'badge_success' => true, 'badge_danger' => true, 'align' => 'text-center', @@ -446,7 +453,7 @@ class AdminProductsControllerCore extends AdminController } } - public function getAdvancePaymentStatus($val, $row) + public function formatStatusAsLabel($val, $row) { if ($val) { $str_return = $this->l('Yes'); @@ -457,7 +464,6 @@ class AdminProductsControllerCore extends AdminController return $str_return; } - private function buildCategoryOptions($category) { $space = str_repeat(' ', 5 * (($category['level_depth'] - $this->objLocationsCategory->level_depth) - 1)); @@ -470,7 +476,7 @@ class AdminProductsControllerCore extends AdminController } } - public static function displayBasePrice($basePrice, $tr) + public static function displayPrice($basePrice, $tr) { return Tools::displayPrice($basePrice, (int) Configuration::get('PS_CURRENCY_DEFAULT')); } @@ -629,6 +635,48 @@ class AdminProductsControllerCore extends AdminController $orderBy = 'id_'.$this->table; $orderWay = 'ASC'; } + if ($this->action == 'export' && empty($this->_listsql)) { + $this->_select .= ' , trg.`name` AS `id_tax_rules_group`, `features`, hrtdl.`global_demands`'; + $this->_join .= ' LEFT JOIN `'._DB_PREFIX_.'tax_rules_group` trg + ON trg.`id_tax_rules_group` = a.`id_tax_rules_group` + LEFT JOIN (SELECT GROUP_CONCAT(fpl.`name`) AS features, fp.`id_product` + FROM `'._DB_PREFIX_.'feature_lang` fpl + LEFT JOIN `'._DB_PREFIX_.'feature_product` fp + ON (fp.`id_feature` = fpl.`id_feature`) + WHERE fpl.`id_lang`='.(int) $this->context->language->id.' + GROUP BY fp.`id_product` + ) AS fpl ON (a.`id_product` = fpl.`id_product`)'; + + $this->_join .= ' LEFT JOIN (SELECT hrtgd.`id_product`, `id_lang`, GROUP_CONCAT(`name`) AS `global_demands` + FROM `'._DB_PREFIX_.'htl_room_type_global_demand_lang` hrtgdl + LEFT JOIN `'._DB_PREFIX_.'htl_room_type_demand` hrtgd + ON hrtgd.`id_global_demand` = hrtgdl.`id_global_demand` + WHERE `id_lang`='.(int) $this->context->language->id.' + GROUP BY hrtgd.`id_product` + ) AS hrtdl ON (hrtdl.`id_product` = a.`id_product`)'; + + $this->fields_list = array_merge($this->fields_list, array( + 'id_tax_rules_group' => array( + 'title' => $this->l('Id Tax Rules group'), + 'filter_key' => 'a!id_tax_rules_group', + ), + 'features' => array( + 'title' => $this->l('Features'), + ), + 'service_products' => array( + 'title' => $this->l('Services Products'), + ), + 'global_demands' => array( + 'title' => $this->l('Additional Facilities'), + ) + ) + ); + + unset($this->fields_list['id_category_default']); + unset($this->fields_list['id_global_demand']); + unset($this->fields_list['id_feature']); + unset($this->fields_list['id_service_product']); + } parent::getList($id_lang, $orderBy, $orderWay, $start, $limit, $this->context->shop->id); /* update product quantity with attributes ...*/ diff --git a/controllers/front/CategoryController.php b/controllers/front/CategoryController.php index 10d9a0ae0..1a7caa27f 100644 --- a/controllers/front/CategoryController.php +++ b/controllers/front/CategoryController.php @@ -140,12 +140,15 @@ class CategoryControllerCore extends FrontController $id_category = Tools::getValue('id_category'); + $displayAllRoomsTypes = false; if (!($date_from = Tools::getValue('date_from'))) { $date_from = date('Y-m-d'); $date_to = date('Y-m-d', strtotime($date_from) + 86400); + $displayAllRoomsTypes = true; } if (!($date_to = Tools::getValue('date_to'))) { $date_to = date('Y-m-d', strtotime($date_from) + 86400); + $displayAllRoomsTypes = true; } // get occupancy of the search @@ -156,11 +159,11 @@ class CategoryControllerCore extends FrontController $currency = new Currency($this->context->currency->id); if ($id_hotel = HotelBranchInformation::getHotelIdByIdCategory($id_category)) { - $preparationTime = (int) HotelOrderRestrictDate::getPreparationTime($id_hotel); - if ($preparationTime - && strtotime(date('Y-m-d', strtotime('+'. ($preparationTime) .' days'))) > strtotime($date_from) + $minBookingOffset = (int) HotelOrderRestrictDate::getMinimumBookingOffset($id_hotel); + if ($minBookingOffset + && strtotime(date('Y-m-d', strtotime('+'. ($minBookingOffset) .' days'))) > strtotime($date_from) ) { - $date_from = date('Y-m-d', strtotime('+ '.$preparationTime.' day')); + $date_from = date('Y-m-d', strtotime('+ '.$minBookingOffset.' day')); if (strtotime($date_from) >= strtotime($date_to)) { $date_to = date('Y-m-d', strtotime($date_from) + 86400); } @@ -180,6 +183,10 @@ class CategoryControllerCore extends FrontController 'id_guest' => $id_guest, ); + if ($displayAllRoomsTypes) { + $bookingParams['get_all_room_types'] = 1; + } + $booking_data = $objBookingDetail->dataForFrontSearch($bookingParams); $num_days = $objBookingDetail->getNumberOfDays($date_from, $date_to); @@ -206,7 +213,8 @@ class CategoryControllerCore extends FrontController 'booking_date_to' => $date_to, 'booking_data' => $booking_data, 'max_order_date' => $max_order_date, - 'order_date_restrict' => $order_date_restrict + 'order_date_restrict' => $order_date_restrict, + 'display_all_room_types' => $displayAllRoomsTypes )); } else { Tools::redirect($this->context->link->getPageLink('pagenotfound')); @@ -261,8 +269,18 @@ class CategoryControllerCore extends FrontController $this->display_header = false; $this->display_footer = false; - $date_from = Tools::getValue('date_from'); - $date_to = Tools::getValue('date_to'); + $displayAllRoomsTypes = false; + if (!($date_from = Tools::getValue('date_from'))) { + $date_from = date('Y-m-d H:i:s'); + $date_to = date('Y-m-d H:i:s', strtotime($date_from) + 86400); + $displayAllRoomsTypes = true; + } + + if (!($date_to = Tools::getValue('date_to'))) { + $date_to = date('Y-m-d H:i:s', strtotime($date_from) + 86400); + $displayAllRoomsTypes = true; + } + $htl_id_category = Tools::getValue('id_category'); // occupancy of the search @@ -317,6 +335,10 @@ class CategoryControllerCore extends FrontController 'id_guest' => $this->context->cookie->id_guest, ); + if ($displayAllRoomsTypes) { + $bookingParams['get_all_room_types'] = 1; + } + $booking_data = $objBookingDetail->dataForFrontSearch($bookingParams); // reset array keys from 0 $booking_data['rm_data'] = array_values($booking_data['rm_data']); diff --git a/controllers/front/ProductController.php b/controllers/front/ProductController.php index 049131fb2..06abb11dc 100644 --- a/controllers/front/ProductController.php +++ b/controllers/front/ProductController.php @@ -334,15 +334,15 @@ class ProductControllerCore extends FrontController $date_from = Tools::getValue('date_from'); $date_to = Tools::getValue('date_to'); - $preparationTime = (int) HotelOrderRestrictDate::getPreparationTime($hotel_id); + $minBookingOffset = (int) HotelOrderRestrictDate::getMinimumBookingOffset($hotel_id); if (!($date_from = Tools::getValue('date_from'))) { $date_from = date('Y-m-d'); } - if ($preparationTime - && strtotime(date('Y-m-d', strtotime('+'. ($preparationTime) .' days'))) > strtotime($date_from) + if ($minBookingOffset + && strtotime(date('Y-m-d', strtotime('+'. ($minBookingOffset) .' days'))) > strtotime($date_from) ) { - $date_from = date('Y-m-d', strtotime('+ '.$preparationTime.' day')); + $date_from = date('Y-m-d', strtotime('+ '.$minBookingOffset.' day')); } if (!($date_to = Tools::getValue('date_to'))) { @@ -401,7 +401,7 @@ class ProductControllerCore extends FrontController 'room_type_info' => $room_info_by_product_id, 'isHotelRefundable' => $hotel_branch_obj->isRefundable(), 'max_order_date' => $max_order_date, - 'preparation_time' => $preparationTime, + 'min_booking_offset' => $minBookingOffset, 'warning_num' => Configuration::get('WK_ROOM_LEFT_WARNING_NUMBER'), 'ratting_img_path' => _MODULE_DIR_.'hotelreservationsystem/views/img/Slices/icons-sprite.png', 'product_controller_url' => $this->context->link->getPageLink('product'), @@ -430,7 +430,7 @@ class ProductControllerCore extends FrontController ) ); - $occupancy_value = array(); + $occupancy_value = Tools::getValue('occupancy', array()); if (Configuration::get('PS_FRONT_ROOM_UNIT_SELECTION_TYPE') == HotelBookingDetail::PS_ROOM_UNIT_SELECTION_TYPE_QUANTITY) { $occupancy_value = 1; } else { @@ -461,10 +461,10 @@ class ProductControllerCore extends FrontController // product price after imposing feature prices... if ($useTax) { $priceProduct = Product::getPriceStatic($this->product->id, true); - $feature_price = HotelRoomTypeFeaturePricing::getRoomTypeFeaturePricesPerDay($this->product->id, $date_from, $date_to, true); + $feature_price = HotelRoomTypeFeaturePricing::getRoomTypeFeaturePricesPerDay($this->product->id, $date_from, $date_to, true, 0, 0, 0, 0, 1, 1, $occupancy_value); } else { $priceProduct = Product::getPriceStatic($this->product->id, false); - $feature_price = HotelRoomTypeFeaturePricing::getRoomTypeFeaturePricesPerDay($this->product->id, $date_from, $date_to, false); + $feature_price = HotelRoomTypeFeaturePricing::getRoomTypeFeaturePricesPerDay($this->product->id, $date_from, $date_to, false, 0, 0, 0, 0, 1, 1, $occupancy_value); } $productPriceWithoutReduction = $this->product->getPriceWithoutReduct(!$useTax); $feature_price_diff = (float)($productPriceWithoutReduction - $feature_price); @@ -660,7 +660,7 @@ class ProductControllerCore extends FrontController $idProduct, $dateFrom, $dateTo, - 0, + $occupancy, 0, 0, 0, @@ -671,7 +671,8 @@ class ProductControllerCore extends FrontController $roomTypeDateRangePrice = HotelRoomTypeFeaturePricing::getRoomTypeTotalPrice( $idProduct, $dateFrom, - $dateTo + $dateTo, + $occupancy ); $featurePrice = 0; @@ -680,7 +681,14 @@ class ProductControllerCore extends FrontController $idProduct, $dateFrom, $dateTo, - true + true, + 0, + 0, + 0, + 0, + 1, + 1, + $occupancy ); $roomTypeDateRangePrice = $roomTypeDateRangePrice['total_price_tax_incl']; $totalPriceWithoutDiscount = $priceWithoutDiscount['total_price_tax_incl']; @@ -690,14 +698,20 @@ class ProductControllerCore extends FrontController $idProduct, $dateFrom, $dateTo, - false + false, + 0, + 0, + 0, + 0, + 1, + 1, + $occupancy ); $roomTypeDateRangePrice = $roomTypeDateRangePrice['total_price_tax_excl']; $totalPriceWithoutDiscount = $priceWithoutDiscount['total_price_tax_excl']; } - $totalPriceWithoutDiscount *= $quantity; - $totalRoomPrice = $roomTypeDateRangePrice * $quantity; + $totalRoomPrice = $roomTypeDateRangePrice; // calculate demand price now $demandsPricePerRoom = 0; $roomTypeDemands = $objHRTDemand->getRoomTypeDemands($idProduct); diff --git a/docs/csv_import/hotels_import.csv b/docs/csv_import/hotels_import.csv index 5225073f8..f3c5962fa 100644 --- a/docs/csv_import/hotels_import.csv +++ b/docs/csv_import/hotels_import.csv @@ -1,3 +1,3 @@ -Hotel ID;Active(0/1);Hotel Name;Short Description;Description;Mobile Phone;Email;Address;Rating;Check-In;Check-Out;Country ID;State ID;City;Zip Code;Hotel Policies;Allow Refund(0/1);Refund IDs (x,y,z...);Max Order Date;Prepration Time;Image URLs (x,y,z...);Delete Existing Images (0 = No, 1 = Yes) +Hotel ID;Active(0/1);Hotel Name;Short Description;Description;Mobile Phone;Email;Address;Rating;Check-In;Check-Out;Country ID;State ID;City;Zip Code;Hotel Policies;Allow Refund(0/1);Refund IDs (x,y,z...);Max booking offset;Min booking offset;Image URLs (x,y,z...);Delete Existing Images (0 = No, 1 = Yes) 2;1;The Kings Hotel;The Kings Hotel with king size rooms. visit for a wonderful experience.;The Kings Hotel with king-size rooms. visit for a wonderful experience.;0900000009;kingshotel@demo.com;Greene St, New York, NY 10003, USA;3;12:00;11:00;21;32;New York;10003;1. intelligentsia tattooed pop-up salvia asymmetrical mixtape meggings tousled ramps VHS cred.2. intelligentsia tattooed pop-up salvia asymmetrical mixtape meggings tousled ramps VHS cred.;1;1;2024-01-01;0;http://localhost/hotelcommerce/modules/hotelreservationsystem/views/img/hotel_img/1/1.jpg;0 3;1;The Sunshine Palace Inn;The Sunshine Palace Inn is a beautiful hotel in japan.;The Sunshine Palace Inn is a beautiful hotel in japan.;0900000009;sunshine@demo.com;Shingashi, Itabashi, Tokyo;4;09:00;08:00;11;306;Tokyo;611-0043;1.loremipsertmkjbg ag mixtape meggings tousled ramps VHS cred.;0;0;;3;http://localhost/hotelcommerce/modules/hotelreservationsystem/views/img/hotel_img/1/2.jpg,http://localhost/hotelcommerce/modules/hotelreservationsystem/views/img/hotel_img/1/3.jpg;0 diff --git a/modules/blockcart/blockcart.php b/modules/blockcart/blockcart.php index 32033875c..cda227fd6 100644 --- a/modules/blockcart/blockcart.php +++ b/modules/blockcart/blockcart.php @@ -241,7 +241,7 @@ class Blockcart extends Module $objProduct->id, $addedProduct['date_from'], $addedProduct['date_to'], - $addedProduct['req_rm'] + $addedProduct['occupancy'] ); if ($priceDisplayMethod == PS_TAX_EXC) { $addedProduct['price'] = Tools::displayPrice($price['total_price_tax_excl']); diff --git a/modules/dashguestcycle/views/templates/hook/dashboard-zone-two.tpl b/modules/dashguestcycle/views/templates/hook/dashboard-zone-two.tpl index abc0a402c..8c3cbc0be 100644 --- a/modules/dashguestcycle/views/templates/hook/dashboard-zone-two.tpl +++ b/modules/dashguestcycle/views/templates/hook/dashboard-zone-two.tpl @@ -27,6 +27,7 @@ + {hook h='displayDashGuestCycleHeader'}
diff --git a/modules/hotelreservationsystem/classes/HotelAdvancedPayment.php b/modules/hotelreservationsystem/classes/HotelAdvancedPayment.php index 076663010..b2702b310 100644 --- a/modules/hotelreservationsystem/classes/HotelAdvancedPayment.php +++ b/modules/hotelreservationsystem/classes/HotelAdvancedPayment.php @@ -105,11 +105,18 @@ class HotelAdvancedPayment extends ObjectModel $objHtlCartBook = new HotelCartBookingData(); if ($roomTypesByIdProduct = $objHtlCartBook->getCartInfoIdCartIdProduct((int) $idCart, (int)$idProduct)) { foreach ($roomTypesByIdProduct as $cartRoomInfo) { + $occupancy = array( + array( + 'adults' => $cartRoomInfo['adults'], + 'children' => $cartRoomInfo['children'], + 'child_ages' => json_decode($cartRoomInfo['child_ages']) + ) + ); $roomTotalPrices = HotelRoomTypeFeaturePricing::getRoomTypeTotalPrice( $cartRoomInfo['id_product'], $cartRoomInfo['date_from'], $cartRoomInfo['date_to'], - 0, + $occupancy, 0, $idCart, $cartRoomInfo['id_guest'], diff --git a/modules/hotelreservationsystem/classes/HotelBookingDetail.php b/modules/hotelreservationsystem/classes/HotelBookingDetail.php index f63d25a46..811bc9b69 100644 --- a/modules/hotelreservationsystem/classes/HotelBookingDetail.php +++ b/modules/hotelreservationsystem/classes/HotelBookingDetail.php @@ -1421,7 +1421,8 @@ class HotelBookingDetail extends ObjectModel // This function algo is same as available rooms algo and it not similar to booked rooms algo. public function chechRoomBooked($id_room, $date_from, $date_to) { - $sql = 'SELECT `id`, `id_product`, `id_order`, `id_cart`, `id_room`, `id_hotel`, `id_customer` + $sql = 'SELECT `id`, `id_product`, `id_order`, `id_cart`, `id_room`, `id_hotel`, `id_customer`, + `check_out`, `check_in`, `id_status` FROM `'._DB_PREFIX_.'htl_booking_detail` WHERE `id_room` = '.(int)$id_room. ' AND `is_back_order` = 0 AND `is_refunded` = 0 AND ((date_from <= \''.pSQL($date_from).'\' AND date_to > \''. pSQL($date_from).'\' AND date_to <= \''.pSQL($date_to).'\') OR (date_from > \''.pSQL($date_from). @@ -1429,6 +1430,12 @@ class HotelBookingDetail extends ObjectModel pSQL($date_to).'\' AND date_to >= \''.pSQL($date_to).'\') OR (date_from < \''.pSQL($date_from). '\' AND date_to > \''.pSQL($date_to).'\'))'; + if ($this->id) { + $sql .= ' AND `id` !='.(int) $this->id; + } + + $sql .= ' ORDER BY `date_add` DESC'; + return Db::getInstance()->getRow($sql); } @@ -1681,8 +1688,6 @@ class HotelBookingDetail extends ObjectModel if (!$only_search_data) { if (!empty($bookingData)) { - $objRoomType = new HotelRoomType(); - foreach ($bookingData['rm_data'] as $key => $value) { $product_feature = Product::getFrontFeaturesStatic($this->context->language->id, $value['id_product']); $prod_amen = array(); @@ -1701,14 +1706,15 @@ class HotelBookingDetail extends ObjectModel continue; } } - $productFeaturePrice = HotelRoomTypeFeaturePricing::getRoomTypeFeaturePricesPerDay($value['id_product'], $date_from, $date_to, self::useTax()); + $productFeaturePrice = HotelRoomTypeFeaturePricing::getRoomTypeFeaturePricesPerDay($value['id_product'], $date_from, $date_to, self::useTax(), 0, 0, 0, 0, 1, 1, $bookingParams['occupancy']); if (!empty($price) && ($price['from'] > $productFeaturePrice || $price['to'] < $productFeaturePrice)) { unset($bookingData['rm_data'][$key]); continue; } - if (count($value['data']['available'])) { + + if (count($value['data']['available']) || (isset($get_all_room_types) && $get_all_room_types)) { $prod_price = Product::getPriceStatic($value['id_product'], self::useTax()); - $productPriceWithoutReduction = HotelRoomTypeFeaturePricing::getRoomTypeFeaturePricesPerDay($value['id_product'], $date_from, $date_to, self::useTax(), 0, 0, 0, 0, 1, 0); + $productPriceWithoutReduction = HotelRoomTypeFeaturePricing::getRoomTypeFeaturePricesPerDay($value['id_product'], $date_from, $date_to, self::useTax(), 0, 0, 0, 0, 1, 0, $bookingParams['occupancy']); $cover_image_arr = Product::getCover($value['id_product']); if (!empty($cover_image_arr)) { $cover_img = $this->context->link->getImageLink($value['link_rewrite'], $value['id_product'].'-'.$cover_image_arr['id_image'], 'home_default'); @@ -2064,11 +2070,19 @@ class HotelBookingDetail extends ObjectModel $objBookingDetail->children = $objCartBookingData->children; $objBookingDetail->child_ages = $objCartBookingData->child_ages; + $occupancy = array( + array( + 'adults' => $objCartBookingData->adults, + 'children' => $objCartBookingData->children, + 'child_ages' => json_decode($objCartBookingData->child_ages) + ) + ); + $totalRoomTypePrice = HotelRoomTypeFeaturePricing::getRoomTypeTotalPrice( $idNewRoomType, $objCartBookingData->date_from, $objCartBookingData->date_to, - 0, + $occupancy, Group::getCurrent()->id, $this->context->cart->id, $this->context->cookie->id_guest, @@ -2519,10 +2533,13 @@ class HotelBookingDetail extends ObjectModel $new_date_from, $new_date_to ) { - $sql = 'SELECT * FROM `'._DB_PREFIX_.'htl_booking_detail` WHERE `id_room`='.(int)$id_room. - ' AND `date_from` < \''.pSQL($new_date_to).'\' AND `date_to` > \''.pSQL($new_date_from). - '\' AND `date_from` != \''.pSQL($old_date_from).'\' AND `date_to` != \''.pSQL($old_date_to). - '\' AND `is_refunded`=0 AND `is_back_order`=0'; + $sql = 'SELECT * FROM `'._DB_PREFIX_.'htl_booking_detail` WHERE `id_room`='.(int)$id_room.' + AND `date_from` < \''.pSQL($new_date_to).'\' AND `date_from` != \''.pSQL($old_date_from).'\' + AND IF(`id_status` !='.HotelBookingDetail::STATUS_CHECKED_OUT.', + `date_to` != \''.pSQL($old_date_to).'\' AND `date_to` > \''.pSQL($new_date_from).'\', + `check_out` != \''.pSQL($old_date_to).'\' AND `check_out` > \''.pSQL($new_date_from).'\' + ) + AND `is_refunded`=0 AND `is_back_order`=0'; return Db::getInstance()->executeS($sql); } diff --git a/modules/hotelreservationsystem/classes/HotelBranchInformation.php b/modules/hotelreservationsystem/classes/HotelBranchInformation.php index 172ed2e61..8c376814e 100644 --- a/modules/hotelreservationsystem/classes/HotelBranchInformation.php +++ b/modules/hotelreservationsystem/classes/HotelBranchInformation.php @@ -71,10 +71,10 @@ class HotelBranchInformation extends ObjectModel public $zipcode; public $address; public $phone; - public $use_global_max_order_date = 1; - public $max_order_date = '0000-00-00'; - public $use_global_preparation_time = 1; - public $preparation_time = '0000-00-00'; + public $use_global_max_checkout_offset = 1; + public $max_checkout_offset = '1000'; + public $use_global_min_booking_offset = 1; + public $min_booking_offset = '0'; protected $webserviceParameters = array( 'objectsNodeName' => 'hotels', @@ -106,10 +106,10 @@ class HotelBranchInformation extends ObjectModel 'subResourceName' => 'hotels' ) ), - 'use_global_max_order_date' => array(), - 'max_order_date' => array(), - 'use_global_preparation_time' => array(), - 'preparation_time' => array(), + 'use_global_max_checkout_offset' => array(), + 'max_checkout_offset' => array(), + 'use_global_min_booking_offset' => array(), + 'min_booking_offset' => array(), ), 'associations' => array( 'room_types' => array( @@ -149,10 +149,10 @@ class HotelBranchInformation extends ObjectModel } if ($hotelRestrictions = HotelOrderRestrictDate::getDataByHotelId($id)) { - $this->use_global_max_order_date = $hotelRestrictions['use_global_max_order_date']; - $this->max_order_date = $hotelRestrictions['max_order_date']; - $this->use_global_preparation_time = $hotelRestrictions['use_global_preparation_time']; - $this->preparation_time = $hotelRestrictions['preparation_time']; + $this->use_global_max_checkout_offset = $hotelRestrictions['use_global_max_checkout_offset']; + $this->max_checkout_offset = $hotelRestrictions['max_checkout_offset']; + $this->use_global_min_booking_offset = $hotelRestrictions['use_global_min_booking_offset']; + $this->min_booking_offset = $hotelRestrictions['min_booking_offset']; } } } @@ -527,9 +527,17 @@ class HotelBranchInformation extends ObjectModel */ public static function getHotelIdByIdCategory($id_category) { - return Db::getInstance()->getValue( - 'SELECT `id` FROM `'._DB_PREFIX_.'htl_branch_info` WHERE id_category = '.(int)$id_category - ); + $cache_key = 'HotelBranchInformation::getHotelIdByIdCategory'.(int)$id_category; + if (!Cache::isStored($cache_key)) { + $res = Db::getInstance()->getValue( + 'SELECT `id` FROM `'._DB_PREFIX_.'htl_branch_info` WHERE id_category = '.(int)$id_category + ); + Cache::store($cache_key, $res); + } else { + $res = Cache::retrieve($cache_key); + } + + return $res; } /** @@ -1064,7 +1072,7 @@ class HotelBranchInformation extends ObjectModel public function setWsHotelRestrictions() { if ($this->id) { - // save maximum booking date and preparation time + // save Maximum checkout offset and min booking offset if ($restrictDateInfo = HotelOrderRestrictDate::getDataByHotelId($this->id)) { $objHotelRestrictDate = new HotelOrderRestrictDate($restrictDateInfo['id']); } else { @@ -1072,13 +1080,13 @@ class HotelBranchInformation extends ObjectModel } $objHotelRestrictDate->id_hotel = $this->id; - $objHotelRestrictDate->use_global_max_order_date = $this->use_global_max_order_date; - if (!$this->use_global_max_order_date) { - $objHotelRestrictDate->max_order_date = $this->max_order_date; + $objHotelRestrictDate->use_global_max_checkout_offset = $this->use_global_max_checkout_offset; + if (!$this->use_global_max_checkout_offset) { + $objHotelRestrictDate->max_checkout_offset = $this->max_checkout_offset; } - $objHotelRestrictDate->use_global_preparation_time = $this->use_global_preparation_time; - if (!$this->use_global_preparation_time) { - $objHotelRestrictDate->preparation_time = $this->preparation_time; + $objHotelRestrictDate->use_global_min_booking_offset = $this->use_global_min_booking_offset; + if (!$this->use_global_min_booking_offset) { + $objHotelRestrictDate->min_booking_offset = $this->min_booking_offset; } return $objHotelRestrictDate->save(); @@ -1111,23 +1119,34 @@ class HotelBranchInformation extends ObjectModel $message = Tools::displayError('City is required field.'); } elseif (!Validate::isCityName($this->city)) { $message = Tools::displayError('Enter a Valid City Name.'); - } elseif (!Validate::isBool($this->use_global_max_order_date)) { - $message = Tools::displayError('invalid value for use_global_max_order_date.'); - } elseif (!Validate::isBool($this->use_global_preparation_time)) { - $message = Tools::displayError('invalid value for use_global_preparation_time.'); - } elseif (!$this->use_global_max_order_date && $this->max_order_date == '') { - $message = Tools::displayError('Maximum date to book a room is required.'); - } elseif (!$this->use_global_max_order_date && !Validate::isDate($this->max_order_date)) { - $message = Tools::displayError('Maximum date to book a room is invalid.'); - } elseif (!$this->use_global_max_order_date - && ($maxOrderDateFormatted = date('Y-m-d', strtotime($this->max_order_date))) - && strtotime($maxOrderDateFormatted) < strtotime(date('Y-m-d')) - ) { - $message = Tools::displayError('Maximum Global Date to book a room can not be a past date. Please use a future date.'); - } elseif (!$this->use_global_preparation_time && $this->preparation_time === '') { + } elseif (!Validate::isBool($this->use_global_max_checkout_offset)) { + $message = Tools::displayError('invalid value for use global max checkout offset.'); + } elseif (!Validate::isBool($this->use_global_min_booking_offset)) { + $message = Tools::displayError('invalid value for use global min booking offset.'); + } elseif (!$this->use_global_max_checkout_offset && $this->max_checkout_offset == '') { + $message = Tools::displayError('Maximum checkout offset is required.'); + } elseif (!$this->use_global_max_checkout_offset && (!$this->max_checkout_offset || !Validate::isUnsignedInt($this->max_checkout_offset))) { + $message = Tools::displayError('Maximum checkout offset is invalid.'); + } elseif (!$this->use_global_min_booking_offset && $this->min_booking_offset === '') { $message = Tools::displayError('Minimum booking offset is a required.'); - } elseif (!$this->use_global_preparation_time && $this->preparation_time !== '0' && !Validate::isUnsignedInt($this->preparation_time)) { + } elseif (!$this->use_global_min_booking_offset && !Validate::isUnsignedInt($this->min_booking_offset)) { $message = Tools::displayError('Minimum booking offset is invalid.'); + } else if (!$this->use_global_min_booking_offset + && !$this->use_global_max_checkout_offset + && $this->max_checkout_offset + && $this->max_checkout_offset <= $this->min_booking_offset + ) { + $message = Tools::displayError('Maximum checkout offset cannot be less than or equal to Minimum booking offset.'); + } else if (!$this->use_global_max_checkout_offset + && $this->use_global_min_booking_offset + && $this->max_checkout_offset <= Configuration::get('PS_MIN_BOOKING_OFFSET') + ) { + $message = Tools::displayError('Maximum checkout offset cannot be less than or equal to Global Minimum booking offset.'); + } else if ($this->use_global_max_checkout_offset + && !$this->use_global_min_booking_offset + && $this->min_booking_offset >= Configuration::get('PS_MAX_CHECKOUT_OFFSET') + ) { + $message = Tools::displayError('Minimum booking offset cannot be be greater than or equal to Global Maximum checkout offset.'); } elseif (!Validate::isLoadedObject($objCountry = new Country($this->id_country))) { $message = Tools::displayError('country is invalid.'); } elseif ($this->id_state diff --git a/modules/hotelreservationsystem/classes/HotelCartBookingData.php b/modules/hotelreservationsystem/classes/HotelCartBookingData.php index 7ad74427a..905883d1e 100644 --- a/modules/hotelreservationsystem/classes/HotelCartBookingData.php +++ b/modules/hotelreservationsystem/classes/HotelCartBookingData.php @@ -346,7 +346,8 @@ class HotelCartBookingData extends ObjectModel $idRoom = 0, $dateFrom = 0, $dateTo = 0, - $updPsCart = 1 + $updPsCart = 1, + $idOrder = 0 ) { $where = '1'; if ($idCart) { @@ -364,8 +365,8 @@ class HotelCartBookingData extends ObjectModel if ($dateTo) { $where .= ' AND `date_to`=\''.pSQL($dateTo).'\''; } - // we have to delete only rows which order is not created - $where .= ' AND `id_order`= 0'; + + $where .= ' AND `id_order`='.(int) $idOrder; // If rooms is deleting from cart the we need to delete the ps_cart quantity of the product from table // if product will delete the prestashop will handle $numRooms = 0; @@ -1029,9 +1030,9 @@ class HotelCartBookingData extends ObjectModel } } - $preparationTime = HotelOrderRestrictDate::getPreparationTime($roomData['id_hotel']); - if ($preparationTime !== false) { - $minOrderDate = date('Y-m-d', strtotime('+'. ($preparationTime) .' days')); + $minBookingOffset = HotelOrderRestrictDate::getMinimumBookingOffset($roomData['id_hotel']); + if ($minBookingOffset !== false) { + $minOrderDate = date('Y-m-d', strtotime('+'. ($minBookingOffset) .' days')); if (strtotime($minOrderDate) > strtotime($roomData['date_from'])) { $objHotelBranchInformation = new HotelBranchInformation( $roomData['id_hotel'], @@ -1078,6 +1079,8 @@ class HotelCartBookingData extends ObjectModel } } + Hook::exec('actionCartBookingsErrorsModifier', array('errors' => &$errors)); + return $errors; } @@ -1112,7 +1115,13 @@ class HotelCartBookingData extends ObjectModel $cart_detail_data[$key]['date_to'] = $value['date_to']; $cart_detail_data[$key]['child_ages'] = json_decode($value['child_ages']); - + $occupancy = array( + array( + 'adults' => $value['adults'], + 'children' => $value['children'], + 'child_ages' => json_decode($value['child_ages']) + ) + ); $unit_price = Product::getPriceStatic($value['id_product'], true); $unit_price_tax_excl = Product::getPriceStatic($value['id_product'], false); $productPriceWithoutReduction = $productObj->getPriceWithoutReduct(false); @@ -1125,7 +1134,9 @@ class HotelCartBookingData extends ObjectModel $id_cart, $value['id_guest'], $value['id_room'], - 0 + 0, + 1, + $occupancy ); $feature_price_tax_excl = HotelRoomTypeFeaturePricing::getRoomTypeFeaturePricesPerDay( $value['id_product'], @@ -1136,7 +1147,9 @@ class HotelCartBookingData extends ObjectModel $id_cart, $value['id_guest'], $value['id_room'], - 0 + 0, + 1, + $occupancy ); $feature_price_diff = (float)($productPriceWithoutReduction - $feature_price); $cart_detail_data[$key]['product_price'] = $unit_price; @@ -1238,7 +1251,7 @@ class HotelCartBookingData extends ObjectModel $value['id_product'], $value['date_from'], $value['date_to'], - 0, + $occupancy, 0, $id_cart, $value['id_guest'], @@ -1331,13 +1344,23 @@ class HotelCartBookingData extends ObjectModel */ public function getCartInfoIdCartIdProduct($id_cart, $id_product, $date_from = false, $date_to = false) { - $sql = 'SELECT * - FROM `'._DB_PREFIX_.'htl_cart_booking_data` - WHERE `id_cart`='.(int) $id_cart.' AND `id_product`='.(int) $id_product; - if ($date_from && $date_to) { - $sql .= ' AND `date_from` = \''.pSQL($date_from).'\' AND `date_to` = \''.pSQL($date_to).'\''; + $cache_key = 'HotelCartBookingData::getCartInfoIdCartIdProduct_'.(int)$id_cart.'_'.(int)$id_product.'_'.($date_from ? strtotime($date_from) : 'null').'_'.($date_to ? strtotime($date_to) : 'null'); + if (!Cache::isStored($cache_key)) { + $sql = 'SELECT * + FROM `'._DB_PREFIX_.'htl_cart_booking_data` + WHERE `id_cart`='.(int) $id_cart.' AND `id_product`='.(int) $id_product; + if ($date_from && $date_to) { + $sql .= ' AND `date_from` = \''.pSQL($date_from).'\' AND `date_to` = \''.pSQL($date_to).'\''; + } + + $res = Db::getInstance()->executeS($sql); + + Cache::store($cache_key, $res); + } else { + $res = Cache::retrieve($cache_key); } - return Db::getInstance()->executeS($sql); + + return $res; } /** @@ -1556,7 +1579,13 @@ class HotelCartBookingData extends ObjectModel 1 ); $totalAdditionalServicePrice = $demandPrice + $serviceProductPrice; - + $occupancy = array( + array( + 'adults' => $data_v['adults'], + 'children' => $data_v['children'], + 'child_ages' => json_decode($data_v['child_ages']) + ) + ); if (isset($cartHotelData[$prodKey]['date_diff'][$dateJoin])) { $numDays = $objBookingDetail->getNumberOfDays($data_v['date_from'], $data_v['date_to']); $cartHotelData[$prodKey]['date_diff'][$dateJoin]['demand_price'] += $totalAdditionalServicePrice; @@ -1572,7 +1601,7 @@ class HotelCartBookingData extends ObjectModel $product['id_product'], $data_v['date_from'], $data_v['date_to'], - 0, + $occupancy, 0, $context->cart->id, $context->cart->id_guest, @@ -1582,7 +1611,7 @@ class HotelCartBookingData extends ObjectModel $product['id_product'], $data_v['date_from'], $data_v['date_to'], - 0, + $occupancy, 0, $context->cart->id, $context->cart->id_guest, @@ -1593,7 +1622,7 @@ class HotelCartBookingData extends ObjectModel $product['id_product'], $data_v['date_from'], $data_v['date_to'], - 0, + $occupancy, 0, $context->cart->id, $context->cart->id_guest, @@ -1634,7 +1663,7 @@ class HotelCartBookingData extends ObjectModel $product['id_product'], $data_v['date_from'], $data_v['date_to'], - 0, + $occupancy, 0, $context->cart->id, $context->cart->id_guest, @@ -1644,7 +1673,7 @@ class HotelCartBookingData extends ObjectModel $product['id_product'], $data_v['date_from'], $data_v['date_to'], - 0, + $occupancy, 0, $context->cart->id, $context->cart->id_guest, @@ -1655,7 +1684,7 @@ class HotelCartBookingData extends ObjectModel $product['id_product'], $data_v['date_from'], $data_v['date_to'], - 0, + $occupancy, 0, $context->cart->id, $context->cart->id_guest, diff --git a/modules/hotelreservationsystem/classes/HotelHelper.php b/modules/hotelreservationsystem/classes/HotelHelper.php index 7182faf92..8ae1bb792 100644 --- a/modules/hotelreservationsystem/classes/HotelHelper.php +++ b/modules/hotelreservationsystem/classes/HotelHelper.php @@ -1063,12 +1063,8 @@ class HotelHelper Configuration::updateValue('WK_GLOBAL_CHILD_MAX_AGE', 15); Configuration::updateValue('WK_GLOBAL_MAX_CHILD_IN_ROOM', 0); - Configuration::updateValue( - 'MAX_GLOBAL_BOOKING_DATE', - date('Y-m-d', strtotime(date('Y-m-d', time()).' + 1 year')) - ); - - Configuration::updateValue('GLOBAL_PREPARATION_TIME', 0); + Configuration::updateValue('PS_MAX_CHECKOUT_OFFSET', 365); + Configuration::updateValue('PS_MIN_BOOKING_OFFSET', 0); Configuration::updateValue('HTL_FEATURE_PRICING_PRIORITY', 'specific_date;special_day;date_range'); Configuration::updateValue('WK_GOOGLE_ACTIVE_MAP', 0); @@ -2499,19 +2495,30 @@ class HotelHelper $startDate = new DateTime($dateFrom); $endDate = new DateTime($dateTo); $daysDifference = $startDate->diff($endDate)->days; + Hook::exec('actionDatesDifferenceModifier', array('date_from'=> $dateFrom, 'date_to'=> $dateTo, 'days_difference'=> &$daysDifference)); return $daysDifference; } + /** + * Validate the date range for a hotel booking. + * + * @param string $dateFrom Start date (format: 'Y-m-d H:i:s') + * @param string $dateTo End date (format: 'Y-m-d H:i:s') + * @param int $idHotel Hotel ID + * @return bool True if the date range is valid, otherwise false + */ public static function validateDateRangeForHotel($dateFrom, $dateTo, $idHotel) { $validStartDateTimeStamp = strtotime(date('Y-m-d')); - if ($preparationTime = (int) HotelOrderRestrictDate::getPreparationTime($idHotel)) { - $validStartDateTimeStamp = strtotime(date('Y-m-d', strtotime('+ '.$preparationTime.' day'))); + if ($minBookingOffset = (int) HotelOrderRestrictDate::getMinimumBookingOffset($idHotel)) { + $validStartDateTimeStamp = strtotime('+ '.$minBookingOffset.' day', $validStartDateTimeStamp); } + $maxOrderDateTimestamp = strtotime(HotelOrderRestrictDate::getMaxOrderDate($idHotel)); $dateFromTimestamp = strtotime($dateFrom); $dateToTimestamp = strtotime($dateTo); + $isValid = true; if ($dateFrom != '' && ($dateFromTimestamp === false || ($dateFromTimestamp < $validStartDateTimeStamp))) { $isValid = false; @@ -2519,6 +2526,8 @@ class HotelHelper $isValid = false; } else if ($dateTo != '' && $dateFrom != '' && $dateFromTimestamp >= $dateToTimestamp) { $isValid = false; + } else if ($dateToTimestamp > $maxOrderDateTimestamp) { + $isValid = false; } Hook::exec('actionValidateDateRangeForHotel', array( diff --git a/modules/hotelreservationsystem/classes/HotelOrderRestrictDate.php b/modules/hotelreservationsystem/classes/HotelOrderRestrictDate.php index d623d8bf6..20f97c976 100644 --- a/modules/hotelreservationsystem/classes/HotelOrderRestrictDate.php +++ b/modules/hotelreservationsystem/classes/HotelOrderRestrictDate.php @@ -22,10 +22,10 @@ class HotelOrderRestrictDate extends ObjectModel { public $id; public $id_hotel; - public $use_global_max_order_date; - public $max_order_date; - public $use_global_preparation_time; - public $preparation_time; + public $use_global_max_checkout_offset; + public $max_checkout_offset; + public $use_global_min_booking_offset; + public $min_booking_offset; public $date_add; public $date_upd; @@ -34,54 +34,77 @@ class HotelOrderRestrictDate extends ObjectModel 'primary' => 'id', 'fields' => array( 'id_hotel' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), - 'use_global_max_order_date' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'), - 'max_order_date' => array('type' => self::TYPE_DATE, 'validate' => 'isDateFormat'), - 'use_global_preparation_time' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'), - 'preparation_time' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), + 'use_global_max_checkout_offset' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'), + 'max_checkout_offset' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), + 'use_global_min_booking_offset' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'), + 'min_booking_offset' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), 'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'), 'date_upd' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'), ), ); + /** + * @param int $id_hotel + * @return array hote wise restriction. + */ public static function getDataByHotelId($idHotel) { - return Db::getInstance()->getRow( - 'SELECT * FROM `'._DB_PREFIX_.'htl_order_restrict_date` ord WHERE ord.`id_hotel` = '.(int) $idHotel - ); - } - - /*Max date of ordering for order restrict*/ - public static function getMaxOrderDate($idHotel) - { - $result = self::getDataByHotelId($idHotel); - if (is_array($result) && count($result) && !$result['use_global_max_order_date']) { - return $result['max_order_date']; + $cache_key = 'HotelOrderRestrictDate::getDataByHotelId'.(int)$idHotel; + if (!Cache::isStored($cache_key)) { + $res = Db::getInstance()->getRow( + 'SELECT * FROM `'._DB_PREFIX_.'htl_order_restrict_date` ord WHERE ord.`id_hotel` = '.(int) $idHotel + ); + Cache::store($cache_key, $res); + } else { + $res = Cache::retrieve($cache_key); } - if ($globalBookingDate = Configuration::get('MAX_GLOBAL_BOOKING_DATE')) { - return $globalBookingDate; - } - - return 0; + return $res; } /** * @param int $id_hotel - * @return int|false + * @return string Maximum checkout date according to the max booking offset for the hotel. */ - public static function getPreparationTime($idHotel) + public static function getMaxOrderDate($idHotel) { $result = self::getDataByHotelId($idHotel); - if (is_array($result) && count($result) && !$result['use_global_preparation_time']) { - return (int) $result['preparation_time']; + if (is_array($result) && count($result) && !$result['use_global_max_checkout_offset']) { + return date('Y-m-d H:i:s', strtotime('+ '.$result['max_checkout_offset'].' days')); } - $globalPreparationTime = Configuration::get('GLOBAL_PREPARATION_TIME'); - if ($globalPreparationTime != '0') { - return (int) $globalPreparationTime; + // since this cannot be zero, this function will always return a date. + $globalBookingDate = (int) Configuration::get('PS_MAX_CHECKOUT_OFFSET'); + + return date('Y-m-d H:i:s', strtotime('+ '.$globalBookingDate.' days')); + } + + /** + * @param int $id_hotel + * @return int Maximum allowable number of days between booking date and checkout date. + */ + public static function getMaximumCheckoutOffset($idHotel) + { + $result = self::getDataByHotelId($idHotel); + if (is_array($result) && count($result) && !$result['use_global_max_checkout_offset']) { + return $result['max_checkout_offset']; } - return false; + return (int) Configuration::get('PS_MAX_CHECKOUT_OFFSET'); + } + + /** + * @param int $id_hotel + * @return int Minimum number of days required between booking and check-in. + */ + public static function getMinimumBookingOffset($idHotel) + { + $result = self::getDataByHotelId($idHotel); + if (is_array($result) && count($result) && !$result['use_global_min_booking_offset']) { + return (int) $result['min_booking_offset']; + } + + return (int) Configuration::get('PS_MIN_BOOKING_OFFSET'); } public static function validateOrderRestrictDateOnPayment(&$controller) diff --git a/modules/hotelreservationsystem/classes/HotelReservationSystemDb.php b/modules/hotelreservationsystem/classes/HotelReservationSystemDb.php index 86f4590fc..98e9bb6ee 100644 --- a/modules/hotelreservationsystem/classes/HotelReservationSystemDb.php +++ b/modules/hotelreservationsystem/classes/HotelReservationSystemDb.php @@ -269,10 +269,10 @@ class HotelReservationSystemDb "CREATE TABLE IF NOT EXISTS `"._DB_PREFIX_."htl_order_restrict_date` ( `id` int(11) NOT NULL AUTO_INCREMENT, `id_hotel` int(11) NOT NULL, - `use_global_max_order_date` tinyint(1) NOT NULL, - `max_order_date` date NOT NULL, - `use_global_preparation_time` tinyint(1) NOT NULL, - `preparation_time` int(11) NOT NULL, + `use_global_max_checkout_offset` tinyint(1) NOT NULL, + `max_checkout_offset` int(11) NOT NULL, + `use_global_min_booking_offset` tinyint(1) NOT NULL, + `min_booking_offset` int(11) NOT NULL, `date_add` datetime NOT NULL, `date_upd` datetime NOT NULL, PRIMARY KEY (`id`) diff --git a/modules/hotelreservationsystem/classes/HotelRoomType.php b/modules/hotelreservationsystem/classes/HotelRoomType.php index 6fcddfe81..dc9938653 100644 --- a/modules/hotelreservationsystem/classes/HotelRoomType.php +++ b/modules/hotelreservationsystem/classes/HotelRoomType.php @@ -250,12 +250,20 @@ class HotelRoomType extends ObjectModel */ public static function getHotelIdAddressByIdProduct($id_product) { - return Db::getInstance()->getValue( - 'SELECT `id_address` from `'._DB_PREFIX_.'address` a - INNER JOIN `'._DB_PREFIX_.'htl_room_type` hrt - ON (hrt.`id_hotel` = a.`id_hotel`) - WHERE hrt.`id_product` = '.(int)$id_product.' AND a.`deleted` = 0 - '); + $cache_key = 'HotelRoomType::getHotelIdAddressByIdProduct'.(int)$id_product; + if (!Cache::isStored($cache_key)) { + $res = Db::getInstance()->getValue( + 'SELECT `id_address` from `'._DB_PREFIX_.'address` a + INNER JOIN `'._DB_PREFIX_.'htl_room_type` hrt + ON (hrt.`id_hotel` = a.`id_hotel`) + WHERE hrt.`id_product` = '.(int)$id_product.' AND a.`deleted` = 0 + '); + Cache::store($cache_key, $res); + } else { + $res = Cache::retrieve($cache_key); + } + + return $res; } /** diff --git a/modules/hotelreservationsystem/classes/HotelRoomTypeFeaturePricing.php b/modules/hotelreservationsystem/classes/HotelRoomTypeFeaturePricing.php index b63d922cf..7dc8ecb8d 100644 --- a/modules/hotelreservationsystem/classes/HotelRoomTypeFeaturePricing.php +++ b/modules/hotelreservationsystem/classes/HotelRoomTypeFeaturePricing.php @@ -636,7 +636,7 @@ class HotelRoomTypeFeaturePricing extends ObjectModel $id_product, $date_from, $date_to, - $quantity = 0, + $occupancy = null, $id_group = 0, $id_cart = 0, $id_guest = 0, @@ -657,6 +657,12 @@ class HotelRoomTypeFeaturePricing extends ObjectModel $taxRate = 0; } + if (is_array($occupancy) && count($occupancy)) { + $quantity = count($occupancy); + } else { + $quantity = $occupancy; + } + // Initializations if (!$id_group) { $id_group = (int)Group::getCurrent()->id; @@ -726,7 +732,8 @@ class HotelRoomTypeFeaturePricing extends ObjectModel 'id_guest' => $id_guest, 'id_group' => $id_group, 'use_reduc' => $use_reduc, - 'tax_rate' => $taxRate + 'tax_rate' => $taxRate, + 'occupancy' => $occupancy ) ); if ($with_auto_room_services) { @@ -805,7 +812,8 @@ class HotelRoomTypeFeaturePricing extends ObjectModel $id_guest = 0, $id_room = 0, $with_auto_room_services = 1, - $use_reduc = 1 + $use_reduc = 1, + $occupancy = array() ) { $dateFrom = date('Y-m-d H:i:s', strtotime($date_from)); $dateTo = date('Y-m-d H:i:s', strtotime($date_to)); @@ -813,7 +821,7 @@ class HotelRoomTypeFeaturePricing extends ObjectModel $id_product, $dateFrom, $dateTo, - 0, + $occupancy, $id_group, $id_cart, $id_guest, @@ -824,8 +832,7 @@ class HotelRoomTypeFeaturePricing extends ObjectModel $totalDurationPriceTI = $totalDurationPrice['total_price_tax_incl']; $totalDurationPriceTE = $totalDurationPrice['total_price_tax_excl']; - $objHotelBookingDetail = new HotelBookingDetail(); - $numDaysInDuration = $objHotelBookingDetail->getNumberOfDays($dateFrom, $dateTo); + $numDaysInDuration = HotelHelper::getNumberOfDays($dateFrom, $dateTo); if ($use_tax) { $pricePerDay = $totalDurationPriceTI/$numDaysInDuration; } else { diff --git a/modules/hotelreservationsystem/classes/RoomTypeServiceProduct.php b/modules/hotelreservationsystem/classes/RoomTypeServiceProduct.php index 7c80b17e1..2c178919f 100644 --- a/modules/hotelreservationsystem/classes/RoomTypeServiceProduct.php +++ b/modules/hotelreservationsystem/classes/RoomTypeServiceProduct.php @@ -160,6 +160,8 @@ class RoomTypeServiceProduct extends ObjectModel ); } + Hook::exec('actionAutoAddServicesModifier', array('services' => &$services, 'dateFrom' => $dateFrom, 'dateTo' => $dateTo)); + return $services; } } @@ -184,7 +186,6 @@ class RoomTypeServiceProduct extends ObjectModel true, $subCategory )) { - $objHotelRoomType = new HotelRoomType(); $serviceProducts = Product::getProductsProperties($idLang, $serviceProducts); $objRoomTypeServiceProductPrice = new RoomTypeServiceProductPrice(); foreach($serviceProducts as &$serviceProduct) { diff --git a/modules/hotelreservationsystem/classes/RoomTypeServiceProductCartDetail.php b/modules/hotelreservationsystem/classes/RoomTypeServiceProductCartDetail.php index fec2fed2c..d3056058a 100644 --- a/modules/hotelreservationsystem/classes/RoomTypeServiceProductCartDetail.php +++ b/modules/hotelreservationsystem/classes/RoomTypeServiceProductCartDetail.php @@ -54,6 +54,19 @@ class RoomTypeServiceProductCartDetail extends ObjectModel $idCart, $idHtlCartData ) { + $isAvailable = true; + Hook::exec('actionCheckServiceAvailability', array( + 'id_product' => $idProduct, + 'quantity' => $quantity, + 'id_cart' => $idCart, + 'htl_cart_booking_id' => $idHtlCartData, + 'is_service_available' => &$isAvailable, + )); + + if (!$isAvailable) { + return false; + } + if ($id_room_type_service_product_cart_detail = $this->alreadyExists($idProduct, $idCart, $idHtlCartData)) { $objRoomTypeServiceProductCartDetail = new RoomTypeServiceProductCartDetail($id_room_type_service_product_cart_detail); } else { @@ -217,7 +230,7 @@ class RoomTypeServiceProductCartDetail extends ObjectModel $idLang = Context::getContext()->language->id; - $sql = 'SELECT rscd.`id_product`, rscd.`quantity`, cbd.`id_cart`, cbd.`id` as `htl_cart_booking_id` , + $sql = 'SELECT rscd.`id_product`, rscd.`quantity`, cbd.`id_cart`, rscd.`id_cart` as service_id_cart, cbd.`id` as `htl_cart_booking_id` , cbd.`id_product` as `room_type_id_product`, cbd.`adults`, cbd.`children`, cbd.`date_from`, cbd.`date_to`'; if (!$getTotalPrice) { $sql .= ', pl.`name`, cbd.`id_guest`, cbd.`id_customer`, p.`auto_add_to_cart`, p.`price_addition_type`, @@ -233,7 +246,8 @@ class RoomTypeServiceProductCartDetail extends ObjectModel $sql .= ' LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (pl.`id_product` = p.`id_product` AND pl.`id_lang` = '.(int)$idLang.')'; } - $sql .= ' WHERE 1'; + + $sql .= ' WHERE 1 AND rscd.`id_product`!=0'; if (!is_null($autoAddToCart)) { $sql .= ' AND p.`auto_add_to_cart` = '. (int)$autoAddToCart; @@ -267,10 +281,9 @@ class RoomTypeServiceProductCartDetail extends ObjectModel if ($getTotalPrice) { $totalPrice = 0; } - $objRoomTypeServiceProductPrice = new RoomTypeServiceProductPrice(); - $objHotelRoomType = new HotelRoomType(); - $selectedServiceProducts = array(); + $objRoomTypeServiceProductPrice = new RoomTypeServiceProductPrice(); + $selectedServiceProducts = array(); if ($serviceProducts = Db::getInstance()->executeS($sql)) { foreach ($serviceProducts as $product) { $qty = $product['quantity'] ? (int)$product['quantity'] : 1; @@ -334,6 +347,7 @@ class RoomTypeServiceProductCartDetail extends ObjectModel 'name' => $product['name'], 'quantity' => $product['quantity'], 'auto_add_to_cart' => $product['auto_add_to_cart'], + 'id_cart' => $product['service_id_cart'], 'allow_multiple_quantity' => $product['allow_multiple_quantity'], 'price_addition_type' => $product['price_addition_type'], 'price_calculation_method' => $product['price_calculation_method'], @@ -449,6 +463,7 @@ class RoomTypeServiceProductCartDetail extends ObjectModel 'quantity' => $product['quantity'], 'auto_add_to_cart' => $product['auto_add_to_cart'], 'allow_multiple_quantity' => $product['allow_multiple_quantity'], + 'id_cart' => $product['service_id_cart'], 'price_addition_type' => $product['price_addition_type'], 'price_calculation_method' => $product['price_calculation_method'], 'unit_price_tax_excl' => ($objRoomTypeServiceProductPrice->getServicePrice( diff --git a/modules/hotelreservationsystem/classes/RoomTypeServiceProductOrderDetail.php b/modules/hotelreservationsystem/classes/RoomTypeServiceProductOrderDetail.php index 2d7059469..f08a92f72 100644 --- a/modules/hotelreservationsystem/classes/RoomTypeServiceProductOrderDetail.php +++ b/modules/hotelreservationsystem/classes/RoomTypeServiceProductOrderDetail.php @@ -254,6 +254,7 @@ class RoomTypeServiceProductOrderDetail extends ObjectModel 'id_order_detail' => $product['id_order_detail'], 'id_product' => $product['id_product'], 'name' => $product['name'], + 'id_cart' => $product['id_cart'], 'quantity' => $product['quantity'], 'allow_multiple_quantity' => $product['product_allow_multiple_quantity'], 'max_quantity' => $product['max_quantity'], @@ -280,6 +281,7 @@ class RoomTypeServiceProductOrderDetail extends ObjectModel 'id_order_detail' => $product['id_order_detail'], 'id_product' => $product['id_product'], 'name' => $product['name'], + 'id_cart' => $product['id_cart'], 'quantity' => $product['quantity'], 'allow_multiple_quantity' => $product['product_allow_multiple_quantity'], 'max_quantity' => $product['max_quantity'], @@ -323,4 +325,4 @@ class RoomTypeServiceProductOrderDetail extends ObjectModel // delete entry from order detail table. return parent::delete(); } -} \ No newline at end of file +} diff --git a/modules/hotelreservationsystem/classes/RoomTypeServiceProductPrice.php b/modules/hotelreservationsystem/classes/RoomTypeServiceProductPrice.php index ffb137c2f..bdb61f1b9 100644 --- a/modules/hotelreservationsystem/classes/RoomTypeServiceProductPrice.php +++ b/modules/hotelreservationsystem/classes/RoomTypeServiceProductPrice.php @@ -69,23 +69,30 @@ class RoomTypeServiceProductPrice extends ObjectModel public static function getProductRoomTypePriceAndTax($idProduct, $idElement, $elementType) { - if ($result = Db::getInstance()->getRow(' - SELECT spp.`price`, spp.`id_tax_rules_group`, p.`auto_add_to_cart`, p.`price_addition_type` - FROM `'._DB_PREFIX_.'product` p - LEFT JOIN `'._DB_PREFIX_.'htl_room_type_service_product` sp - ON (sp.`id_product` = p.`id_product`) - LEFT JOIN `'._DB_PREFIX_.'htl_room_type_service_product_price` spp - ON (spp.`id_product` = sp.`id_product` AND spp.`id_element` = sp.`id_element` AND spp.`element_type` = sp.`element_type`) - WHERE p.`id_product`='.(int)$idProduct. - ' AND sp.`id_element`='.(int)$idElement. - ' AND sp.`element_type`='.(int)$elementType) - ) { - if ($result['auto_add_to_cart'] && $result['price_addition_type'] == Product::PRICE_ADDITION_TYPE_WITH_ROOM) { - // if service is auto add to cart and added in room price, we need to find room type tax rule group - if ($elementType == RoomTypeServiceProduct::WK_ELEMENT_TYPE_ROOM_TYPE) { - $result['id_tax_rules_group'] = Product::getIdTaxRulesGroupByIdProduct((int)$idElement); + $cache_key = 'RoomTypeServiceProductPrice::getProductRoomTypePriceAndTax'.$idProduct.'_'.$idElement.'_'.$elementType; + if (!Cache::isStored($cache_key)) { + if ($result = Db::getInstance()->getRow(' + SELECT spp.`price`, spp.`id_tax_rules_group`, p.`auto_add_to_cart`, p.`price_addition_type` + FROM `'._DB_PREFIX_.'product` p + LEFT JOIN `'._DB_PREFIX_.'htl_room_type_service_product` sp + ON (sp.`id_product` = p.`id_product`) + LEFT JOIN `'._DB_PREFIX_.'htl_room_type_service_product_price` spp + ON (spp.`id_product` = sp.`id_product` AND spp.`id_element` = sp.`id_element` AND spp.`element_type` = sp.`element_type`) + WHERE p.`id_product`='.(int)$idProduct. + ' AND sp.`id_element`='.(int)$idElement. + ' AND sp.`element_type`='.(int)$elementType) + ) { + if ($result['auto_add_to_cart'] && $result['price_addition_type'] == Product::PRICE_ADDITION_TYPE_WITH_ROOM) { + // if service is auto add to cart and added in room price, we need to find room type tax rule group + if ($elementType == RoomTypeServiceProduct::WK_ELEMENT_TYPE_ROOM_TYPE) { + $result['id_tax_rules_group'] = Product::getIdTaxRulesGroupByIdProduct((int)$idElement); + } } } + + Cache::store($cache_key, $result); + } else { + $result = Cache::retrieve($cache_key); } return $result; diff --git a/modules/hotelreservationsystem/controllers/admin/AdminAddHotelController.php b/modules/hotelreservationsystem/controllers/admin/AdminAddHotelController.php index 402635d74..9b92aaa73 100644 --- a/modules/hotelreservationsystem/controllers/admin/AdminAddHotelController.php +++ b/modules/hotelreservationsystem/controllers/admin/AdminAddHotelController.php @@ -172,15 +172,7 @@ class AdminAddHotelController extends ModuleAdminController } } - $restrictDateInfo = HotelOrderRestrictDate::getDataByHotelId($idHotel); - if ($restrictDateInfo) { - if ($restrictDateInfo['max_order_date'] == '0000-00-00') { - $restrictDateInfo['max_order_date'] = date('d-m-Y', strtotime('1 year')); - } else { - $restrictDateInfo['max_order_date'] = date('d-m-Y', strtotime($restrictDateInfo['max_order_date'])); - } - } - $smartyVars['order_restrict_date_info'] = $restrictDateInfo; + $smartyVars['order_restrict_date_info'] = HotelOrderRestrictDate::getDataByHotelId($idHotel); $objHotelFeatures = new HotelFeatures(); $hotelFeatures = $this->object->getFeaturesOfHotelByHotelId($this->object->id); if ($features = $objHotelFeatures->HotelBranchSelectedFeaturesArray($hotelFeatures)) { @@ -224,8 +216,8 @@ class AdminAddHotelController extends ModuleAdminController $smartyVars['state_var'] = $stateOptions; $smartyVars['enabledDisplayMap'] = Configuration::get('PS_API_KEY') && Configuration::get('WK_GOOGLE_ACTIVE_MAP'); $smartyVars['ps_img_dir'] = _PS_IMG_.'l/'; - $smartyVars['MAX_GLOBAL_BOOKING_DATE'] = (Configuration::get('MAX_GLOBAL_BOOKING_DATE')); - $smartyVars['GLOBAL_PREPARATION_TIME'] = Configuration::get('GLOBAL_PREPARATION_TIME'); + $smartyVars['PS_MAX_CHECKOUT_OFFSET'] = (int) Configuration::get('PS_MAX_CHECKOUT_OFFSET'); + $smartyVars['PS_MIN_BOOKING_OFFSET'] = (int) Configuration::get('PS_MIN_BOOKING_OFFSET'); $smartyVars['WK_ORDER_REFUND_ALLOWED'] = Configuration::get('WK_ORDER_REFUND_ALLOWED'); $this->context->smarty->assign($smartyVars); @@ -246,6 +238,10 @@ class AdminAddHotelController extends ModuleAdminController public function processSave() { + if (!$this->loadObject(true)) { + return false; + } + $idHotel = Tools::getValue('id'); $phone = Tools::getValue('phone'); $email = Tools::getValue('email'); @@ -259,10 +255,10 @@ class AdminAddHotelController extends ModuleAdminController $address = Tools::getValue('address'); $active = Tools::getValue('ENABLE_HOTEL'); $activeRefund = Tools::getValue('active_refund'); - $enableUseGlobalMaxOrderDate = Tools::getValue('enable_use_global_max_order_date'); - $maximumBookingDate = Tools::getValue('maximum_booking_date'); - $enableUseGlobalPreparationTime = Tools::getValue('enable_use_global_preparation_time'); - $preparationTime = Tools::getValue('preparation_time'); + $enableUseGlobalMaxCheckoutOffset = Tools::getValue('enable_use_global_max_checkout_offset'); + $maxCheckoutOffset = trim(Tools::getValue('max_checkout_offset')); + $enableUseGlobalMinBookingOffset = Tools::getValue('enable_use_global_min_booking_offset'); + $minBookingOffset = trim(Tools::getValue('min_booking_offset')); $latitude = Tools::getValue('loclatitude'); $longitude = Tools::getValue('loclongitude'); $map_formated_address = Tools::getValue('locformatedAddr'); @@ -445,24 +441,35 @@ class AdminAddHotelController extends ModuleAdminController } if ($idHotel) { - if (!$enableUseGlobalMaxOrderDate) { - $maximumBookingDateFormatted = date('Y-m-d', strtotime($maximumBookingDate)); - if ($maximumBookingDate == '') { - $this->errors[] = $this->l('Maximum Check-out Date to book a room is a required field.'); - } elseif (!Validate::isDate($maximumBookingDateFormatted)) { - $this->errors[] = $this->l('Maximum Check-out Date to book a room is invalid.'); - } elseif (strtotime($maximumBookingDateFormatted) < strtotime(date('Y-m-d'))) { - $this->errors[] = $this->l('Maximum Check-out Date to book a room can not be a past date. Please use a future date.'); + if (!$enableUseGlobalMaxCheckoutOffset) { + if ($maxCheckoutOffset === '') { + $this->errors[] = $this->l('Maximum checkout offset is a required field.'); + } elseif (!$maxCheckoutOffset || !Validate::isUnsignedInt($maxCheckoutOffset)) { + $this->errors[] = $this->l('Maximum checkout offset is invalid.'); } } - if (!$enableUseGlobalPreparationTime) { - if ($preparationTime === '') { + if (!$enableUseGlobalMinBookingOffset) { + if ($minBookingOffset === '') { $this->errors[] = $this->l('Minimum booking offset is a required field.'); - } elseif ($preparationTime !== '0' && !Validate::isUnsignedInt($preparationTime)) { + } elseif (!Validate::isUnsignedInt($minBookingOffset)) { $this->errors[] = $this->l('Minimum booking offset is invalid.'); } } + + if (empty($this->errors)) { + if (!$enableUseGlobalMaxCheckoutOffset && !$enableUseGlobalMinBookingOffset) { + if ($maxCheckoutOffset && $maxCheckoutOffset <= $minBookingOffset) { + $this->errors[] = $this->l('Field Maximum checkout offset cannot be be less than or equal to Minimum booking offset.'); + } + } else { + if (!$enableUseGlobalMaxCheckoutOffset && $maxCheckoutOffset <= Configuration::get('PS_MIN_BOOKING_OFFSET')) { + $this->errors[] = $this->l('Field Maximum checkout offset cannot be be less than or equal to global Minimum booking offset.'); + } else if (!$enableUseGlobalMinBookingOffset && $minBookingOffset >= Configuration::get('PS_MAX_CHECKOUT_OFFSET')) { + $this->errors[] = $this->l('Field Minimum booking offset cannot be be greater than or equal to Global Maximum checkout offset.'); + } + } + } } if (!count($this->errors)) { @@ -745,24 +752,25 @@ class AdminAddHotelController extends ModuleAdminController $objHotelBranch->updateRoomTypeCategories(); if ($idHotel) { - // save maximum booking date and preparation time + // save Maximum checkout offset and minimum booking offset $objHotelOrderRestrictDate = new HotelOrderRestrictDate(); $restrictDateInfo = HotelOrderRestrictDate::getDataByHotelId($newIdHotel); if ($restrictDateInfo) { $objHotelOrderRestrictDate = new HotelOrderRestrictDate($restrictDateInfo['id']); - } else { - $objHotelOrderRestrictDate = new HotelOrderRestrictDate(); } $objHotelOrderRestrictDate->id_hotel = $newIdHotel; - $objHotelOrderRestrictDate->use_global_max_order_date = $enableUseGlobalMaxOrderDate; - if (!$enableUseGlobalMaxOrderDate) { - $objHotelOrderRestrictDate->max_order_date = $maximumBookingDateFormatted; + $objHotelOrderRestrictDate->use_global_max_checkout_offset = $enableUseGlobalMaxCheckoutOffset; + $objHotelOrderRestrictDate->use_global_min_booking_offset = $enableUseGlobalMinBookingOffset; + + if (!$enableUseGlobalMaxCheckoutOffset) { + $objHotelOrderRestrictDate->max_checkout_offset = $maxCheckoutOffset; } - $objHotelOrderRestrictDate->use_global_preparation_time = $enableUseGlobalPreparationTime; - if (!$enableUseGlobalPreparationTime) { - $objHotelOrderRestrictDate->preparation_time = $preparationTime; + + if (!$enableUseGlobalMinBookingOffset) { + $objHotelOrderRestrictDate->min_booking_offset = $minBookingOffset; } + $objHotelOrderRestrictDate->save(); $objHotelFeatures = new HotelBranchFeatures(); @@ -772,32 +780,25 @@ class AdminAddHotelController extends ModuleAdminController } } + $conf = 3; + if ($idHotel) { + $conf = 4; + } + if (Tools::isSubmit('submitAdd'.$this->table.'AndStay')) { - if ($idHotel) { - Tools::redirectAdmin( - self::$currentIndex.'&id='.(int) $newIdHotel.'&update'.$this->table.'&conf=4&token='. - $this->token - ); - } else { - Tools::redirectAdmin( - self::$currentIndex.'&id='.(int) $newIdHotel.'&update'.$this->table.'&conf=3&token='. - $this->token - ); - } + Tools::redirectAdmin(self::$currentIndex.'&id='.(int) $newIdHotel.'&update'.$this->table.'&conf='.$conf.'&token='.$this->token ); } else { - if ($idHotel) { - Tools::redirectAdmin(self::$currentIndex.'&conf=4&token='.$this->token); - } else { - Tools::redirectAdmin(self::$currentIndex.'&conf=3&token='.$this->token); - } + Tools::redirectAdmin(self::$currentIndex.'&conf='.$conf.'&token='.$this->token); } } + if ($idHotel) { $this->display = 'edit'; } else { $this->display = 'add'; } } + public function processStatus() { parent::processStatus(); diff --git a/modules/hotelreservationsystem/controllers/admin/AdminHotelRoomsBookingController.php b/modules/hotelreservationsystem/controllers/admin/AdminHotelRoomsBookingController.php index 6cbe0183c..24e060f1b 100644 --- a/modules/hotelreservationsystem/controllers/admin/AdminHotelRoomsBookingController.php +++ b/modules/hotelreservationsystem/controllers/admin/AdminHotelRoomsBookingController.php @@ -199,7 +199,7 @@ class AdminHotelRoomsBookingController extends ModuleAdminController $this->errors[] = $this->l('Selected room is not available for reallocation.'); } elseif (!in_array($idRoomToReallocate, array_column($availableRooms, 'id_room'))) { $this->errors[] = $this->l('Selected room is not available for reallocation.'); - } elseif (!Validate::isFloat($priceDiff)) { + } elseif (!Validate::isPrice($priceDiff)) { $this->errors[] = $this->l('Invalid price difference of the room types.'); } } else { @@ -875,11 +875,18 @@ class AdminHotelRoomsBookingController extends ModuleAdminController // if room is changing in the reallocation if ($objHotelBooking->id_product != $idNewRoomType) { $result['has_room_type_change'] = 1; + $occupancy = array( + array( + 'adults' => $objHotelBooking->adults, + 'children' => $objHotelBooking->children, + 'child_ages' => json_decode($objHotelBooking->child_ages) + ) + ); $newRoomTotalPrice = HotelRoomTypeFeaturePricing::getRoomTypeTotalPrice( $idNewRoomType, $objHotelBooking->date_from, $objHotelBooking->date_to, - 0, + $occupancy, 0, 0, 0, diff --git a/modules/hotelreservationsystem/controllers/admin/AdminOrderRefundRequestsController.php b/modules/hotelreservationsystem/controllers/admin/AdminOrderRefundRequestsController.php index 315dfeb1b..d35064fe9 100644 --- a/modules/hotelreservationsystem/controllers/admin/AdminOrderRefundRequestsController.php +++ b/modules/hotelreservationsystem/controllers/admin/AdminOrderRefundRequestsController.php @@ -33,6 +33,8 @@ class AdminOrderRefundRequestsController extends ModuleAdminController $this->_join .= ' LEFT JOIN `'._DB_PREFIX_.'customer` cust ON (cust.`id_customer` = ord.`id_customer`)'; $this->_orderWay = 'DESC'; + $this->allow_export = true; + $this->_new_list_header_design = true; if ($idOrder = Tools::getValue('id_order')) { $this->_select .= ', orsl.`name` as `status_name`, ors.`color`, COUNT(ordrd.`id_order_return_detail`) as num_rooms'; $this->_join .= 'LEFT JOIN '._DB_PREFIX_.'order_return_state ors ON (ors.`id_order_return_state` = a.`state`)'; @@ -176,9 +178,83 @@ class AdminOrderRefundRequestsController extends ModuleAdminController public function setCustomerLink($customerName, $row) { + if ($this->action == 'export') { + return $customerName.' (#'.$row['id_customer'].')'; + } + return ''.$customerName.' (#'.$row['id_customer'].')'; } + public function getList( + $id_lang, + $order_by = null, + $order_way = null, + $start = 0, + $limit = null, + $id_lang_shop = false + ){ + if ($this->action == 'export' && empty($this->_listsql)) { + if (Tools::getValue('id_order')) { + $this->_select .= ', ordtl.*'; + } else { + $this->_select .= ', GROUP_CONCAT(ordtl.`room_num`) AS `room_num`, + GROUP_CONCAT(DISTINCT ordtl.`room_type_name`) AS `room_type_name`, + ordtl.`hotel_name`, ordtl.`id_order`, + GROUP_CONCAT(ordtl.`date_from`) AS `date_from`, + GROUP_CONCAT(ordtl.`date_to`) AS `date_to`'; + } + + $this->_join .= ' LEFT JOIN ( + SELECT GROUP_CONCAT(hbd.`room_num`) AS room_num, + GROUP_CONCAT(DISTINCT(hbd.`room_type_name`)) AS room_type_name, + ord.`id_order_return`, hbd.`hotel_name`, hbd.`id_order`, + GROUP_CONCAT(hbd.`date_from`) AS date_from, + GROUP_CONCAT(hbd.`date_to`) AS date_to + FROM `'._DB_PREFIX_.'order_return_detail` ord + LEFT JOIN `'._DB_PREFIX_.'htl_booking_detail` hbd ON ord.`id_htl_booking` = hbd.`id` + GROUP BY ord.`id_order_return` + ) AS ordtl ON (ordtl.`id_order_return` = a.`id_order_return`)'; + $this->fields_list = array_merge($this->fields_list, array( + 'room_num' => array( + 'title' => $this->l('Room num(s)') + ), + 'room_type_name' => array( + 'title' => $this->l('Room type(s)'), + 'callback' => 'getUniqueRoomTypeNames' + ), + 'hotel_name' => array( + 'title' => $this->l('Hotel') + ), + 'date_from' => array( + 'title' => $this->l('Date From') + ), + 'date_to' => array( + 'title' => $this->l('Date To') + ), + )); + } + + parent::getList( + $id_lang, + $order_by, + $order_way, + $start, + $limit, + $id_lang_shop + ); + } + + public function getUniqueRoomTypeNames($roomTypeNames, $tr) + { + if ($roomTypeNames) { + $roomTypeNames = explode(',', $roomTypeNames); + $roomTypeNames = array_unique($roomTypeNames); + $roomTypeNames = implode(',', $roomTypeNames); + } + + return $roomTypeNames; + } + public function initToolbar() { parent::initToolbar(); diff --git a/modules/hotelreservationsystem/hotelreservationsystem.php b/modules/hotelreservationsystem/hotelreservationsystem.php index de232e2e2..fdd875768 100644 --- a/modules/hotelreservationsystem/hotelreservationsystem.php +++ b/modules/hotelreservationsystem/hotelreservationsystem.php @@ -65,15 +65,6 @@ class HotelReservationSystem extends Module public function hookDisplayHeader() { - // check max global order_restriction date is set - if (!Configuration::get('MAX_GLOBAL_BOOKING_DATE') - || (strtotime(date('Y-m-d')) > strtotime(Configuration::get('MAX_GLOBAL_BOOKING_DATE'))) - ) { - Configuration::updateValue( - 'MAX_GLOBAL_BOOKING_DATE', - date('Y-m-d', strtotime(date('Y-m-d', time()).' + 1 year')) - ); - } if (!Configuration::get('PS_CATALOG_MODE')) { /*To remove room from cart before todays date*/ if (isset($this->context->cart->id) && $this->context->cart->id) { diff --git a/modules/hotelreservationsystem/views/css/HotelReservationAdmin.css b/modules/hotelreservationsystem/views/css/HotelReservationAdmin.css index 147403354..6b2ee3587 100644 --- a/modules/hotelreservationsystem/views/css/HotelReservationAdmin.css +++ b/modules/hotelreservationsystem/views/css/HotelReservationAdmin.css @@ -426,12 +426,6 @@ p.room_cat_data } /*AdminHotelConfigurationSetting controller*/ - -#max_global_book_date -{ - width: 30%; -} - .htl_all_setting .btn.btn-default { margin: 20px!important; } diff --git a/modules/hotelreservationsystem/views/js/HotelReservationAdmin.js b/modules/hotelreservationsystem/views/js/HotelReservationAdmin.js index 30c96a0ee..75160764d 100644 --- a/modules/hotelreservationsystem/views/js/HotelReservationAdmin.js +++ b/modules/hotelreservationsystem/views/js/HotelReservationAdmin.js @@ -551,22 +551,6 @@ $(document).ready(function() { $("#conf_id_WK_BO_MESSAGE").hide(); }); - /*For OrderRestrict Functionality*/ - $("#max_htl_book_date").datepicker({ - defaultDate: new Date(), - dateFormat: 'dd-mm-yy', - minDate: 0, - }); - - $("#max_global_book_date").datepicker({ - defaultDate: new Date(), - dateFormat: 'dd-mm-yy', - minDate: 0, - }); - - //$( "#max_global_book_date" ).datepicker( "option", "maxDate", '20 Mar 2020'); - /*END*/ - /* ---- AdminHotelFeaturePricesSettingsController Admin ---- */ if ($('input[name="create_multiple"]:checked').val() == 1) { @@ -827,26 +811,19 @@ $(document).ready(function() { }); } - // manage hotel page - $('#maximum_booking_date').datepicker({ - defaultDate: new Date(), - dateFormat: 'dd-mm-yy', - minDate: 0, - }); - - $('input[name="enable_use_global_max_order_date"]').on('change', function () { + $('input[name="enable_use_global_max_checkout_offset"]').on('change', function () { if (parseInt($(this).val())) { - $('input[name="maximum_booking_date"]').closest('.form-group').hide(200); + $('input[name="max_checkout_offset"]').closest('.form-group').hide(200); } else { - $('input[name="maximum_booking_date"]').closest('.form-group').show(200); + $('input[name="max_checkout_offset"]').closest('.form-group').show(200); } }); - $('input[name="enable_use_global_preparation_time"]').on('change', function () { + $('input[name="enable_use_global_min_booking_offset"]').on('change', function () { if (parseInt($(this).val())) { - $('input[name="preparation_time"]').closest('.form-group').hide(200); + $('input[name="min_booking_offset"]').closest('.form-group').hide(200); } else { - $('input[name="preparation_time"]').closest('.form-group').show(200); + $('input[name="min_booking_offset"]').closest('.form-group').show(200); } }); diff --git a/modules/hotelreservationsystem/views/templates/admin/add_hotel/helpers/form/form.tpl b/modules/hotelreservationsystem/views/templates/admin/add_hotel/helpers/form/form.tpl index 68766826c..b473873ee 100644 --- a/modules/hotelreservationsystem/views/templates/admin/add_hotel/helpers/form/form.tpl +++ b/modules/hotelreservationsystem/views/templates/admin/add_hotel/helpers/form/form.tpl @@ -428,23 +428,23 @@ {if isset($hotel_info.id) && $hotel_info.id}
- - - - + + + + -
{l s='Global max order date:' mod='hotelreservationsystem'} {dateFormat date=$MAX_GLOBAL_BOOKING_DATE}
+
{l s='Global Maximum checkout offset:' mod='hotelreservationsystem'} {$PS_MAX_CHECKOUT_OFFSET}
-