diff --git a/admin/themes/default/template/controllers/products/amenities.tpl b/admin/themes/default/template/controllers/products/amenities.tpl new file mode 100644 index 000000000..17a354dd7 --- /dev/null +++ b/admin/themes/default/template/controllers/products/amenities.tpl @@ -0,0 +1,124 @@ +{** +* NOTICE OF LICENSE +* +* This source file is subject to the Open Software License version 3.0 +* that is bundled with this package in the file LICENSE.md +* It is also available through the world-wide-web at this URL: +* https://opensource.org/license/osl-3-0-php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to support@qloapps.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade this module to a newer +* versions in the future. If you wish to customize this module for your needs +* please refer to https://store.webkul.com/customisation-guidelines for more information. +* +* @author Webkul IN +* @copyright Since 2010 Webkul +* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0 +*} + +{if isset($product->id)} +
+ +

{l s='Amenities'}

+ +
+

{l s='If you want to add a new amenity, please use the following link.'} + + {l s='Manage amenities'} + +

+
+ + {if isset($room_type_amenities_tree) && $room_type_amenities_tree} +
+ +
+ {$room_type_amenities_tree} +
+
+ +
+ +
+ +
+
+ {else} +
+ {l s='No amenities have been defined yet.'} +
+ {/if} + + +
+ + +{/if} diff --git a/admin/themes/default/template/controllers/products/features.tpl b/admin/themes/default/template/controllers/products/features.tpl index a2caa28af..03dc6222b 100644 --- a/admin/themes/default/template/controllers/products/features.tpl +++ b/admin/themes/default/template/controllers/products/features.tpl @@ -28,162 +28,35 @@

{l s='Assign features to this room type'}

+ {if isset($room_type_features_tree) && $room_type_features_tree}
- {l s='You can specify a value for each relevant feature regarding this room type. Empty fields will not be displayed.'}
- {l s='You can either create a specific value, or select among the existing pre-defined values you\'ve previously added.'} + +

{l s='If you want to add a new feature, please use the following link.'} + + {l s='Add a new feature'} + +

+
+ +
+ {$room_type_features_tree} +
+
+ {else} +
+ {l s='No features have been defined'} +
+ {/if} - - - - - - - - - - - - {foreach from=$available_features item=available_feature} - - - {foreach from=$available_feature.featureValues item=value} - - - - {/foreach} - {*-- - {* *} - - - {foreachelse} - - - - {/foreach} - -
{l s='Feature'}{l s='Feature Image'}
- - {$available_feature.name} - - - - {if sizeof($available_feature.featureValues)} - - {else} - - {l s='N/A'} - - {l s='Add pre-defined values first'} - - {/if} *} - - - - - {foreach from=$languages key=k item=language} - {if $languages|count > 1} -
-
- {/if} - - - {if $languages|count > 1} -
-
- - -
-
- {/if} - {/foreach} -
{l s='No features have been defined'}
- - - {l s='Add a new feature'} - - -{/literal} - {/if} diff --git a/admin/themes/default/template/controllers/products/informations.tpl b/admin/themes/default/template/controllers/products/informations.tpl index c8716ea36..788e99d9b 100644 --- a/admin/themes/default/template/controllers/products/informations.tpl +++ b/admin/themes/default/template/controllers/products/informations.tpl @@ -465,21 +465,6 @@ {/if} -
- -
- -
-
- {*
diff --git a/classes/Product.php b/classes/Product.php index fc962d3c0..038d34b85 100644 --- a/classes/Product.php +++ b/classes/Product.php @@ -1073,9 +1073,6 @@ class ProductCore extends ObjectModel if (!$this->deleteServiceInfo()) { return false; } - } else { - $objHotelRoomTypeBedType = new HotelRoomTypeBedType(); - $objHotelRoomTypeBedType->deleteRoomTypeBedTypes(false, $this->id); } Hook::exec('actionProductDelete', array('id_product' => (int)$this->id, 'product' => $this)); @@ -1083,6 +1080,7 @@ class ProductCore extends ObjectModel !GroupReduction::deleteProductReduction($this->id) || !$this->deleteCategories(true) || !$this->deleteProductFeatures() || + !HotelRoomTypeAmenities::deleteByProduct((int)$this->id) || !$this->deleteTags() || !$this->deleteAttributesImpacts() || !$this->deleteAttachments(false) || @@ -6873,4 +6871,55 @@ class ProductCore extends ObjectModel return $price * (int)$quantity; } + + /** + * Prepare grouped core features and values for a room type, with selection state. + * + * @param int $idProduct + * @param int $idLang defaults to current context language + * @return array + */ + public static function getRoomTypeFeatureTreeData($idProduct, $idLang = 0) + { + if (!$idLang) { + $idLang = Context::getContext()->language->id; + } + + $product = new self((int) $idProduct); + $features = Feature::getFeatures( + $idLang, + (Shop::isFeatureActive() && Shop::getContext() == Shop::CONTEXT_SHOP) + ); + $selectedFeatureValues = array(); + foreach ($product->getFeatures() as $productFeature) { + $selectedFeatureValues[(int) $productFeature['id_feature']][] = (int) $productFeature['id_feature_value']; + } + + foreach ($features as &$feature) { + $featureValues = FeatureValue::getFeatureValuesWithLang( + $idLang, + (int) $feature['id_feature'] + ); + $feature['value'] = (int) $feature['id_feature']; + $feature['input_name'] = 'feature_value_parents'; + $feature['children'] = array(); + $selectedValues = isset($selectedFeatureValues[(int) $feature['id_feature']]) + ? $selectedFeatureValues[(int) $feature['id_feature']] + : array(); + + foreach ($featureValues as $featureValue) { + $featureValue['name'] = $featureValue['value']; + $featureValue['value'] = (int) $featureValue['id_feature_value']; + $featureValue['input_name'] = 'feature_values['.(int) $feature['id_feature'].']'; + $featureValue['selected'] = in_array((int) $featureValue['id_feature_value'], $selectedValues); + $feature['children'][] = $featureValue; + } + + if ($feature['children'] && count($selectedValues) === count($feature['children'])) { + $feature['selected'] = true; + } + } + + return $features; + } } diff --git a/controllers/admin/AdminFeaturesController.php b/controllers/admin/AdminFeaturesController.php index aa5d9c899..c90e51990 100644 --- a/controllers/admin/AdminFeaturesController.php +++ b/controllers/admin/AdminFeaturesController.php @@ -91,13 +91,22 @@ class AdminFeaturesControllerCore extends AdminController parent::__construct(); } + public function init() + { + parent::init(); + + if (($id = Tools::getValue('id_feature')) && Tools::getIsset('viewfeature')) { + self::$currentIndex .= '&id_feature='.(int)$id.'&viewfeature'; + } + } + /** * AdminController::renderList() override * @see AdminController::renderList() */ public function renderList() { - /*$this->addRowAction('view');*//*by webkul*/ + $this->addRowAction('view'); $this->addRowAction('edit'); $this->addRowAction('delete'); @@ -154,7 +163,6 @@ class AdminFeaturesControllerCore extends AdminController ); $this->_where = sprintf('AND `id_feature` = %d', (int)$id); - self::$currentIndex = self::$currentIndex.'&id_feature='.(int)$id.'&viewfeature'; $this->processFilter(); return parent::renderList(); } @@ -322,8 +330,14 @@ class AdminFeaturesControllerCore extends AdminController break; case 'view': - $bread_extended[] = $this->feature_name[$this->context->employee->id_lang]; - $this->addMetaTitle($bread_extended[count($bread_extended) - 1]); + if (!$this->feature_name && ($id = Tools::getValue('id_feature'))) { + $obj = new Feature((int)$id); + $this->feature_name = $obj->name; + } + if ($this->feature_name) { + $bread_extended[] = $this->feature_name[$this->context->employee->id_lang]; + $this->addMetaTitle($bread_extended[count($bread_extended) - 1]); + } break; case 'editFeatureValue': @@ -334,7 +348,7 @@ class AdminFeaturesControllerCore extends AdminController } if (Validate::isLoadedObject($obj = new FeatureValue((int)Tools::getValue('id_feature_value')))) { - $bread_extended[] = sprintf($this->l('Edit: %s'), $obj->value[$this->context->employee->id_lang]); + $bread_extended[] = sprintf($this->l('Edit: %s'), $obj->value[$this->context->employee->id_lang]); } } else { $bread_extended[] = $this->l('Edit Value'); @@ -549,13 +563,15 @@ class AdminFeaturesControllerCore extends AdminController { $object = parent::processAdd(); - if (Tools::isSubmit('submitAdd'.$this->table.'AndStay') && !count($this->errors)) { - if ($this->table == 'feature_value' && ($this->display == 'edit' || $this->display == 'add')) { - $this->redirect_after = self::$currentIndex.'&addfeature_value&id_feature='.(int)Tools::getValue('id_feature').'&token='.$this->token; + if ('feature_value' === $this->table && !count($this->errors)) { + if (Tools::isSubmit('submitAdd'.$this->table.'AndStay') && ($this->display == 'edit' || $this->display == 'add')) { + $this->redirect_after = self::$currentIndex.'&addfeature_value&id_feature='.(int)Tools::getValue('id_feature').'&conf=3&token='.$this->token; } else { - $this->redirect_after = self::$currentIndex.'&'.$this->identifier.'='.(int) $object->id.'&conf=3&update'.$this->table.'&token='.$this->token; + $this->redirect_after = self::$currentIndex.'&id_feature='.(int)Tools::getValue('id_feature').'&viewfeature&conf=3&token='.$this->token; } - } elseif (Tools::isSubmit('submitAdd'.$this->table.'AndStay') && count($this->errors) && $this->table == 'feature_value') { // enter only if feature is submitted + } elseif (Tools::isSubmit('submitAdd'.$this->table.'AndStay') && !count($this->errors)) { + $this->redirect_after = self::$currentIndex.'&'.$this->identifier.'='.(int) $object->id.'&conf=3&update'.$this->table.'&token='.$this->token; + } elseif (Tools::isSubmit('submitAdd'.$this->table.'AndStay') && count($this->errors) && 'feature_value' === $this->table) { // enter only if feature is submitted $this->display = 'editFeatureValue'; } @@ -570,8 +586,14 @@ class AdminFeaturesControllerCore extends AdminController { $object = parent::processUpdate(); - if (Tools::isSubmit('submitAdd'.$this->table.'AndStay') && !count($this->errors)) { - $this->redirect_after = self::$currentIndex.'&'.$this->identifier.'='.(int) Tools::getValue('id_feature').'&conf=4&update'.$this->table.'&token='.$this->token; + if ('feature_value' === $this->table && !count($this->errors)) { + if (Tools::isSubmit('submitAdd'.$this->table.'AndStay')) { + $this->redirect_after = self::$currentIndex.'&addfeature_value&id_feature='.(int)Tools::getValue('id_feature').'&conf=4&token='.$this->token; + } else { + $this->redirect_after = self::$currentIndex.'&id_feature='.(int)Tools::getValue('id_feature').'&viewfeature&conf=4&token='.$this->token; + } + } elseif (Tools::isSubmit('submitAdd'.$this->table.'AndStay') && !count($this->errors)) { + $this->redirect_after = self::$currentIndex.'&'.$this->identifier.'='.(int)$object->id.'&conf=4&update'.$this->table.'&token='.$this->token; } return $object; @@ -628,24 +650,12 @@ class AdminFeaturesControllerCore extends AdminController $this->errors[] = $this->l('Some error occurred while uploding room feature logo. Please try again.'); } } - - if ($featureValues = FeatureValue::getFeatureValuesWithLang( - $this->context->language->id, - $objFeature->id - )) { - $objFeatureValue = new FeatureValue($featureValues[0]['id_feature_value']); - } else { - $objFeatureValue = new FeatureValue(); - } - - $objFeatureValue->id_feature = $objFeature->id; - foreach (Language::getLanguages(true) as $lang) { - $objFeatureValue->value[$lang['id_lang']] = $objFeature->id.'.jpg'; - } - $objFeatureValue->save(); - return $objFeature; } + + return $objFeature; } + + return parent::processSave(); } /** diff --git a/controllers/admin/AdminImportController.php b/controllers/admin/AdminImportController.php index 6be582d49..a790be281 100644 --- a/controllers/admin/AdminImportController.php +++ b/controllers/admin/AdminImportController.php @@ -3326,7 +3326,7 @@ class AdminImportControllerCore extends AdminController Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'htl_image`'); Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'htl_access`'); Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'htl_booking_detail`'); - Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'htl_branch_features`'); + Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'htl_branch_amenity`'); Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'htl_cart_booking_data`'); Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'htl_branch_refund_rules`'); Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'htl_order_restrict_date`'); diff --git a/controllers/admin/AdminProductsController.php b/controllers/admin/AdminProductsController.php index 1664501e9..79499ce6b 100644 --- a/controllers/admin/AdminProductsController.php +++ b/controllers/admin/AdminProductsController.php @@ -107,6 +107,7 @@ class AdminProductsControllerCore extends AdminController 'Images' => $this->l('Images'), 'ServiceProduct' => $this->l('Service Products'), // 'Associations' => $this->l('Associations'), + 'Amenities' => $this->l('Amenities'), 'Features' => $this->l('Features'), 'Configuration' => $this->l('Rooms'), 'Occupancy' => $this->l('Occupancy'), @@ -121,9 +122,10 @@ class AdminProductsControllerCore extends AdminController 'Seo' => 2, // 'Associations' => 3, 'Images' => 4, - 'Features' => 5, - 'Configuration' => 6, - 'Occupancy' => 7, + 'Amenities' => 5, + 'Features' => 6, + 'Configuration' => 7, + 'Occupancy' => 8, 'ServiceProduct' => 9, 'LengthOfStay' => 10, 'AdditionalFacilities' => 11, @@ -944,12 +946,6 @@ class AdminProductsControllerCore extends AdminController $id_hotel_new = $room_type_info['id_hotel']; } - $objHotelRoomTypeBedType = new HotelRoomTypeBedType(); - if ($roomTypeBedTypes = $objHotelRoomTypeBedType->getRoomTypeBedTypes($id_product_old)) { - $roomTypeBedTypes = array_column($roomTypeBedTypes, 'id_bed_type'); - $objHotelRoomTypeBedType->updateRoomTypeBedTypes($roomTypeBedTypes, $product->id); - } - if ($product->hasAttributes()) { Product::updateDefaultAttribute($product->id); } else { @@ -1143,34 +1139,45 @@ class AdminProductsControllerCore extends AdminController } if (Validate::isLoadedObject($product = new Product((int)Tools::getValue('id_product')))) { - // delete all objects - $product->deleteFeatures(); - - // add new objects - $languages = Language::getLanguages(false); - foreach ($_POST as $key => $val) { - if (preg_match('/^feature_([0-9]+)_check/i', $key, $match)) { - if ($val) { - $product->addFeaturesToDB($match[1], $val); - } else { - if ($default_value = $this->checkFeatures($languages, $match[1])) { - $id_value = $product->addFeaturesToDB($match[1], 0, 1); - foreach ($languages as $language) { - if ($cust = Tools::getValue('custom_'.$match[1].'_'.(int)$language['id_lang'])) { - $product->addFeaturesCustomToDB($id_value, (int)$language['id_lang'], $cust); - } else { - $product->addFeaturesCustomToDB($id_value, (int)$language['id_lang'], $default_value); - } - } - } - } - } + if (!$this->saveRoomTypeFeatures($product)) { + $this->errors[] = Tools::displayError('An error occurred while saving room type features.'); } } else { $this->errors[] = Tools::displayError('A room type must be created before adding features.'); } } + /** + * Save assigned core feature values for a room type. + * + * @param Product $product + * + * @return bool + */ + protected function saveRoomTypeFeatures(Product $product) + { + $product->deleteFeatures(); + + $featureValues = Tools::getValue('feature_values', array()); + if (!is_array($featureValues) || empty($featureValues)) { + return true; + } + + foreach ($featureValues as $idFeature => $selectedValues) { + $idFeature = (int)$idFeature; + if (!$idFeature) { + continue; + } + foreach (array_unique(array_map('intval', $selectedValues)) as $idFeatureValue) { + if ($idFeatureValue) { + $product->addFeaturesToDB($idFeature, $idFeatureValue); + } + } + } + + return true; + } + /** * This function is never called at the moment (specific prices cannot be edited) */ @@ -1925,14 +1932,29 @@ class AdminProductsControllerCore extends AdminController $this->copyFromPost($this->object, $this->table); $this->object->booking_product = true; if ($this->object->add()) { - $objHotelRoomTypeBedType = new HotelRoomTypeBedType(); - $objHotelRoomTypeBedType->updateRoomTypeBedTypes(Tools::getValue('id_bed_types'), $this->object->id); // associateroom type to hotel // if ($this->object->is_virtual) { // } $this->assignRoomType($this->object); + if ($this->isTabSubmitted('Amenities')) { + $categories = HotelAmenities::getCategories(); + if ($categories && !HotelAmenities::getAmenities()) { + $this->errors[] = Tools::displayError('No amenities have been created. Please add amenities to at least one category before assigning them.'); + return false; + } + $selectedAmenities = Tools::getValue('room_type_amenities', array()); + $featuredAmenities = Tools::getValue('featured_amenities', array()); + if (!(new HotelRoomTypeAmenities())->saveRoomTypeAmenities((int)$this->object->id, $selectedAmenities, $featuredAmenities)) { + $this->errors[] = Tools::displayError('An error occurred while saving room type amenities.'); + return false; + } + } + if ($this->isTabSubmitted('Features') && !$this->saveRoomTypeFeatures($this->object)) { + $this->errors[] = Tools::displayError('An error occurred while saving room type features.'); + return false; + } PrestaShopLogger::addLog(sprintf($this->l('%s addition', 'AdminTab', false, false), $this->className), 1, null, $this->className, (int)$this->object->id, true, (int)$this->context->employee->id); @@ -2175,8 +2197,18 @@ class AdminProductsControllerCore extends AdminController } if ($object->update()) { - $objHotelRoomTypeBedType = new HotelRoomTypeBedType(); - $objHotelRoomTypeBedType->updateRoomTypeBedTypes(Tools::getValue('id_bed_types'), $object->id); + if ($this->isTabSubmitted('Amenities')) { + $selectedAmenities = Tools::getValue('room_type_amenities', array()); + $featuredAmenities = Tools::getValue('featured_amenities', array()); + if (!(new HotelRoomTypeAmenities())->saveRoomTypeAmenities((int)$object->id, $selectedAmenities, $featuredAmenities)) { + $this->errors[] = Tools::displayError('An error occurred while saving room type amenities.'); + return false; + } + } + if ($this->isTabSubmitted('Features') && !$this->saveRoomTypeFeatures($object)) { + $this->errors[] = Tools::displayError('An error occurred while saving room type features.'); + return false; + } // update position in category $object->setPositionInCategory(Tools::getValue('category_position')); @@ -2200,9 +2232,6 @@ class AdminProductsControllerCore extends AdminController if ($this->isTabSubmitted('Suppliers')) { // $this->processSuppliers(); } - if ($this->isTabSubmitted('Features')) { - $this->processFeatures(); - } if ($this->isTabSubmitted('Combinations')) { $this->processProductAttribute(); } @@ -4601,15 +4630,6 @@ class AdminProductsControllerCore extends AdminController $data->assign('htl_full_info', $hotelFullInfo); } - $objHotelBedType = new HotelBedType(); - $bedTypes = $objHotelBedType->getAllBedTypes($this->context->language->id); - $data->assign('bed_types_info', $bedTypes); - $objHotelRoomTypeBedType = new HotelRoomTypeBedType(); - if ($selectedBedTypes = $objHotelRoomTypeBedType->getRoomTypeBedTypes($product->id)) { - $selectedBedTypes = array_column($selectedBedTypes, 'id_bed_type'); - $data->assign('selected_bed_types', $selectedBedTypes); - } - $this->tpl_form_vars['product'] = $product; $this->tpl_form_vars['custom_form'] = $data->fetch(); } @@ -4851,37 +4871,17 @@ class AdminProductsControllerCore extends AdminController } else { if ($obj->id) { if ($this->product_exists_in_shop) { - $features = Feature::getFeatures($this->context->language->id, (Shop::isFeatureActive() && Shop::getContext() == Shop::CONTEXT_SHOP)); - - foreach ($features as $k => $tab_features) { - $features[$k]['current_item'] = false; - $features[$k]['val'] = array(); - - $custom = true; - foreach ($obj->getFeatures() as $tab_products) { - if ($tab_products['id_feature'] == $tab_features['id_feature']) { - $features[$k]['current_item'] = $tab_products['id_feature_value']; - } - } - - $features[$k]['featureValues'] = FeatureValue::getFeatureValuesWithLang($this->context->language->id, (int)$tab_features['id_feature']); - if (count($features[$k]['featureValues'])) { - foreach ($features[$k]['featureValues'] as $value) { - if ($features[$k]['current_item'] == $value['id_feature_value']) { - $custom = false; - } - } - } - - if ($custom) { - $feature_values_lang = FeatureValue::getFeatureValueLang($features[$k]['current_item']); - foreach ($feature_values_lang as $feature_value) { - $features[$k]['val'][$feature_value['id_lang']] = $feature_value; - } - } + $features = Product::getRoomTypeFeatureTreeData($obj->id); + if ($features) { + $tree = new HelperTree('room-type-features-tree', $features); + $tree->setShowCollapseExpandButton(true) + ->setUseCheckBox(true) + ->setAutoSelectChildren(true) + ->setUseBulkActions(true) + ->setUseSearch(true) + ->setHeaderTemplate('tree_header_room.tpl'); + $data->assign('room_type_features_tree', $tree->render()); } - - $data->assign('available_features', $features); $data->assign('product', $obj); $data->assign('link', $this->context->link); $data->assign('default_form_language', $this->default_form_language); @@ -4895,6 +4895,50 @@ class AdminProductsControllerCore extends AdminController $this->tpl_form_vars['custom_form'] = $data->fetch(); } + /** + * Prepare the amenities form tab for a room type. + * + * @param Product $obj + * + * @throws Exception + * @throws SmartyException + */ + public function initFormAmenities($obj) + { + if (!$this->default_form_language) { + $this->getLanguages(); + } + + $data = $this->createTemplate($this->tpl_form); + $data->assign('default_form_language', $this->default_form_language); + $data->assign('languages', $this->_languages); + $data->assign('link', $this->context->link); + $data->assign('product', $obj); + + if ($obj->id) { + if ($this->product_exists_in_shop) { + $roomTypeAmenities = HotelRoomTypeAmenities::getRoomTypeAmenitiesTreeData((int) $obj->id); + if ($roomTypeAmenities) { + $tree = new HelperTree('room-type-amenities-tree', $roomTypeAmenities); + $tree->setShowCollapseExpandButton(true) + ->setUseCheckBox(true) + ->setAutoSelectChildren(true) + ->setUseBulkActions(true) + ->setUseSearch(true) + ->setHeaderTemplate('tree_header_room.tpl'); + $data->assign('room_type_amenities_tree', $tree->render()); + $data->assign('featured_amenity_ids', array_column(HotelRoomTypeAmenities::getAmenities((int)$obj->id, 0, true), 'id')); + } + } else { + $this->displayWarning($this->l('You must save the room type in this shop before adding amenities.')); + } + } else { + $this->displayWarning($this->l('You must save this room type before adding amenities.')); + } + + $this->tpl_form_vars['custom_form'] = $data->fetch(); + } + public function getModalDuplicateOptions() { $idsHotel = HotelBranchInformation::getProfileAccessedHotels($this->context->employee->id_profile, 1, 1); diff --git a/controllers/admin/AdminSearchController.php b/controllers/admin/AdminSearchController.php index ac47c445f..c2ac5e28f 100644 --- a/controllers/admin/AdminSearchController.php +++ b/controllers/admin/AdminSearchController.php @@ -38,7 +38,7 @@ class AdminSearchControllerCore extends AdminController 'AdminOrderRefundRules' => 1, 'AdminRoomTypeGlobalDemand' => 1, 'AdminGroups' => 1, - 'AdminHotelFeatures' => 1, + 'AdminHotelAmenities' => 1, 'AdminCustomers' => 1, 'AdminAddHotel' => 1, 'AdminNormalProducts' => 1, @@ -190,7 +190,7 @@ class AdminSearchControllerCore extends AdminController if (!$searchType) { $this->searchAddress(); - $this->searchHotelFeatures(); + $this->searchHotelAmenities(); $this->searchAdditionalFacilities(); $this->searchRefundRules(); } @@ -428,23 +428,23 @@ class AdminSearchControllerCore extends AdminController } } - public function searchHotelFeatures() + public function searchHotelAmenities() { - if (class_exists('HotelFeatures')) { - if (isset($this->controllerAccess['AdminHotelFeatures']) && $this->controllerAccess['AdminHotelFeatures']) { - $objHotelFeatures = new HotelFeatures(); - if ($hotelFeatures = $objHotelFeatures->searchByName($this->query, $this->context->language->id)) { - $features = array(); - foreach ($hotelFeatures as $key => $hotelFeature) { - $features[$hotelFeature['id']]['name'] = $hotelFeature['name']; - if ($hotelFeature['parent_feature_id']) { - $features[$hotelFeature['id']]['id'] = $hotelFeature['parent_feature_id']; + if (class_exists('HotelAmenities')) { + if (isset($this->controllerAccess['AdminHotelAmenities']) && $this->controllerAccess['AdminHotelAmenities']) { + $objHotelAmenities = new HotelAmenities(); + if ($hotelAmenities = $objHotelAmenities->searchByName($this->query, $this->context->language->id)) { + $amenities = array(); + foreach ($hotelAmenities as $key => $hotelAmenity) { + $amenities[$hotelAmenity['id_amenity']]['name'] = $hotelAmenity['name']; + if ($hotelAmenity['id_parent']) { + $amenities[$hotelAmenity['id_amenity']]['id'] = $hotelAmenity['id_parent']; } else { - $features[$hotelFeature['id']]['id'] = $hotelFeature['id']; + $amenities[$hotelAmenity['id_amenity']]['id'] = $hotelAmenity['id_amenity']; } } - $this->_list['hotel_features'] = $features; + $this->_list['hotel_amenities'] = $amenities; } } } @@ -681,10 +681,10 @@ class AdminSearchControllerCore extends AdminController ); } - protected function initHotelFeatureList() + protected function initHotelAmenityList() { $this->show_toolbar = false; - $this->fields_list['hotel_features'] = array( + $this->fields_list['hotel_amenities'] = array( 'name' => array('title' => $this->l('name'), 'width' => 'auto'), ); } @@ -929,26 +929,26 @@ class AdminSearchControllerCore extends AdminController $this->tpl_view_vars['customers'] = $view; } - if (isset($this->_list['hotel_features']) && count($this->_list['hotel_features'])) { + if (isset($this->_list['hotel_amenities']) && count($this->_list['hotel_amenities'])) { $view = ''; - $this->initHotelFeatureList(); + $this->initHotelAmenityList(); $helper = new HelperList(); $helper->shopLinkType = ''; $helper->simple_header = true; - $helper->identifier = 'id'; + $helper->identifier = 'id_amenity'; $helper->actions = array('edit', 'view'); $helper->show_toolbar = false; - $helper->table = 'htl_features'; - $helper->currentIndex = $this->context->link->getAdminLink('AdminHotelFeatures', false); - $helper->token = Tools::getAdminTokenLite('AdminHotelFeatures'); + $helper->table = 'htl_amenity'; + $helper->currentIndex = $this->context->link->getAdminLink('AdminHotelAmenities', false); + $helper->token = Tools::getAdminTokenLite('AdminHotelAmenities'); - if ($this->_list['hotel_features']) { - $view = $helper->generateList($this->_list['hotel_features'], $this->fields_list['hotel_features']); + if ($this->_list['hotel_amenities']) { + $view = $helper->generateList($this->_list['hotel_amenities'], $this->fields_list['hotel_amenities']); } - $this->tpl_view_vars['num_hotel_features'] = count($this->_list['hotel_features']); - $this->tpl_view_vars['hotel_features'] = $view; + $this->tpl_view_vars['num_hotel_amenities'] = count($this->_list['hotel_amenities']); + $this->tpl_view_vars['hotel_amenities'] = $view; } if (isset($this->_list['groups']) && count($this->_list['groups'])) { $view = ''; diff --git a/controllers/front/CategoryController.php b/controllers/front/CategoryController.php index bdf716637..6abb5d336 100644 --- a/controllers/front/CategoryController.php +++ b/controllers/front/CategoryController.php @@ -245,7 +245,6 @@ class CategoryControllerCore extends FrontController } } - $feat_img_dir = _PS_IMG_.'rf/'; $ratting_img = _MODULE_DIR_.'hotelreservationsystem/views/img/Slices/icons-sprite.png'; $this->context->smarty->assign(array( 'warning_num' => $warning_num, @@ -258,7 +257,7 @@ class CategoryControllerCore extends FrontController 'display_all_room_types' => $displayAllRoomsTypes, 'id_hotel' => $id_hotel, 'currency' => $currency, - 'feat_img_dir' => $feat_img_dir, + 'amenity_img_dir' => _MODULE_DIR_.'hotelreservationsystem/views/img/hotel_amenities/', 'ratting_img' => $ratting_img, )); diff --git a/controllers/front/ProductController.php b/controllers/front/ProductController.php index db3e4c574..7430e93dd 100644 --- a/controllers/front/ProductController.php +++ b/controllers/front/ProductController.php @@ -352,12 +352,12 @@ class ProductControllerCore extends FrontController $hotel_location = $addressInfo['city']. ($addressInfo['id_state']?', '.$addressInfo['state']:'').', '.$addressInfo['country']; - $obj_hotel_feaures_ids = $obj_hotel_branch->getFeaturesOfHotelByHotelId($hotel_id); + $obj_hotel_amenities_ids = $obj_hotel_branch->getAmenitiesOfHotelByHotelId($hotel_id); - if (isset($obj_hotel_feaures_ids) && $obj_hotel_feaures_ids) { - foreach ($obj_hotel_feaures_ids as $key => $value) { - $obj_htl_ftr = new HotelFeatures(); - $htl_info = $obj_htl_ftr->getFeatureInfoById($value['feature_id']); + if (isset($obj_hotel_amenities_ids) && $obj_hotel_amenities_ids) { + foreach ($obj_hotel_amenities_ids as $key => $value) { + $obj_htl_amenity = new HotelAmenities(); + $htl_info = $obj_htl_amenity->getAmenityInfoById($value['amenity_id']); $htl_features[] = $htl_info['name']; } } @@ -415,19 +415,9 @@ class ProductControllerCore extends FrontController } } - $objHotelBedType = new HotelBedType(); - if ($bedTypes = $objHotelBedType->getAllBedTypes($this->context->language->id)) { - foreach ($bedTypes as $bedTypeKey => $bedType) { - $bedTypes[$bedTypeKey]['area'] = Tools::ps_round($bedType['width'], 2).' * '.Tools::ps_round($bedType['length'], 2); - } - - $bedTypes = array_column($bedTypes, null, 'id_bed_type'); - } - - $objHotelRoomTypeBedType = new HotelRoomTypeBedType(); - if ($selectedBedTypes = $objHotelRoomTypeBedType->getRoomTypeBedTypes($this->product->id)) { - $selectedBedTypes = array_column($selectedBedTypes, 'id_bed_type'); - } + $roomFeatures = $this->product->getFrontFeatures($this->context->language->id); + $roomAmenities = HotelRoomTypeAmenities::getAmenities($this->product->id, $this->context->language->id); + $hotelAmenities = HotelBranchAmenities::getAmenities($hotel_id, $this->context->language->id); $this->context->smarty->assign( array( @@ -455,14 +445,14 @@ class ProductControllerCore extends FrontController 'hotel_description' => $hotel_info_by_id['description'], 'hotel_policies' => $hotel_policies, 'hotel_features' => $htl_features, + 'room_type_features' => $roomFeatures, + 'room_dynamic_amenities' => $roomAmenities, + 'hotel_dynamic_amenities' => $hotelAmenities, + 'amenity_img_dir' => _MODULE_DIR_.'hotelreservationsystem/views/img/hotel_amenities/', 'hotel_image_link' => $hotelImageLink, 'hotel_has_images' => (bool) HotelImage::getCover($hotel_id), - 'ftr_img_src' => _PS_IMG_.'rf/', 'order_date_restrict' => $order_date_restrict, 'PS_SERVICE_PRODUCT_CATEGORY_FILTER' => Configuration::get('PS_SERVICE_PRODUCT_CATEGORY_FILTER'), - 'bed_types_info' => $bedTypes, - 'selected_bed_types' => $selectedBedTypes, - 'dimension_unit' => Configuration::get('WK_DIMENSION_UNIT', $this->context->language->id), ) ); diff --git a/img/rf/1.jpg b/img/rf/1.jpg index 9d820ba43..722d4ec53 100644 Binary files a/img/rf/1.jpg and b/img/rf/1.jpg differ diff --git a/img/rf/10.jpg b/img/rf/10.jpg new file mode 100644 index 000000000..d6f959d54 Binary files /dev/null and b/img/rf/10.jpg differ diff --git a/img/rf/11.jpg b/img/rf/11.jpg new file mode 100644 index 000000000..cb60b74d2 Binary files /dev/null and b/img/rf/11.jpg differ diff --git a/img/rf/12.jpg b/img/rf/12.jpg new file mode 100644 index 000000000..ab71aa737 Binary files /dev/null and b/img/rf/12.jpg differ diff --git a/img/rf/13.jpg b/img/rf/13.jpg new file mode 100644 index 000000000..e8d249de2 Binary files /dev/null and b/img/rf/13.jpg differ diff --git a/img/rf/2.jpg b/img/rf/2.jpg index ed46f7fff..5f78f92f7 100644 Binary files a/img/rf/2.jpg and b/img/rf/2.jpg differ diff --git a/img/rf/3.jpg b/img/rf/3.jpg index d5f91bdbf..b4803e566 100644 Binary files a/img/rf/3.jpg and b/img/rf/3.jpg differ diff --git a/img/rf/4.jpg b/img/rf/4.jpg index 05c7251eb..45e63101b 100644 Binary files a/img/rf/4.jpg and b/img/rf/4.jpg differ diff --git a/img/rf/5.jpg b/img/rf/5.jpg index 33236f769..c0149e50c 100644 Binary files a/img/rf/5.jpg and b/img/rf/5.jpg differ diff --git a/img/rf/6.jpg b/img/rf/6.jpg index 6f057b5a9..620dcccb1 100644 Binary files a/img/rf/6.jpg and b/img/rf/6.jpg differ diff --git a/img/rf/7.jpg b/img/rf/7.jpg index bd7203ed1..632435172 100644 Binary files a/img/rf/7.jpg and b/img/rf/7.jpg differ diff --git a/img/rf/8.jpg b/img/rf/8.jpg new file mode 100644 index 000000000..54a94da89 Binary files /dev/null and b/img/rf/8.jpg differ diff --git a/img/rf/9.jpg b/img/rf/9.jpg new file mode 100644 index 000000000..0a49d24bf Binary files /dev/null and b/img/rf/9.jpg differ diff --git a/install/data/db_structure.sql b/install/data/db_structure.sql index 097000718..55f952897 100644 --- a/install/data/db_structure.sql +++ b/install/data/db_structure.sql @@ -831,7 +831,7 @@ CREATE TABLE `PREFIX_feature_product` ( `id_feature` int(10) unsigned NOT NULL, `id_product` int(10) unsigned NOT NULL, `id_feature_value` int(10) unsigned NOT NULL, - PRIMARY KEY (`id_feature`,`id_product`), + PRIMARY KEY (`id_feature`,`id_product`,`id_feature_value`), KEY `id_feature_value` (`id_feature_value`), KEY `id_product` (`id_product`) ) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8 COLLATION; diff --git a/modules/hotelreservationsystem/classes/HotelAmenities.php b/modules/hotelreservationsystem/classes/HotelAmenities.php new file mode 100644 index 000000000..8dcabfd64 --- /dev/null +++ b/modules/hotelreservationsystem/classes/HotelAmenities.php @@ -0,0 +1,291 @@ + 'htl_amenity', + 'primary' => 'id_amenity', + 'multilang' => true, + 'fields' => array( + 'id_parent' => array('type' => self::TYPE_INT, 'required' => true), + 'position' => array('type' => self::TYPE_INT), + 'active' => array('type' => self::TYPE_INT, 'required' => true), + 'logo_type' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName'), + 'logo' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName'), + 'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate', 'copy_post' => false), + 'date_upd' => array('type' => self::TYPE_DATE, 'validate' => 'isDate', 'copy_post' => false), + // lang fields + 'name' => array('type' => self::TYPE_STRING, 'lang' => true, 'required' => true), + ), + ); + + protected $webserviceParameters = array( + 'objectsNodeName' => 'hotel_amenities', + 'objectNodeName' => 'hotel_amenity', + 'fields' => array(), + ); + + public function delete() + { + if ($id = $this->id) { + $imgFile = dirname(__FILE__).'/../views/img/hotel_amenities/'.(int)$id.'.jpg'; + if (file_exists($imgFile)) { + unlink($imgFile); + } + return parent::delete(); + } + return false; + } + + /** + * Return all categories (id_parent = 0) with their child amenities. + * + * @param int $idLang + * @return array|false + */ + public function getAmenitiesTree($idLang = 0) + { + if (!$idLang) { + $idLang = Context::getContext()->language->id; + } + + $rows = Db::getInstance()->executeS( + 'SELECT ha.`id_amenity`, ha.`id_parent`, ha.`position`, ha.`active`, ha.`logo_type`, ha.`logo`, hal.`name` + FROM `'._DB_PREFIX_.'htl_amenity` ha + LEFT JOIN `'._DB_PREFIX_.'htl_amenity_lang` hal + ON (hal.`id_amenity` = ha.`id_amenity` AND hal.`id_lang` = '.(int)$idLang.') + ORDER BY ha.`id_parent` ASC, ha.`position` ASC' + ); + + if (!$rows) { + return false; + } + + $result = array(); + $amenitiesByCategory = array(); + + foreach ($rows as $row) { + if ($row['id_parent'] == 0) { + $result[$row['id_amenity']] = array( + 'id' => $row['id_amenity'], + 'name' => $row['name'], + 'position' => $row['position'], + 'children' => array(), + ); + } else { + $row['id'] = $row['id_amenity']; + $amenitiesByCategory[$row['id_parent']][] = $row; + } + } + + foreach ($amenitiesByCategory as $categoryId => $amenities) { + if (isset($result[$categoryId])) { + $result[$categoryId]['children'] = $amenities; + } + } + + return $result ?: false; + } + + /** + * Returns all amenity categories with children, marking which are selected for a hotel/room type. + * + * @param array $selectedIds flat array of selected amenity IDs + * @param int $idLang + * @return array|false + */ + public function hotelBranchSelectedAmenities($selectedIds, $idLang = 0) + { + if (!$idLang) { + $idLang = Context::getContext()->language->id; + } + + $rows = Db::getInstance()->executeS( + 'SELECT ha.`id_amenity`, ha.`id_parent`, hal.`name` + FROM `'._DB_PREFIX_.'htl_amenity` ha + LEFT JOIN `'._DB_PREFIX_.'htl_amenity_lang` hal + ON (hal.`id_amenity` = ha.`id_amenity` AND hal.`id_lang` = '.(int)$idLang.') + ORDER BY ha.`id_parent` ASC' + ); + + if (!$rows) { + return array(); + } + + $result = array(); + + foreach ($rows as $row) { + if ($row['id_parent'] == 0) { + $result[$row['id_amenity']]['name'] = $row['name']; + } else { + $result[$row['id_parent']]['children'][] = array( + 'id_amenity' => $row['id_amenity'], + 'id' => $row['id_amenity'], + 'name' => $row['name'], + 'selected' => in_array($row['id_amenity'], $selectedIds) ? 1 : 0, + ); + } + } + + return $result ?: false; + } + + /** + * @param int $id + * @param int $idLang + * @return array|false + */ + public function getAmenityInfoById($id, $idLang = 0) + { + if (!$idLang) { + $idLang = Context::getContext()->language->id; + } + return Db::getInstance()->getRow( + 'SELECT ha.`id_amenity`, hal.`name` + FROM `'._DB_PREFIX_.'htl_amenity` ha + LEFT JOIN `'._DB_PREFIX_.'htl_amenity_lang` hal + ON (hal.`id_amenity` = ha.`id_amenity` AND hal.`id_lang` = '.(int)$idLang.') + WHERE ha.`id_amenity` = '.(int)$id + ); + } + + /** + * @param int $parentId + * @return array|false + */ + public function getChildAmenitiesByParentAmenityId($parentId) + { + return Db::getInstance()->executeS( + 'SELECT `id_amenity` FROM `'._DB_PREFIX_.'htl_amenity` WHERE `id_parent` = '.(int)$parentId + ); + } + + /** + * Delete a category and all its child amenities. + * + * @param int $deleteId + * @return bool + */ + public function deleteCategory($idCategory) + { + $rows = Db::getInstance()->executeS( + 'SELECT `id_amenity` FROM `'._DB_PREFIX_.'htl_amenity` + WHERE `id_parent` = '.(int)$idCategory.' OR `id_amenity` = '.(int)$idCategory + ); + + if ($rows) { + foreach ($rows as $row) { + $objHotelAmenities = new HotelAmenities((int)$row['id_amenity']); + $objHotelAmenities->delete(); + } + } + + return true; + } + + /** + * @param string $query + * @param int $idLang + * @return array|false + */ + public function searchByName($query, $idLang = 0) + { + if (!$idLang) { + $idLang = Context::getContext()->language->id; + } + + return Db::getInstance()->executeS( + 'SELECT ha.*, hal.* FROM `'._DB_PREFIX_.'htl_amenity` ha + LEFT JOIN `'._DB_PREFIX_.'htl_amenity_lang` hal ON hal.`id_amenity` = ha.`id_amenity` + WHERE hal.`name` LIKE \'%'.pSQL($query).'%\' + AND hal.`id_lang` = '.(int)$idLang + ); + } + + /** + * Return all amenity categories (id_parent = 0), ordered by position. + * + * @param int $idLang + * @return array + */ + public static function getCategories($idLang = 0) + { + if (!$idLang) { + $idLang = Context::getContext()->language->id; + } + + return Db::getInstance()->executeS( + 'SELECT ha.`id_amenity`, hal.`name` + FROM `'._DB_PREFIX_.'htl_amenity` ha + LEFT JOIN `'._DB_PREFIX_.'htl_amenity_lang` hal + ON (hal.`id_amenity` = ha.`id_amenity` AND hal.`id_lang` = '.(int)$idLang.') + WHERE ha.`id_parent` = 0 + ORDER BY ha.`position` ASC' + ) ?: array(); + } + + /** + * Return all active child amenities (id_parent > 0). + * + * @param int $idLang + * @return array + */ + public static function getAmenities($idLang = 0) + { + if (!$idLang) { + $idLang = Context::getContext()->language->id; + } + + return Db::getInstance()->executeS( + 'SELECT ha.`id_amenity`, hal.`name` + FROM `'._DB_PREFIX_.'htl_amenity` ha + LEFT JOIN `'._DB_PREFIX_.'htl_amenity_lang` hal + ON (hal.`id_amenity` = ha.`id_amenity` AND hal.`id_lang` = '.(int)$idLang.') + WHERE ha.`id_parent` > 0 + AND ha.`active` = 1 + ORDER BY hal.`name` ASC' + ) ?: array(); + } + + /** + * Return image path for amenity logo stored in views/img/hotel_amenities/. + * + * @param int $id + * @return string + */ + public static function getAmenityImagePath($id) + { + return _MODULE_DIR_.'hotelreservationsystem/views/img/hotel_amenities/'.(int)$id.'.jpg'; + } +} diff --git a/modules/hotelreservationsystem/classes/HotelBedType.php b/modules/hotelreservationsystem/classes/HotelBedType.php deleted file mode 100644 index 13d47d822..000000000 --- a/modules/hotelreservationsystem/classes/HotelBedType.php +++ /dev/null @@ -1,62 +0,0 @@ - 'htl_bed_type', - 'primary' => 'id_bed_type', - 'multilang' => true, - 'fields' => array( - 'length' => array('type' => self::TYPE_FLOAT, 'validate' => 'isUnsignedFloat'), - 'width' => array('type' => self::TYPE_FLOAT, 'validate' => 'isUnsignedFloat'), - // lang fields - 'name' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isCatalogName', 'required' => true, 'size' => 128), - ), - ); - - public function getAllBedTypes($idLang) - { - if (!$idLang) { - $idLang = Context::getContext()->language->id; - } - - $sql = 'SELECT hbt.*, hbtl.`name` FROM `'._DB_PREFIX_.$this->table.'` hbt - LEFT JOIN `'._DB_PREFIX_.$this->table.'_lang` hbtl ON hbt.`id_bed_type` = hbtl.`id_bed_type` - WHERE 1 AND hbtl.`id_lang` ='.(int) $idLang; - - return Db::getInstance()->executeS($sql); - } - - public function delete() - { - $objHotelRoomTypeBedType = new HotelRoomTypeBedType(); - $objHotelRoomTypeBedType->deleteRoomTypeBedTypes($this->id); - - return parent::delete(); - } -} diff --git a/modules/hotelreservationsystem/classes/HotelBookingDetail.php b/modules/hotelreservationsystem/classes/HotelBookingDetail.php index 8a6f7916e..58f205dfb 100644 --- a/modules/hotelreservationsystem/classes/HotelBookingDetail.php +++ b/modules/hotelreservationsystem/classes/HotelBookingDetail.php @@ -1779,19 +1779,15 @@ class HotelBookingDetail extends ObjectModel if (!$only_search_data) { if (!empty($bookingData)) { foreach ($bookingData['rm_data'] as $key => $value) { - $product_feature = Product::getFrontFeaturesStatic($context->language->id, $value['id_product']); - $prod_amen = array(); + // featured amenities for display in room type list + $product_feature = HotelRoomTypeAmenities::getAmenities( + $value['id_product'], + $context->language->id, + true + ); if (!empty($amenities) && $amenities) { - $prod_amen = $amenities; - foreach ($product_feature as $a_key => $a_val) { - if (($pa_key = array_search($a_val['id_feature'], $prod_amen)) !== false) { - unset($prod_amen[$pa_key]); - if (empty($prod_amen)) { - break; - } - } - } - if (!empty($prod_amen)) { + $roomAmenityIds = array_column(HotelRoomTypeAmenities::getAmenities($value['id_product']), 'id'); + if (array_diff($amenities, $roomAmenityIds)) { unset($bookingData['rm_data'][$key]); continue; } diff --git a/modules/hotelreservationsystem/classes/HotelBranchAmenities.php b/modules/hotelreservationsystem/classes/HotelBranchAmenities.php new file mode 100644 index 000000000..e3c999fba --- /dev/null +++ b/modules/hotelreservationsystem/classes/HotelBranchAmenities.php @@ -0,0 +1,146 @@ + 'htl_branch_amenity', + 'primary' => 'id_branch_amenity', + 'fields' => array( + 'id_hotel' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), + 'amenity_id' => array('type' => self::TYPE_INT), + 'is_featured' => array('type' => self::TYPE_INT), + 'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate', 'copy_post' => false), + 'date_upd' => array('type' => self::TYPE_DATE, 'validate' => 'isDate', 'copy_post' => false), + ), + ); + + /** + * @param int $idHotel + * @param int $idLang defaults to current context language + * @param bool $featuredOnly true = is_featured=1 only; false = all active child amenities + * @return array + */ + public static function getAmenities($idHotel, $idLang = 0, $featuredOnly = false) + { + if (!$idLang) { + $idLang = Context::getContext()->language->id; + } + + $filter = $featuredOnly ? 'AND hba.`is_featured` = 1' : ''; + + return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( + 'SELECT ha.`id_amenity` AS `id`, ha.`logo_type`, ha.`logo`, hal.`name` + FROM `'._DB_PREFIX_.'htl_branch_amenity` hba + INNER JOIN `'._DB_PREFIX_.'htl_amenity` ha + ON (ha.`id_amenity` = hba.`amenity_id`) + INNER JOIN `'._DB_PREFIX_.'htl_amenity_lang` hal + ON (hal.`id_amenity` = hba.`amenity_id` AND hal.`id_lang` = '.(int)$idLang.') + WHERE hba.`id_hotel` = '.(int)$idHotel.' + AND ha.`active` = 1 + AND ha.`id_parent` > 0 + '.$filter.' + ORDER BY ha.`position` ASC, hal.`name` ASC' + ) ?: array(); + } + + /** + * Prepare amenities tree data for a hotel form, with selection state. + * + * @param int $idHotel + * @param int $idLang defaults to current context language + * @return array + */ + public static function getBranchAmenitiesTreeData($idHotel, $idLang = 0) + { + if (!$idLang) { + $idLang = Context::getContext()->language->id; + } + + $objHotelAmenities = new HotelAmenities(); + $amenities = $objHotelAmenities->hotelBranchSelectedAmenities( + array_column(self::getAmenities($idHotel), 'id'), + $idLang + ); + + if (!$amenities) { + return array(); + } + + foreach ($amenities as $idAmenity => &$amenity) { + $amenity['value'] = $idAmenity; + $amenity['input_name'] = 'id_amenity_parents'; + + $selectedChildAmenities = 0; + if (!empty($amenity['children'])) { + foreach ($amenity['children'] as &$childAmenity) { + $childAmenity['value'] = $childAmenity['id']; + $childAmenity['input_name'] = 'id_amenities'; + if (!empty($childAmenity['selected'])) { + $selectedChildAmenities++; + } + } + + if ($selectedChildAmenities === count($amenity['children'])) { + $amenity['selected'] = true; + } + } + } + + return $amenities; + } + + /** + * Delete existing assignments then save new ones for a hotel. + * + * @param int $idHotel + * @param array $amenityIds + * @param array $featuredIds amenity IDs that should be marked is_featured=1 + * @return bool + */ + public function saveBranchAmenities($idHotel, array $amenityIds, array $featuredIds = array()) + { + Db::getInstance()->delete('htl_branch_amenity', '`id_hotel` = '.(int)$idHotel); + + $featuredSet = array_flip(array_map('intval', $featuredIds)); + + foreach ($amenityIds as $amenityId) { + $objHotelBranchAmenities = new self(); + $objHotelBranchAmenities->id_hotel = (int)$idHotel; + $objHotelBranchAmenities->amenity_id = (int)$amenityId; + $objHotelBranchAmenities->is_featured = isset($featuredSet[$amenityId]) ? 1 : 0; + if (!$objHotelBranchAmenities->save()) { + return false; + } + } + + return true; + } +} diff --git a/modules/hotelreservationsystem/classes/HotelBranchFeatures.php b/modules/hotelreservationsystem/classes/HotelBranchFeatures.php deleted file mode 100644 index 9892de05d..000000000 --- a/modules/hotelreservationsystem/classes/HotelBranchFeatures.php +++ /dev/null @@ -1,69 +0,0 @@ - 'htl_branch_features', - 'primary' => 'id', - 'fields' => array( - 'id_hotel' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), - 'feature_id' => array('type' => self::TYPE_STRING), - 'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate', 'copy_post' => false), - 'date_upd' => array('type' => self::TYPE_DATE, 'validate' => 'isDate', 'copy_post' => false), - )); - - /** - * [deleteBranchFeaturesByHotelId : For deleting features of a hotel by hotel id] - * @param [int] $idHotel [Hotel's id , which hotel's features to be deleted] - * @return [Boolean] [true if deleted or false if no deleted] - */ - public function deleteBranchFeaturesByHotelId($idHotel) - { - return Db::getInstance()->delete('htl_branch_features', '`id_hotel` = '.(int) $idHotel); - } - - /** - * [assignFeaturesToHotel : For assigning Hotel features to a hotel] - * @param [int] $idHotel [Hotel's id , To which features to be assigned] - * @param [Array] $features [array of features to be assigned to the hotel] - * @return [Boolean] [true] - */ - public function assignFeaturesToHotel($idHotel, $features) - { - if ($features) { - foreach ($features as $feature) { - $obj_htl_features = new HotelBranchFeatures(); - $obj_htl_features->id_hotel = $idHotel; - $obj_htl_features->feature_id = $feature; - $obj_htl_features->save(); - } - } - return true; - } -} diff --git a/modules/hotelreservationsystem/classes/HotelBranchInformation.php b/modules/hotelreservationsystem/classes/HotelBranchInformation.php index 0797c7035..802ae8a5e 100644 --- a/modules/hotelreservationsystem/classes/HotelBranchInformation.php +++ b/modules/hotelreservationsystem/classes/HotelBranchInformation.php @@ -128,8 +128,8 @@ class HotelBranchInformation extends ObjectModel 'resource' => 'image', 'fields' => array('id' => array()) ), - 'hotel_features' => array( - 'resource' => 'hotel_feature', + 'hotel_amenities' => array( + 'resource' => 'hotel_amenity', 'fields' => array('id' => array('required' => true)) ), 'hotel_refund_rules' => array( @@ -506,31 +506,25 @@ class HotelBranchInformation extends ObjectModel $sql = 'SELECT hbi.`id`, hbl.`hotel_name` FROM `'._DB_PREFIX_.'htl_branch_info` hbi LEFT JOIN `'._DB_PREFIX_.'htl_branch_info_lang` hbl ON (hbl.`id` = hbi.`id` AND hbl.`id_lang` = '.(int)$idLang.') - WHERE hbi.`id` NOT IN (SELECT DISTINCT id_hotel FROM `'._DB_PREFIX_.'htl_branch_features`)'; + WHERE hbi.`id` NOT IN (SELECT DISTINCT id_hotel FROM `'._DB_PREFIX_.'htl_branch_amenity`)'; return Db::getInstance()->executeS($sql); } /** - * [getFeaturesOfHotelByHotelId : To get assigned Features of a hotel by its id]. - * - * @param [type] $id_hotel [id of the hotel] - * - * @return [array | false] [If no feature found then returns false otherwise returns array of all features assigned to the hotel] + * @param int $id_hotel + * @return array|false */ - public function getFeaturesOfHotelByHotelId($id_hotel) + public function getAmenitiesOfHotelByHotelId($id_hotel) { return Db::getInstance()->executeS( - 'SELECT feature_id FROM `'._DB_PREFIX_.'htl_branch_features` WHERE id_hotel='.(int)$id_hotel + 'SELECT amenity_id FROM `'._DB_PREFIX_.'htl_branch_amenity` WHERE id_hotel='.(int)$id_hotel ); } /** - * [getFeaturesOfHotelByHotelId : To get Hotel's id by its category id]. - * - * @param [int] $id_category [id_category of the hotel] - * - * @return [array | int] [If no hotel found then returns false otherwise returns id of the hotel] + * @param int $id_category + * @return int|false */ public static function getHotelIdByIdCategory($id_category) { @@ -548,11 +542,8 @@ class HotelBranchInformation extends ObjectModel } /** - * [getFeaturesOfHotelByHotelId : To get Category Information by its id_category]. - * - * @param [int] $id_category [id of the category , Which innformation is wanted] - * - * @return [array | false] [If no Category found then returns false otherwise returns array of information of that category] + * @param int $id_category + * @return array|false */ public function getCategoryDataByIdCategory($id_category) { @@ -802,11 +793,11 @@ class HotelBranchInformation extends ObjectModel } } } - $objHotelfeatures = new HotelBranchFeatures(); + $objHotelAmenities = new HotelBranchAmenities(); $objHotelImage = new HotelImage(); - if (!$objHotelfeatures->deleteBranchFeaturesByHotelId($idHotel)) { + if (!$objHotelAmenities->saveBranchAmenities($idHotel, array())) { $contextController->errors[] = $this->moduleInstance->l( - 'Some error has occurred while deleting hotel feature data.', + 'Some error has occurred while deleting hotel amenity data.', 'HotelBranchInformation' ); } @@ -1003,25 +994,25 @@ class HotelBranchInformation extends ObjectModel return $ids; } - // Webservice:: function to prepare id parameter for hotel features in a hotel api - public function getWsHotelFeatures() + // Webservice:: function to prepare id parameter for hotel amenities in a hotel api + public function getWsHotelAmenities() { return Db::getInstance()->executeS( - 'SELECT `feature_id` as `id` FROM `'._DB_PREFIX_.'htl_branch_features` WHERE `id_hotel` = '.(int)$this->id. - ' ORDER BY `feature_id` ASC' + 'SELECT `amenity_id` as `id` FROM `'._DB_PREFIX_.'htl_branch_amenity` WHERE `id_hotel` = '.(int)$this->id. + ' ORDER BY `amenity_id` ASC' ); } - // Webservice:: function to prepare id parameter for hotel features in a hotel api - public function setWsHotelFeatures($branchFeatures) + // Webservice:: function to set hotel amenities in a hotel api + public function setWsHotelAmenities($branchAmenities) { Db::getInstance()->execute(' - DELETE FROM `'._DB_PREFIX_.'htl_branch_features` + DELETE FROM `'._DB_PREFIX_.'htl_branch_amenity` WHERE `id_hotel` = '.(int)$this->id ); - foreach ($branchFeatures as $feature) { - Db::getInstance()->execute('INSERT INTO `'._DB_PREFIX_.'htl_branch_features` (`id_hotel`, `feature_id`, `date_add`, `date_upd`) VALUES ('.(int)$this->id.', '.(int)$feature['id'].', NOW(), NOW())'); + foreach ($branchAmenities as $amenity) { + Db::getInstance()->execute('INSERT INTO `'._DB_PREFIX_.'htl_branch_amenity` (`id_hotel`, `amenity_id`, `date_add`, `date_upd`) VALUES ('.(int)$this->id.', '.(int)$amenity['id'].', NOW(), NOW())'); } return true; diff --git a/modules/hotelreservationsystem/classes/HotelCartBookingData.php b/modules/hotelreservationsystem/classes/HotelCartBookingData.php index a6a0800bf..f0e62109a 100644 --- a/modules/hotelreservationsystem/classes/HotelCartBookingData.php +++ b/modules/hotelreservationsystem/classes/HotelCartBookingData.php @@ -1535,7 +1535,7 @@ class HotelCartBookingData extends ObjectModel $objCartBooking = new self(); $objRoomType = new HotelRoomType(); $objHotelBranch = new HotelBranchInformation(); - $objHtlFeatures = new HotelFeatures(); + $objHtlFeatures = new HotelAmenities(); $objCartBookingData = new HotelCartBookingData(); $objRoomDemands = new HotelRoomTypeDemand(); $objRoomTypeServiceProduct = new RoomTypeServiceProduct(); @@ -1609,17 +1609,16 @@ class HotelCartBookingData extends ObjectModel $addressInfo['country'].', '.$addressInfo['postcode']; - // append hotel features - if ($hotelFeaureIds = $objHotelBranch->getFeaturesOfHotelByHotelId($roomDetail['id_hotel'])) { - $hotelFeatures = array(); - foreach ($hotelFeaureIds as $value) { - $htlFeatureInfo = $objHtlFeatures->getFeatureInfoById($value['feature_id']); - if ($htlFeatureInfo = $objHtlFeatures->getFeatureInfoById($value['feature_id'])) { - $hotelFeatures[] = $htlFeatureInfo['name']; + // append hotel amenities + if ($hotelAmenityIds = $objHotelBranch->getAmenitiesOfHotelByHotelId($roomDetail['id_hotel'])) { + $hotelAmenities = array(); + foreach ($hotelAmenityIds as $value) { + if ($htlAmenityInfo = $objHtlFeatures->getAmenityInfoById($value['amenity_id'])) { + $hotelAmenities[] = $htlAmenityInfo['name']; } } - if ($hotelFeatures) { - $hotelInfo['htl_features'] = $hotelFeatures; + if ($hotelAmenities) { + $hotelInfo['htl_features'] = $hotelAmenities; } } // append roomtype features diff --git a/modules/hotelreservationsystem/classes/HotelFeatures.php b/modules/hotelreservationsystem/classes/HotelFeatures.php deleted file mode 100644 index dc219551b..000000000 --- a/modules/hotelreservationsystem/classes/HotelFeatures.php +++ /dev/null @@ -1,228 +0,0 @@ - 'htl_features', - 'primary' => 'id', - 'multilang' => true, - 'fields' => array( - 'parent_feature_id' => array('type' => self::TYPE_INT, 'required' => true), - 'position' => array('type' => self::TYPE_INT), - 'active' => array('type' => self::TYPE_INT, 'required' => true), - 'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate', 'copy_post' => false), - 'date_upd' => array('type' => self::TYPE_DATE, 'validate' => 'isDate', 'copy_post' => false), - //lang fields - 'name' => array('type' => self::TYPE_STRING, 'lang' => true, 'required' => true), - ) - ); - - protected $webserviceParameters = array( - 'objectsNodeName' => 'hotel_features', - 'objectNodeName' => 'hotel_feature', - 'fields' => array(), - ); - - public function delete() - { - if ($id = $this->id) { - if (Db::getInstance()->delete('htl_branch_features', '`feature_id` = '.(int) $id)) { - return parent::delete(); - } - } - return false; - } - - /** - * [getFeatureInfoById :: To get feature in formation by its id] - * @param [int] $id [description] - * @return [false | array] [Returns false if no data found otherwise returns array of the information of the - * feature] - */ - public function getFeatureInfoById($id, $idLang = 0) - { - if (!$idLang) { - $idLang = Context::getContext()->language->id; - } - return Db::getInstance()->getRow( - 'SELECT hf.`id` , hfl.`name` - FROM `'._DB_PREFIX_.'htl_features` hf - LEFT JOIN `'._DB_PREFIX_.'htl_features_lang` hfl - ON (hfl.`id` = hf.`id` AND hfl.`id_lang` = '.(int)$idLang.') - WHERE hf.`id`='.(int) $id - ); - } - - /** - * [HotelAllCommonFeaturesArray :: To get array of all hotel features information according to parents feature and - * children features under parent feature] - * @return [boolean] [If data found returns array of all common features as parent then children under this parent] - */ - public function HotelAllCommonFeaturesArray($idLang = 0) - { - if (!$idLang) { - $idLang = Context::getContext()->language->id; - } - $result = array(); - if ($parentFeatures = Db::getInstance()->executeS( - 'SELECT hf.`id`, hf.`position`, hfl.`name` - FROM `'._DB_PREFIX_.'htl_features` hf - LEFT JOIN `'._DB_PREFIX_.'htl_features_lang` hfl - ON (hfl.`id` = hf.`id` AND hfl.`id_lang` = '.(int)$idLang.') - WHERE hf.`parent_feature_id`=0 order by position' - )) { - foreach ($parentFeatures as $value) { - $result[$value['id']]['name'] = $value['name']; - $result[$value['id']]['id'] = $value['id']; - $result[$value['id']]['position'] = $value['position']; - if ($childFeatures = Db::getInstance()->executeS( - 'SELECT hf.`id`, hfl.`name` - FROM `'._DB_PREFIX_.'htl_features` hf - LEFT JOIN `'._DB_PREFIX_.'htl_features_lang` hfl - ON (hfl.`id` = hf.`id` AND hfl.`id_lang` = '.(int)$idLang.') - WHERE hf.`parent_feature_id`='.(int) $value['id'] - )) { - foreach ($childFeatures as $value1) { - $result[$value['id']]['children'][] = $value1; - } - } - } - } - if (!$result) { - return false; - } - return $result; - } - - /** - * [deleteHotelFeatures :: Deletes the feature which id is $deleteId and also delete all the child features which - * parent id is $deleteId] - * @param [int] $deleteId [id(primary_key) of the htl_features table] - * @return [boolean] [true if deleted otherwise false] - */ - public function deleteHotelFeatures($deleteId, $deleteOnlyChilds = 0) - { - $sql = 'SELECT `id` FROM `'._DB_PREFIX_.'htl_features` WHERE `parent_feature_id`='.(int) $deleteId; - - if (!$deleteOnlyChilds) { - $sql .= ' OR `id`='.(int) $deleteId; - } - if ($idsToDetele = Db::getInstance()->executeS($sql)) { - foreach ($idsToDetele as $value) { - $objHotelFeatures = new HotelFeatures($value['id']); - $objHotelFeatures->delete(); - } - } - return true; - } - - /** - * [HotelBranchSelectedFeaturesArray :: To get array of all hotel features information according to parents and - * children including which child features are selected for a hotel] - * @param [array] $htl_features [array containing information of the features of a hotel] - * @return [boolean] [If data found returns array of all common features as parent then children under this parent - * and also set an index in the array that defines whether the child feature is selected for the hotel or not] - */ - public function HotelBranchSelectedFeaturesArray($htl_features, $idLang = 0) - { - if (!$idLang) { - $idLang = Context::getContext()->language->id; - } - $result = array(); - if ($parentFeatures = Db::getInstance()->executeS( - 'SELECT hf.`id`, hfl.`name` - FROM `'._DB_PREFIX_.'htl_features` hf - LEFT JOIN `'._DB_PREFIX_.'htl_features_lang` hfl - ON (hfl.`id` = hf.`id` AND hfl.`id_lang` = '.(int)$idLang.') - WHERE hf.`parent_feature_id`=0' - )) { - foreach ($parentFeatures as $value) { - $result[$value['id']]['name'] = $value['name']; - if ($childFeatures = Db::getInstance()->executeS( - 'SELECT hf.`id`, hfl.`name` - FROM `'._DB_PREFIX_.'htl_features` hf - LEFT JOIN `'._DB_PREFIX_.'htl_features_lang` hfl - ON (hfl.`id` = hf.`id` AND hfl.`id_lang` = '.(int)$idLang.') - WHERE hf.`parent_feature_id`='.(int) $value['id'] - )) { - foreach ($childFeatures as $value1) { - $flag =0; - if ($htl_features) { - foreach ($htl_features as $ftr) { - if ($value1['id'] == $ftr['feature_id']) { - $flag = 1; - } - } - } - if ($flag) { - $value1['selected'] = 1; - } else { - $value1['selected'] = 0; - } - - $result[$value['id']]['children'][] = $value1; - } - } - } - } - if (!$result) { - return false; - } - return $result; - } - - public function getChildFeaturesByParentFeatureId($parent_feature_id) - { - return Db::getInstance()->executeS( - 'SELECT `id` FROM `'._DB_PREFIX_.'htl_features` WHERE `parent_feature_id`='.(int)$parent_feature_id - ); - } - - public function updateHotelFeatureInfoByParentFeatureId($parent_feature_id, $update_params) - { - return Db::getInstance()->update('htl_features', $update_params, 'id='.(int) $parent_feature_id); - } - - public function searchByName($query, $idLang = false) - { - if (!$idLang) { - $idLang = Context::getContext()->language->id; - } - - return Db::getInstance()->executeS( - 'SELECT hf.*, hfl.* FROM `'._DB_PREFIX_.'htl_features` hf - LEFT JOIN `'._DB_PREFIX_.'htl_features_lang` hfl - ON hfl.`id` = hf.`id` - WHERE hfl.`name` LIKE \'%'.pSQL($query).'%\' - AND hfl.`id_lang`='.(int) $idLang - ); - } -} diff --git a/modules/hotelreservationsystem/classes/HotelHelper.php b/modules/hotelreservationsystem/classes/HotelHelper.php index f7f4f1c2b..68c477b84 100644 --- a/modules/hotelreservationsystem/classes/HotelHelper.php +++ b/modules/hotelreservationsystem/classes/HotelHelper.php @@ -43,9 +43,9 @@ class HotelHelper Media::addJsDef($jsVars); } - public function insertHotelCommonFeatures() + public function insertHotelCommonAmenities() { - $parent_features_arr = array( + $parent_amenities_arr = array( 'Business Services' => array( 'name' => array( 'en' => 'Business Services', @@ -55,7 +55,7 @@ class HotelHelper 'ru' => 'Бизнес-услуги', 'es' => 'Servicios empresariales', ), - 'features' => array( + 'amenities' => array( array( 'en' => 'Business Center', 'nl' => 'Businesscentrum', @@ -123,7 +123,7 @@ class HotelHelper 'ru' => 'Дополнительные услуги', 'es' => 'Servicios complementarios', ), - 'features' => array( + 'amenities' => array( array( 'en' => 'Internet Access Free', 'nl' => 'Gratis internettoegang', @@ -175,7 +175,7 @@ class HotelHelper 'ru' => 'Развлечения', 'es' => 'Entretenimiento', ), - 'features' => array( + 'amenities' => array( array( 'en' => 'DiscoTheatre', 'nl' => 'Discotheek/theater', @@ -243,7 +243,7 @@ class HotelHelper 'ru' => 'Удобства', 'es' => 'Instalaciones', ), - 'features' => array( + 'amenities' => array( array( 'en' => 'Laundry Service', 'nl' => 'Wasservice', @@ -359,7 +359,7 @@ class HotelHelper 'ru' => 'Общие услуги', 'es' => 'Servicios generales', ), - 'features' => array( + 'amenities' => array( array( 'en' => 'Room Service', 'nl' => 'Roomservice', @@ -443,7 +443,7 @@ class HotelHelper 'ru' => 'В помещении', 'es' => 'Interior', ), - 'features' => array( + 'amenities' => array( array( 'en' => 'Parking', 'nl' => 'Parkeren', @@ -479,7 +479,7 @@ class HotelHelper 'ru' => 'Интернет', 'es' => 'Internet', ), - 'features' => array( + 'amenities' => array( array( 'en' => 'Internet Access-Surcharge', 'nl' => 'Internettoegang - toeslag', @@ -507,7 +507,7 @@ class HotelHelper 'ru' => 'На открытом воздухе', 'es' => 'Al aire libre', ), - 'features' => array( + 'amenities' => array( array( 'en' => 'Gardens', 'nl' => 'Tuinen', @@ -591,7 +591,7 @@ class HotelHelper 'ru' => 'Парковка', 'es' => 'Aparcamiento', ), - 'features' => array( + 'amenities' => array( array( 'en' => 'Parking (Surcharge)', 'nl' => 'Parkeren (toeslag)', @@ -627,7 +627,7 @@ class HotelHelper 'ru' => 'Спорт и отдых', 'es' => 'Deportes y recreación', ), - 'features' => array( + 'amenities' => array( array( 'en' => 'Health Club / Gym Facility Available', 'nl' => 'Health Club / Sportschool beschikbaar', @@ -823,7 +823,7 @@ class HotelHelper 'ru' => 'Водные удобства', 'es' => 'Instalaciones acuáticas', ), - 'features' => array( + 'amenities' => array( array( 'en' => 'Swimming Pool', 'nl' => 'Zwembad', @@ -875,7 +875,7 @@ class HotelHelper 'ru' => 'Вино и ужин', 'es' => 'Vino y cena', ), - 'features' => array( + 'amenities' => array( array( 'en' => 'Bar / Lounge', 'nl' => 'Bar / Lounge', @@ -977,34 +977,46 @@ class HotelHelper ); // lang fields $languages = Language::getLanguages(false); + $imgDir = dirname(__FILE__).'/../views/img/hotel_amenities/'; $i = 1; - foreach ($parent_features_arr as $key => $value) { - $obj_feature = new HotelFeatures(); + $defaultImageIndex = 0; + foreach ($parent_amenities_arr as $key => $value) { + $obj_amenity = new HotelAmenities(); foreach ($languages as $lang) { if (isset($value['name'][$lang['iso_code']])) { - $obj_feature->name[$lang['id_lang']] = $value['name'][$lang['iso_code']]; + $obj_amenity->name[$lang['id_lang']] = $value['name'][$lang['iso_code']]; } else { - $obj_feature->name[$lang['id_lang']] = $value['name']['en']; + $obj_amenity->name[$lang['id_lang']] = $value['name']['en']; } } - $obj_feature->active = 1; - $obj_feature->position = $i; - $obj_feature->parent_feature_id = 0; - $obj_feature->save(); - $parent_feature_id = $obj_feature->id; - foreach ($value['features'] as $val) { - $obj_feature = new HotelFeatures(); + $obj_amenity->active = 1; + $obj_amenity->position = $i; + $obj_amenity->id_parent = 0; + $obj_amenity->save(); + $idParent = $obj_amenity->id; + foreach ($value['amenities'] as $val) { + ++$defaultImageIndex; + $obj_amenity = new HotelAmenities(); foreach ($languages as $lang) { if (isset($val[$lang['iso_code']])) { - $obj_feature->name[$lang['id_lang']] = $val[$lang['iso_code']]; + $obj_amenity->name[$lang['id_lang']] = $val[$lang['iso_code']]; } else { - $obj_feature->name[$lang['id_lang']] = $val['en']; + $obj_amenity->name[$lang['id_lang']] = $val['en']; + } + } + $obj_amenity->active = 1; + $obj_amenity->id_parent = $idParent; + $obj_amenity->save(); + + $srcImg = $imgDir.'_default/'.$defaultImageIndex.'.jpg'; + if (file_exists($srcImg)) { + if (ImageManager::resize($srcImg, $imgDir.$obj_amenity->id.'.jpg')) { + $obj_amenity->logo_type = 'image'; + $obj_amenity->logo = $obj_amenity->id.'.jpg'; + $obj_amenity->save(); } } - $obj_feature->active = 1; - $obj_feature->parent_feature_id = $parent_feature_id; - $obj_feature->save(); } ++$i; } @@ -1139,233 +1151,57 @@ class HotelHelper return true; } + /** + * Seed default core room features and values used by room types. + * + * @return bool + */ public function createHotelRoomDefaultFeatures() { - $htl_room_ftrs = array( - 'Wi-Fi' => array( - 'en' => 'Wi-Fi', - 'nl' => 'Wi-Fi', - 'fr' => 'Wi-Fi', - 'de' => 'Wi-Fi', - 'ru' => 'Wi-Fi', - 'es' => 'Wi-Fi' - ), - 'News Paper' => array( - 'en' => 'News Paper', - 'nl' => 'Krant', - 'fr' => 'Journal', - 'de' => 'Zeitung', - 'ru' => 'Газета', - 'es' => 'Periódico' - ), - 'Power BackUp' => array( - 'en' => 'Power BackUp', - 'nl' => 'Stroomvoorziening', - 'fr' => 'Alimentation de secours', - 'de' => 'Notstromversorgung', - 'ru' => 'Резервное электропитание', - 'es' => 'Energía de respaldo' - ), - 'Refrigerator' => array( - 'en' => 'Refrigerator', - 'nl' => 'Koelkast', - 'fr' => 'Réfrigérateur', - 'de' => 'Kühlschrank', - 'ru' => 'Холодильник', - 'es' => 'Refrigerador' - ), - 'Restaurant' => array( - 'en' => 'Restaurant', - 'nl' => 'Restaurant', - 'fr' => 'Restaurant', - 'de' => 'Restaurant', - 'ru' => 'Ресторан', - 'es' => 'Restaurante' - ), - 'Room Service' => array( - 'en' => 'Room Service', - 'nl' => 'Roomservice', - 'fr' => 'Service de chambre', - 'de' => 'Zimmerservice', - 'ru' => 'Обслуживание номеров', - 'es' => 'Servicio de habitaciones' - ), - 'Gym' => array( - 'en' => 'Gym', - 'nl' => 'Fitnessruimte', - 'fr' => 'Salle de sport', - 'de' => 'Fitnessraum', - 'ru' => 'Фитнес', - 'es' => 'Gimnasio' - ) - ); + $idLang = (int) Configuration::get('PS_LANG_DEFAULT'); + $position = 0; - // image value in rf/ folder - $pos = 1; - $languages = Language::getLanguages(true); - foreach ($htl_room_ftrs as $room_ftr_k => $room_ftr_v) { - $obj_feature = new Feature(); - foreach ($languages as $lang) { - if (isset($room_ftr_v[$lang['iso_code']])) { - $obj_feature->name[$lang['id_lang']] = $room_ftr_v[$lang['iso_code']]; - } else { - $obj_feature->name[$lang['id_lang']] = $room_ftr_v['en']; - } + foreach ($this->getDefaultRoomFeatures() as $featureName => $featureValues) { + $idFeature = (int) Feature::addFeatureImport($featureName, $position); + if (!$idFeature) { + return false; } - $obj_feature->position = $pos-1; - $obj_feature->save(); - if ($obj_feature->id) { - $obj_feature_value = new FeatureValue(); - $obj_feature_value->id_feature = $obj_feature->id; - foreach ($languages as $lang) { - $obj_feature_value->value[$lang['id_lang']] = $obj_feature->id.'.jpg'; - } - - $obj_feature_value->save(); - if ($obj_feature_value->id) { - if (file_exists(_PS_IMG_DIR_.'rf/'.$pos.'.jpg')) { - rename(_PS_IMG_DIR_.'rf/'.$pos.'.jpg', _PS_IMG_DIR_.'rf/'.$obj_feature->id.'.jpg'); - } + foreach ($featureValues as $featureValue) { + $idFeatureValue = (int) FeatureValue::addFeatureValueImport($idFeature, $featureValue, null, $idLang, false); + if (!$idFeatureValue) { + return false; } } - $pos++; + ++$position; } return true; } - public function createHotelDefaultBedTypes() + /** + * Return the default room feature/value seed set. + * + * @return array + */ + protected function getDefaultRoomFeatures() { - $htlBedTypes = array( - array( - 'length' => '6.25', - 'width' => '3.16', - 'name' => array( - 'en' => 'Twin Bed', - 'nl' => 'Eenpersoonsbed', - 'fr' => 'Lit simple', - 'de' => 'Einzelbett', - 'ru' => 'Односпальная кровать', - 'es' => 'Cama individual', - ), - ), - array( - 'length' => '6.66', - 'width' => '3.16', - 'name' => array( - 'en' => 'Twin XL Bed', - 'nl' => 'Eenpersoonsbed XL', - 'fr' => 'Lit simple XL', - 'de' => 'Einzelbett XL', - 'ru' => 'Односпальная кровать XL', - 'es' => 'Cama individual XL', - ), - ), - array( - 'length' => '6.25', - 'width' => '4.5', - 'name' => array( - 'en' => 'Full Bed', - 'nl' => 'Tweepersoonsbed', - 'fr' => 'Lit double', - 'de' => 'Doppelbett', - 'ru' => 'Двуспальная кровать', - 'es' => 'Cama doble', - ), - ), - array( - 'length' => '6.66', - 'width' => '5', - 'name' => array( - 'en' => 'Queen Bed', - 'nl' => 'Queen size bed', - 'fr' => 'Lit Queen', - 'de' => 'Queen-Size-Bett', - 'ru' => 'Кровать Queen Size', - 'es' => 'Cama Queen', - ), - ), - array( - 'length' => '6.66', - 'width' => '6.33', - 'name' => array( - 'en' => 'King Bed', - 'nl' => 'King size bed', - 'fr' => 'Lit King', - 'de' => 'King-Size-Bett', - 'ru' => 'Кровать King Size', - 'es' => 'Cama King', - ), - ), - array( - 'length' => '7', - 'width' => '6', - 'name' => array( - 'en' => 'California King Bed', - 'nl' => 'California King bed', - 'fr' => 'Lit California King', - 'de' => 'California King-Bett', - 'ru' => 'Калифорнийская кровать King Size', - 'es' => 'Cama California King', - ), - ), - array( - 'length' => '6.25', - 'width' => '3.16', - 'name' => array( - 'en' => 'Bunk Bed', - 'nl' => 'Stapelbed', - 'fr' => 'Lit superposé', - 'de' => 'Etagenbett', - 'ru' => 'Двухъярусная кровать', - 'es' => 'Litera', - ), - ), - array( - 'length' => '6.25', - 'width' => '4.5', - 'name' => array( - 'en' => 'Sofa Bed', - 'nl' => 'Slaapbank', - 'fr' => 'Canapé-lit', - 'de' => 'Schlafsofa', - 'ru' => 'Диван-кровать', - 'es' => 'Sofá cama', - ), - ), - array( - 'length' => '6.66', - 'width' => '5', - 'name' => array( - 'en' => 'Murphy Bed', - 'nl' => 'Inklapbed', - 'fr' => 'Lit escamotable', - 'de' => 'Klappbett', - 'ru' => 'Откидная кровать', - 'es' => 'Cama abatible', - ), - ), + return array( + 'Bed Type' => array('Single', 'Double', 'Queen', 'King', 'Super King', 'Twin', 'Bunk Bed', 'Sofa Bed', 'Futon', 'Murphy Bed', 'Water Bed'), + 'Extra Bed Available' => array('Yes', 'No', 'On Request', 'Chargeable'), + 'Crib/Cot Available' => array('Yes', 'No', 'On Request'), + 'Room Size' => array('150 sq ft', '200 sq ft', '300 sq ft', '400 sq ft', '500 sq ft', '600 sq ft', '800 sq ft', '1000+ sq ft'), + 'View' => array('Sea/Ocean View', 'Garden View', 'City View', 'Pool View', 'Mountain View', 'Lake View', 'River View', 'Park View', 'Courtyard View', 'Desert View', 'No View/Interior'), + 'Balcony Type' => array('Private Balcony', 'Shared Terrace', 'Juliet Balcony', 'Rooftop Access', 'Patio', 'Veranda', 'None'), + 'Bathroom Type' => array('Private/Ensuite', 'Shared', 'Jack and Jill (shared between 2 rooms)', 'Half Bath'), + 'AC Type' => array('Split AC', 'Central AC', 'Window AC', 'No AC', 'Fan Only'), + 'Heating Type' => array('Central Heating', 'Room Heater', 'Underfloor Heating', 'Fireplace', 'No Heating'), + 'TV Type' => array('No TV', 'LED TV', 'Smart TV', 'OLED TV'), + 'Wi-Fi Speed' => array('No Wi-Fi', 'Basic', 'High Speed', 'Premium/Fiber'), + 'Smoke Detection' => array('Smoke Detector', 'Sprinkler', 'None'), + 'Smoking Policy' => array('Smoking Not Allowed', 'Smoking Allowed'), ); - - $languages = Language::getLanguages(true); - foreach ($htlBedTypes as $htlBedType) { - $objBedType = new HotelBedType(); - foreach ($languages as $lang) { - if (isset($htlBedType['name'][$lang['iso_code']])) { - $objBedType->name[$lang['id_lang']] = $htlBedType['name'][$lang['iso_code']]; - } else { - $objBedType->name[$lang['id_lang']] = $htlBedType['name']['en']; - } - - $objBedType->width = $htlBedType['width']; - $objBedType->length = $htlBedType['length']; - $objBedType->save(); - } - } - - return true; } public static function getPsProducts($id_lang, $start = 0, $limit = 0, $booking_product = null) @@ -1804,14 +1640,14 @@ class HotelHelper return $htl_id; } - public function saveDummyHotelFeatures($id_hotel) + public function saveDummyHotelAmenities($id_hotel) { - $branch_ftr_ids = array(1, 2, 4, 7, 8, 9, 11, 12, 14, 16, 17, 18, 21); - foreach ($branch_ftr_ids as $value_ftr) { - $htl_ftr_obj = new HotelBranchFeatures(); - $htl_ftr_obj->id_hotel = $id_hotel; - $htl_ftr_obj->feature_id = $value_ftr; - $htl_ftr_obj->save(); + $branch_amenity_ids = array(2, 4, 7, 8, 11, 12, 14, 16, 17, 18, 21); + foreach ($branch_amenity_ids as $amenityId) { + $objHotelAmenities = new HotelBranchAmenities(); + $objHotelAmenities->id_hotel = $id_hotel; + $objHotelAmenities->amenity_id = $amenityId; + $objHotelAmenities->save(); } } @@ -1820,7 +1656,6 @@ class HotelHelper $roomTypeDemoDataLang = array( array( 'price' => 1000, - 'id_bed_types' => array(4), 'en' => array( 'name' => 'General Rooms', 'description_short' => 'Our General Rooms offer space and comfort with multiple bedrooms and a cozy living area. Enjoy flat-screen TVs, complimentary Wi-Fi, and a kitchenette for a perfect family getaway.', @@ -1854,7 +1689,6 @@ class HotelHelper ), array( 'price' => 1500, - 'id_bed_types' => array(4, 5), 'en' => array( 'name' => 'Delux Rooms', 'description_short' => 'Enjoy lake views from our Deluxe Rooms with a king-sized bed, elegant furnishings, and a spacious sitting area. Perfect for guests seeking comfort, luxury, and modern amenities.', @@ -1888,7 +1722,6 @@ class HotelHelper ), array( 'price' => 2000, - 'id_bed_types' => array(5, 6), 'en' => array( 'name' => 'Executive Rooms', 'description_short' => 'Indulge in our Executive Rooms, featuring separate living and sleeping areas, a luxurious bathroom, and exclusive lounge access. Ideal for business travelers seeking privacy', @@ -1922,7 +1755,6 @@ class HotelHelper ), array( 'price' => 2500, - 'id_bed_types' => array(6, 8), 'en' => array( 'name' => 'Luxury Rooms', 'description_short' => 'Retreat to tranquility in our Luxury Rooms with expansive views. Featuring a queen-sized bed, workspace, and serene decor, perfect for business and leisure travelers alike.', @@ -1956,7 +1788,6 @@ class HotelHelper ), ); - $objHotelRoomTypeBedType = new HotelRoomTypeBedType(); $languages = Language::getLanguages(true); foreach ($roomTypeDemoDataLang as $key => $roomTypeData) { // Add Product @@ -2077,16 +1908,8 @@ class HotelHelper $htl_rm_type->save(); - // Add features to the product - $ftr_arr = array(0 => 1, 1 => 2, 2 => 3, 3 => 4); - $ftr_val_arr = array(0 => 1, 1 => 2, 2 => 3, 3 => 4); - foreach ($ftr_arr as $key_htl_ftr => $val_htl_ftr) { - $product->addFeaturesToDB($val_htl_ftr, $ftr_val_arr[$key_htl_ftr]); - } - // save advance payment information $this->saveAdvancedPaymentInfo($product_id); - $objHotelRoomTypeBedType->updateRoomTypeBedTypes($roomTypeData['id_bed_types'], $product_id); } } @@ -2474,7 +2297,7 @@ class HotelHelper { $htl_id = $this->saveDummyHotelBranchInfo(); $this->saveDummyHotelImages($htl_id); - $this->saveDummyHotelFeatures($htl_id); + $this->saveDummyHotelAmenities($htl_id); $this->saveDummyProductsAndRelatedInfo($htl_id); $this->saveDummyServiceProductsAndRelatedInfo(); diff --git a/modules/hotelreservationsystem/classes/HotelReservationSystemDb.php b/modules/hotelreservationsystem/classes/HotelReservationSystemDb.php index 4dfdabc01..e474ef68c 100644 --- a/modules/hotelreservationsystem/classes/HotelReservationSystemDb.php +++ b/modules/hotelreservationsystem/classes/HotelReservationSystemDb.php @@ -91,32 +91,50 @@ class HotelReservationSystemDb PRIMARY KEY (`id`) ) ENGINE="._MYSQL_ENGINE_." DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;", - "CREATE TABLE IF NOT EXISTS `"._DB_PREFIX_."htl_branch_features` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `id_hotel` int(10) unsigned NOT NULL, - `feature_id` varchar(255) DEFAULT NULL, - `date_add` datetime NOT NULL, - `date_upd` datetime NOT NULL, - PRIMARY KEY (`id`) - ) ENGINE="._MYSQL_ENGINE_." DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;", - - "CREATE TABLE IF NOT EXISTS `"._DB_PREFIX_."htl_features` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `parent_feature_id` int(10) unsigned NOT NULL, + "CREATE TABLE IF NOT EXISTS `"._DB_PREFIX_."htl_amenity` ( + `id_amenity` int(10) unsigned NOT NULL AUTO_INCREMENT, + `id_parent` int(10) unsigned NOT NULL, `position` int(10) unsigned NOT NULL, `active` int(2) NOT NULL DEFAULT '0', + `logo_type` varchar(10) NOT NULL DEFAULT 'icon', + `logo` varchar(255) NOT NULL DEFAULT '', `date_add` datetime NOT NULL, `date_upd` datetime NOT NULL, - PRIMARY KEY (`id`) + PRIMARY KEY (`id_amenity`) ) ENGINE="._MYSQL_ENGINE_." DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;", - "CREATE TABLE IF NOT EXISTS `"._DB_PREFIX_."htl_features_lang` ( - `id` int(10) unsigned NOT NULL, + "CREATE TABLE IF NOT EXISTS `"._DB_PREFIX_."htl_amenity_lang` ( + `id_amenity` int(10) unsigned NOT NULL, `id_lang` int(10) unsigned NOT NULL, `name` varchar(255) NOT NULL, - PRIMARY KEY (`id`, `id_lang`) + PRIMARY KEY (`id_amenity`, `id_lang`) ) ENGINE="._MYSQL_ENGINE_." DEFAULT CHARSET=utf8;", + "CREATE TABLE IF NOT EXISTS `"._DB_PREFIX_."htl_branch_amenity` ( + `id_branch_amenity` int(10) unsigned NOT NULL AUTO_INCREMENT, + `id_hotel` int(10) unsigned NOT NULL, + `amenity_id` int(10) unsigned NOT NULL, + `is_featured` tinyint(1) NOT NULL DEFAULT '0', + `date_add` datetime NOT NULL, + `date_upd` datetime NOT NULL, + PRIMARY KEY (`id_branch_amenity`), + CONSTRAINT `fk_htl_branch_amenity_amenity` FOREIGN KEY (`amenity_id`) + REFERENCES `"._DB_PREFIX_."htl_amenity` (`id_amenity`) ON DELETE CASCADE + ) ENGINE="._MYSQL_ENGINE_." DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;", + + "CREATE TABLE IF NOT EXISTS `"._DB_PREFIX_."htl_room_type_amenity` ( + `id_room_type_amenity` int(10) unsigned NOT NULL AUTO_INCREMENT, + `id_product` int(10) unsigned NOT NULL, + `amenity_id` int(10) unsigned NOT NULL, + `is_featured` tinyint(1) NOT NULL DEFAULT '0', + `date_add` datetime NOT NULL, + `date_upd` datetime NOT NULL, + PRIMARY KEY (`id_room_type_amenity`), + KEY `id_product` (`id_product`), + CONSTRAINT `fk_htl_room_type_amenity_amenity` FOREIGN KEY (`amenity_id`) + REFERENCES `"._DB_PREFIX_."htl_amenity` (`id_amenity`) ON DELETE CASCADE + ) ENGINE="._MYSQL_ENGINE_." DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;", + "CREATE TABLE IF NOT EXISTS `"._DB_PREFIX_."htl_cart_booking_data` ( `id` int(11) NOT NULL AUTO_INCREMENT, `id_cart` int(11) NOT NULL, @@ -494,26 +512,7 @@ class HotelReservationSystemDb `date_upd` datetime NOT NULL, PRIMARY KEY (`id_settings_link`) ) ENGINE="._MYSQL_ENGINE_." DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;", - "CREATE TABLE IF NOT EXISTS `"._DB_PREFIX_."htl_bed_type` ( - `id_bed_type` INT(11) NOT NULL AUTO_INCREMENT, - `length` DECIMAL(20,6) NOT NULL DEFAULT '0.000000', - `width` DECIMAL(20,6) NOT NULL DEFAULT '0.000000', - PRIMARY KEY (`id_bed_type`) - ) ENGINE="._MYSQL_ENGINE_." DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;", - "CREATE TABLE IF NOT EXISTS `"._DB_PREFIX_."htl_bed_type_lang`( - `id_bed_type` INT(11) NOT NULL, - `name` VARCHAR(255) DEFAULT NULL, - `id_lang` INT(11) NOT NULL, - PRIMARY KEY (`id_bed_type`, `id_lang`) - ) ENGINE="._MYSQL_ENGINE_." DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;", - "CREATE TABLE IF NOT EXISTS `"._DB_PREFIX_."htl_room_type_bed_type` ( - `id_room_type_bed_type` INT(11) NOT NULL AUTO_INCREMENT, - `id_product` INT(11) NOT NULL, - `id_bed_type` INT(11) NOT NULL, - PRIMARY KEY (`id_room_type_bed_type`) - ) ENGINE="._MYSQL_ENGINE_." DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;", - - "INSERT INTO `"._DB_PREFIX_."htl_settings_link` (`id_settings_link`, `icon`, `link`, `new_window`, `position`, `unremovable`, `active`, `date_add`, `date_upd`) VALUES + "INSERT IGNORE INTO `"._DB_PREFIX_."htl_settings_link` (`id_settings_link`, `icon`, `link`, `new_window`, `position`, `unremovable`, `active`, `date_add`, `date_upd`) VALUES (1, 'icon-cogs', 'index.php?controller=AdminHotelGeneralSettings', 0, 0, 1, 1, NOW(), NOW()), (2, 'icon-dollar', 'index.php?controller=AdminHotelFeaturePricesSettings', 0, 2, 1, 1, NOW(), NOW()), (3, 'icon-plus-square', 'index.php?controller=AdminRoomTypeGlobalDemand', 0, 3, 1, 1, NOW(), NOW()), @@ -528,27 +527,27 @@ class HotelReservationSystemDb PRIMARY KEY (`id_settings_link`, `id_lang`) ) ENGINE="._MYSQL_ENGINE_." DEFAULT CHARSET=utf8;", - "INSERT INTO `"._DB_PREFIX_."htl_settings_link_lang` (`id_settings_link`, `id_lang`, `name`, `hint`) + "INSERT IGNORE INTO `"._DB_PREFIX_."htl_settings_link_lang` (`id_settings_link`, `id_lang`, `name`, `hint`) SELECT 1, `id_lang`, 'General Settings', 'Configure Your hotel general settings using this option.' FROM `"._DB_PREFIX_."lang` ORDER BY `id_lang`;", - "INSERT INTO `"._DB_PREFIX_."htl_settings_link_lang` (`id_settings_link`, `id_lang`, `name`, `hint`) + "INSERT IGNORE INTO `"._DB_PREFIX_."htl_settings_link_lang` (`id_settings_link`, `id_lang`, `name`, `hint`) SELECT 2, `id_lang`, 'Advanced Price Rules', 'Here set Advanced price rules for specific dates.' FROM `"._DB_PREFIX_."lang` ORDER BY `id_lang`;", - "INSERT INTO `"._DB_PREFIX_."htl_settings_link_lang` (`id_settings_link`, `id_lang`, `name`, `hint`) + "INSERT IGNORE INTO `"._DB_PREFIX_."htl_settings_link_lang` (`id_settings_link`, `id_lang`, `name`, `hint`) SELECT 3, `id_lang`, 'Additional Facilities', 'Here create Additional facilities and their prices for room types.' FROM `"._DB_PREFIX_."lang` ORDER BY `id_lang`;", - "INSERT INTO `"._DB_PREFIX_."htl_settings_link_lang` (`id_settings_link`, `id_lang`, `name`, `hint`) + "INSERT IGNORE INTO `"._DB_PREFIX_."htl_settings_link_lang` (`id_settings_link`, `id_lang`, `name`, `hint`) SELECT 4, `id_lang`, 'Hotel Interior Block', 'Configure Hotel Interior block. You can display hotel interior images using this block. This block will be displayed on home page.' FROM `"._DB_PREFIX_."lang` ORDER BY `id_lang`;", - "INSERT INTO `"._DB_PREFIX_."htl_settings_link_lang` (`id_settings_link`, `id_lang`, `name`, `hint`) + "INSERT IGNORE INTO `"._DB_PREFIX_."htl_settings_link_lang` (`id_settings_link`, `id_lang`, `name`, `hint`) SELECT 5, `id_lang`, 'Hotel Amenities Block', 'Configure Hotels Amenities settings. You can display hotel amenities images using this block. This block will be displayed on home page.' FROM `"._DB_PREFIX_."lang` ORDER BY `id_lang`;", @@ -589,9 +588,10 @@ class HotelReservationSystemDb `'._DB_PREFIX_.'htl_branch_info`, `'._DB_PREFIX_.'htl_branch_info_lang`, `'._DB_PREFIX_.'htl_image`, - `'._DB_PREFIX_.'htl_branch_features`, - `'._DB_PREFIX_.'htl_features`, - `'._DB_PREFIX_.'htl_features_lang`, + `'._DB_PREFIX_.'htl_branch_amenity`, + `'._DB_PREFIX_.'htl_room_type_amenity`, + `'._DB_PREFIX_.'htl_amenity`, + `'._DB_PREFIX_.'htl_amenity_lang`, `'._DB_PREFIX_.'htl_cart_booking_data`, `'._DB_PREFIX_.'htl_booking_detail`, `'._DB_PREFIX_.'htl_booking_document`, diff --git a/modules/hotelreservationsystem/classes/HotelRoomTypeAmenities.php b/modules/hotelreservationsystem/classes/HotelRoomTypeAmenities.php new file mode 100644 index 000000000..1a91823ff --- /dev/null +++ b/modules/hotelreservationsystem/classes/HotelRoomTypeAmenities.php @@ -0,0 +1,155 @@ + 'htl_room_type_amenity', + 'primary' => 'id_room_type_amenity', + 'fields' => array( + 'id_product' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), + 'amenity_id' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), + 'is_featured' => array('type' => self::TYPE_INT), + 'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate', 'copy_post' => false), + 'date_upd' => array('type' => self::TYPE_DATE, 'validate' => 'isDate', 'copy_post' => false), + ), + ); + + /** + * @param int $idProduct + * @param int $idLang defaults to current context language + * @param bool $featuredOnly true = is_featured=1 only; false = all active child amenities + * @return array + */ + public static function getAmenities($idProduct, $idLang = 0, $featuredOnly = false) + { + if (!$idLang) { + $idLang = Context::getContext()->language->id; + } + + $filter = $featuredOnly ? 'AND hrta.`is_featured` = 1' : ''; + + return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( + 'SELECT ha.`id_amenity` AS `id`, ha.`logo_type`, ha.`logo`, hal.`name`, hrta.`is_featured` + FROM `'._DB_PREFIX_.'htl_room_type_amenity` hrta + INNER JOIN `'._DB_PREFIX_.'htl_amenity` ha + ON (ha.`id_amenity` = hrta.`amenity_id`) + INNER JOIN `'._DB_PREFIX_.'htl_amenity_lang` hal + ON (hal.`id_amenity` = hrta.`amenity_id` AND hal.`id_lang` = '.(int)$idLang.') + WHERE hrta.`id_product` = '.(int)$idProduct.' + AND ha.`active` = 1 + AND ha.`id_parent` > 0 + '.$filter.' + ORDER BY ha.`position` ASC, hal.`name` ASC' + ) ?: array(); + } + + /** + * @param int $idProduct + * @return bool + */ + public static function deleteByProduct($idProduct) + { + return (bool)Db::getInstance()->delete('htl_room_type_amenity', '`id_product` = '.(int)$idProduct); + } + + /** + * Prepare amenities tree data for a room type form, with selection state. + * + * @param int $idProduct + * @param int $idLang defaults to current context language + * @return array + */ + public static function getRoomTypeAmenitiesTreeData($idProduct, $idLang = 0) + { + if (!$idLang) { + $idLang = Context::getContext()->language->id; + } + + $objHotelAmenities = new HotelAmenities(); + $amenities = $objHotelAmenities->hotelBranchSelectedAmenities( + array_column(self::getAmenities($idProduct), 'id'), + $idLang + ); + + if (!$amenities) { + return array(); + } + + foreach ($amenities as $idAmenityGroup => &$amenityGroup) { + $amenityGroup['value'] = (int) $idAmenityGroup; + $amenityGroup['input_name'] = 'room_type_amenity_parents'; + + $selectedAmenities = 0; + if (!empty($amenityGroup['children'])) { + foreach ($amenityGroup['children'] as &$amenity) { + $amenity['value'] = (int) $amenity['id']; + $amenity['input_name'] = 'room_type_amenities'; + if (!empty($amenity['selected'])) { + ++$selectedAmenities; + } + } + + if ($selectedAmenities === count($amenityGroup['children'])) { + $amenityGroup['selected'] = true; + } + } + } + + return $amenities; + } + + /** + * Delete existing assignments then save new ones for a room type. + * + * @param int $idProduct + * @param array $amenityIds + * @param array $featuredIds amenity IDs that should be marked is_featured=1 + * @return bool + */ + public function saveRoomTypeAmenities($idProduct, array $amenityIds, array $featuredIds = array()) + { + static::deleteByProduct($idProduct); + + $featuredSet = array_flip(array_map('intval', $featuredIds)); + + foreach (array_unique(array_filter(array_map('intval', $amenityIds))) as $amenityId) { + $objHotelRoomTypeAmenities = new self(); + $objHotelRoomTypeAmenities->id_product = (int)$idProduct; + $objHotelRoomTypeAmenities->amenity_id = (int)$amenityId; + $objHotelRoomTypeAmenities->is_featured = isset($featuredSet[$amenityId]) ? 1 : 0; + if (!$objHotelRoomTypeAmenities->save()) { + return false; + } + } + + return true; + } +} diff --git a/modules/hotelreservationsystem/classes/HotelRoomTypeBedType.php b/modules/hotelreservationsystem/classes/HotelRoomTypeBedType.php deleted file mode 100644 index e404ca4a0..000000000 --- a/modules/hotelreservationsystem/classes/HotelRoomTypeBedType.php +++ /dev/null @@ -1,96 +0,0 @@ - 'htl_room_type_bed_type', - 'primary' => 'id_room_type_bed_type', - 'fields' => array( - 'id_bed_type' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), - 'id_product' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'), - ), - ); - - public function getRoomTypeBedTypes($idProduct) - { - $sql = 'SELECT * FROM `'._DB_PREFIX_.$this->table.'` - WHERE `id_product` ='.(int) $idProduct; - - return Db::getInstance()->executeS($sql); - } - - public function updateRoomTypeBedTypes($idBedTypes, $idProduct) - { - $res = true; - if ($roomTypeBedTypes = $this->getRoomTypeBedTypes($idProduct)) { - $roomTypeBedTypes = array_column($roomTypeBedTypes, 'id_room_type_bed_type', 'id_bed_type'); - } - - if ($idBedTypes) { - foreach ($idBedTypes as $idBedType) { - // If room type bed type mapping already exits no need to update it. - if (isset($roomTypeBedTypes[$idBedType])) { - unset($roomTypeBedTypes[$idBedType]); - } else { - $objHotelRoomTypeBedType = new self(); - $objHotelRoomTypeBedType->id_product = $idProduct; - $objHotelRoomTypeBedType->id_bed_type = $idBedType; - $res &=$objHotelRoomTypeBedType->save(); - } - } - } - - // Removing the non selected bed types. - if ($roomTypeBedTypes) { - $res &= $this->deleteRoomTypeBedTypesById($roomTypeBedTypes); - } - - return $res; - } - - public function deleteRoomTypeBedTypesById($idRoomTypeBedTypes) - { - $res = true; - if ($idRoomTypeBedTypes) { - foreach ($idRoomTypeBedTypes as $idRoomTypeBedType) { - $objHotelRoomTypeBedType = new self($idRoomTypeBedType); - $res &= $objHotelRoomTypeBedType->delete(); - } - } - - return $res; - } - - public function deleteRoomTypeBedTypes($idBedType = false, $idProduct = false) - { - return Db::getInstance()->delete( - $this->table, - ' 1 '.($idBedType ? ' AND `id_bed_type`='.(int) $idBedType : '').($idProduct ? ' AND `id_product`='.(int) $idProduct : '') - ); - } - -} diff --git a/modules/hotelreservationsystem/controllers/admin/AdminAddHotelController.php b/modules/hotelreservationsystem/controllers/admin/AdminAddHotelController.php index 868012630..020227614 100644 --- a/modules/hotelreservationsystem/controllers/admin/AdminAddHotelController.php +++ b/modules/hotelreservationsystem/controllers/admin/AdminAddHotelController.php @@ -176,35 +176,15 @@ class AdminAddHotelController extends ModuleAdminController } $smartyVars['order_restrict_date_info'] = HotelOrderRestrictDate::getDataByHotelId($idHotel); - $objHotelFeatures = new HotelFeatures(); - $hotelFeatures = $this->object->getFeaturesOfHotelByHotelId($this->object->id); - if ($features = $objHotelFeatures->HotelBranchSelectedFeaturesArray($hotelFeatures)) { - foreach ($features as $idFeature => $feature) { - $features[$idFeature]['value'] = $idFeature; - $features[$idFeature]['input_name'] = 'id_feature_parents'; - if (isset($feature['children']) && $feature['children']) { - $selectedChildFeatures = 0; - foreach ($feature['children'] as $childKey => $childFeature) { - $features[$idFeature]['children'][$childKey]['value'] = $childFeature['id']; - $features[$idFeature]['children'][$childKey]['input_name'] = 'id_features'; - if (isset($childFeature['selected']) && $childFeature['selected']) { - $selectedChildFeatures++; - } - } - - if ($selectedChildFeatures == count($feature['children'])) { - $features[$idFeature]['selected'] = true; - } - } - } - - $tree = new HelperTree('hotel-features-tree', $features); + if ($amenities = HotelBranchAmenities::getBranchAmenitiesTreeData((int)$idHotel)) { + $tree = new HelperTree('hotel-amenities-tree', $amenities); $tree->setShowCollapseExpandButton(true) ->setUseCheckBox(true) ->setAutoSelectChildren(true) - ->setUseBulkActions(true); - $treeContent = $tree->render(); - $smartyVars['hotel_feature_tree'] = $treeContent; + ->setUseBulkActions(true) + ->setUseSearch(true); + $smartyVars['hotel_amenity_tree'] = $tree->render(); + $smartyVars['hotel_featured_amenity_ids'] = array_column(HotelBranchAmenities::getAmenities((int)$idHotel, 0, true), 'id'); } $smartyVars['rewrite_url'] = []; @@ -282,7 +262,8 @@ class AdminAddHotelController extends ModuleAdminController $longitude = Tools::getValue('loclongitude'); $map_formated_address = Tools::getValue('locformatedAddr'); $map_input_text = Tools::getValue('googleInputField'); - $hotelFeatures = Tools::getValue('id_features', array()); + $hotelAmenities = Tools::getValue('id_amenities', array()); + $hotelFeaturedAmenities = Tools::getValue('hotel_featured_amenities', array()); $shortDescriptionMaxChar = Configuration::get('PS_SHORT_DESC_LIMIT') ? Configuration::get('PS_SHORT_DESC_LIMIT') : Configuration::PS_SHORT_DESC_LIMIT; // check if field is atleast in default language. Not available in default prestashop @@ -496,6 +477,11 @@ class AdminAddHotelController extends ModuleAdminController } } + $amenityCategories = HotelAmenities::getCategories(); + if ($amenityCategories && !HotelAmenities::getAmenities()) { + $this->errors[] = $this->l('No amenities have been created. Please add amenities to at least one category before assigning them.'); + } + if (!count($this->errors)) { if ($idHotel) { $objHotelBranch = new HotelBranchInformation($idHotel); @@ -819,10 +805,9 @@ class AdminAddHotelController extends ModuleAdminController $objHotelOrderRestrictDate->save(); - $objHotelFeatures = new HotelBranchFeatures(); - $objHotelFeatures->deleteBranchFeaturesByHotelId($idHotel); - if (!$objHotelFeatures->assignFeaturesToHotel($idHotel, $hotelFeatures)) { - $this->errors[] = $this->l('Some problem occurred while assigning features to the hotel.'); + $objHotelAmenities = new HotelBranchAmenities(); + if (!$objHotelAmenities->saveBranchAmenities($idHotel, $hotelAmenities, $hotelFeaturedAmenities)) { + $this->errors[] = $this->l('Some problem occurred while assigning amenities to the hotel.'); } } diff --git a/modules/hotelreservationsystem/controllers/admin/AdminHotelAmenitiesController.php b/modules/hotelreservationsystem/controllers/admin/AdminHotelAmenitiesController.php new file mode 100644 index 000000000..6001b3546 --- /dev/null +++ b/modules/hotelreservationsystem/controllers/admin/AdminHotelAmenitiesController.php @@ -0,0 +1,352 @@ +bootstrap = true; + $this->table = 'htl_amenity'; + $this->className = 'HotelAmenities'; + $this->identifier = 'id_amenity'; + $this->toolbar_title = $this->l('Manage Amenities'); + + parent::__construct(); + + $this->display = 'view'; + } + + public function initToolbar() + { + parent::initToolbar(); + + if ($this->display == 'view') { + $this->page_header_toolbar_btn['add_category'] = array( + 'href' => self::$currentIndex.'&add'.$this->table.'&token='.$this->token, + 'desc' => $this->l('Add new Amenity Category'), + 'imgclass' => 'new', + ); + } + } + + public function initContent() + { + if (Tools::isSubmit('add'.$this->table) || Tools::isSubmit('update'.$this->table) + || Tools::isSubmit('add'.$this->table.'_item') || Tools::isSubmit('update'.$this->table.'_item') + ) { + $this->display = 'edit'; + } + + $this->initTabModuleList(); + $this->initToolbar(); + $this->initPageHeaderToolbar(); + + if ($this->display == 'edit') { + $this->content = $this->renderForm(); + } else { + $this->content = $this->renderView(); + } + + $this->context->smarty->assign(array( + 'content' => $this->content, + 'url_post' => self::$currentIndex.'&token='.$this->token, + 'show_page_header_toolbar' => $this->show_page_header_toolbar, + 'page_header_toolbar_title' => $this->page_header_toolbar_title, + 'page_header_toolbar_btn' => $this->page_header_toolbar_btn, + )); + } + + public function renderView() + { + $objHotelAmenities = new HotelAmenities(); + $this->context->smarty->assign(array( + 'amenities_tree' => $objHotelAmenities->getAmenitiesTree(), + 'img_base_url' => $this->module->getPathUri().self::IMG_DIR, + 'current_index' => self::$currentIndex, + 'token' => $this->token, + 'admin_link' => Context::getContext()->link->getAdminLink('AdminHotelAmenities'), + )); + + return parent::renderView(); + } + + public function renderForm() + { + $languages = Language::getLanguages(false); + $defaultLang = (int)Configuration::get('PS_LANG_DEFAULT'); + $adminLink = Context::getContext()->link->getAdminLink('AdminHotelAmenities'); + + $this->context->smarty->assign(array( + 'languages' => $languages, + 'default_lang_id' => $defaultLang, + 'current_index' => self::$currentIndex, + 'token' => $this->token, + 'admin_link' => $adminLink, + )); + + if (Tools::isSubmit('add'.$this->table.'_item') || Tools::isSubmit('update'.$this->table.'_item')) { + $idAmenity = (int)Tools::getValue('id'); + $idCategory = (int)Tools::getValue('id_category'); + $amenity = array(); + + if ($idAmenity) { + $objHotelAmenities = new HotelAmenities($idAmenity); + if (Validate::isLoadedObject($objHotelAmenities)) { + $idCategory = (int)$objHotelAmenities->id_parent; + $amenity = array( + 'id' => $objHotelAmenities->id, + 'id_parent' => $idCategory, + 'active' => (int)$objHotelAmenities->active, + 'logo_type' => $objHotelAmenities->logo_type, + 'logo' => $objHotelAmenities->logo, + 'name' => is_array($objHotelAmenities->name) ? $objHotelAmenities->name : array(), + ); + } + } + + $imgPath = $this->module->getLocalPath().self::IMG_DIR.$idAmenity.'.jpg'; + $this->context->smarty->assign(array( + 'amenity' => $amenity, + 'id_category' => $idCategory, + 'existing_img' => ($idAmenity && file_exists($imgPath)) + ? $this->module->getPathUri().self::IMG_DIR.$idAmenity.'.jpg' + : false, + )); + } else { + $idCategory = (int)Tools::getValue('id'); + $category = array(); + + if ($idCategory) { + $objHotelAmenities = new HotelAmenities($idCategory); + if (Validate::isLoadedObject($objHotelAmenities)) { + $category = array( + 'id' => $objHotelAmenities->id, + 'position' => $objHotelAmenities->position, + 'name' => is_array($objHotelAmenities->name) ? $objHotelAmenities->name : array(), + ); + } + } + + $this->context->smarty->assign('category', $category); + } + + $this->fields_form = array('submit' => array('title' => $this->l('Save'))); + return parent::renderForm(); + } + + public function postProcess() + { + if (Tools::isSubmit('submitHtlCategory') || Tools::isSubmit('submitHtlCategoryAndStay')) { + $idCategory = (int)Tools::getValue('id'); + $pos = (int)Tools::getValue('position'); + $languages = Language::getLanguages(false); + $defaultLang = (int)Configuration::get('PS_LANG_DEFAULT'); + + if (!$pos || !Validate::isUnsignedInt($pos)) { + $this->errors[] = $this->l('Position is invalid.'); + } + + $nameDefault = trim(Tools::getValue('cat_name_'.$defaultLang)); + if (!$nameDefault) { + $this->errors[] = $this->l('Category name is required in default language.'); + } elseif (!Validate::isGenericName($nameDefault)) { + $this->errors[] = $this->l('Category name is invalid.'); + } + + if (count($this->errors)) { + $this->display = 'edit'; + return; + } + + $objHotelAmenities = $idCategory ? new HotelAmenities($idCategory) : new HotelAmenities(); + foreach ($languages as $lang) { + $val = trim(Tools::getValue('cat_name_'.$lang['id_lang'])); + $objHotelAmenities->name[$lang['id_lang']] = $val ?: $nameDefault; + } + $objHotelAmenities->id_parent = 0; + $objHotelAmenities->position = $pos; + $objHotelAmenities->active = 1; + + if (!$objHotelAmenities->save()) { + $this->errors[] = $this->l('Error saving category.'); + $this->display = 'edit'; + return; + } + + $conf = $idCategory ? 4 : 3; + if (Tools::isSubmit('submitHtlCategoryAndStay')) { + Tools::redirectAdmin(self::$currentIndex.'&id='.(int)$objHotelAmenities->id.'&update'.$this->table.'&conf='.$conf.'&token='.$this->token); + } else { + Tools::redirectAdmin(self::$currentIndex.'&conf='.$conf.'&token='.$this->token); + } + return; + } + + if (Tools::isSubmit('submitHtlAmenityItem') || Tools::isSubmit('submitHtlAmenityItemAndStay')) { + $idAmenity = (int)Tools::getValue('id'); + $idCategory = (int)Tools::getValue('id_category'); + $active = (int)Tools::getValue('active'); + $logoType = Tools::getValue('logo_type'); + $languages = Language::getLanguages(false); + $defaultLang = (int)Configuration::get('PS_LANG_DEFAULT'); + + if (!$idCategory) { + $this->errors[] = $this->l('Category is required.'); + } + + $nameDefault = trim(Tools::getValue('amenity_name_'.$defaultLang)); + if (!$nameDefault) { + $this->errors[] = $this->l('Amenity name is required in default language.'); + } elseif (!Validate::isGenericName($nameDefault)) { + $this->errors[] = $this->l('Amenity name is invalid.'); + } + + $logoValue = ''; + if ($logoType === 'icon') { + $logoValue = trim(Tools::getValue('logo_icon')); + if (!$logoValue) { + $this->errors[] = $this->l('Icon class is required.'); + } elseif (!preg_match('/^icon-/', $logoValue)) { + $this->errors[] = $this->l('Icon class must start with "icon-" (e.g. icon-wifi).'); + } elseif (!Validate::isGenericName(str_replace('-', ' ', $logoValue))) { + $this->errors[] = $this->l('Icon name is invalid.'); + } + } else { + $hasUpload = isset($_FILES['logo_image']) && !empty($_FILES['logo_image']['tmp_name']); + $hasExisting = $idAmenity && file_exists($this->module->getLocalPath().self::IMG_DIR.$idAmenity.'.jpg'); + if (!$hasUpload && !$hasExisting) { + $this->errors[] = $this->l('Please upload an image for this amenity.'); + } + } + + if (count($this->errors)) { + $this->display = 'edit'; + return; + } + + $objHotelAmenities = $idAmenity ? new HotelAmenities($idAmenity) : new HotelAmenities(); + foreach ($languages as $lang) { + $val = trim(Tools::getValue('amenity_name_'.$lang['id_lang'])); + $objHotelAmenities->name[$lang['id_lang']] = $val ?: $nameDefault; + } + $objHotelAmenities->id_parent = $idCategory; + $objHotelAmenities->active = $active; + $objHotelAmenities->logo_type = ($logoType === 'icon') ? 'icon' : 'image'; + $objHotelAmenities->logo = ($logoType === 'icon') ? $logoValue : $objHotelAmenities->logo; + + if (!$objHotelAmenities->save()) { + $this->errors[] = $this->l('Error saving amenity.'); + $this->display = 'edit'; + return; + } + + if ($logoType === 'icon') { + $imgFile = $this->module->getLocalPath().self::IMG_DIR.$objHotelAmenities->id.'.jpg'; + if (file_exists($imgFile)) { + unlink($imgFile); + } + } + + if ($logoType === 'image' && isset($_FILES['logo_image']) && $_FILES['logo_image']['tmp_name']) { + $imgFile = $_FILES['logo_image']; + if ($error = ImageManager::validateUpload($imgFile, Tools::getMaxUploadSize())) { + $this->errors[] = $error; + } else { + $imgDir = $this->module->getLocalPath().self::IMG_DIR; + if (!is_dir($imgDir)) { + mkdir($imgDir, 0755, true); + } + if (ImageManager::resize($imgFile['tmp_name'], $imgDir.$objHotelAmenities->id.'.jpg')) { + $objHotelAmenities->logo = $objHotelAmenities->id.'.jpg'; + $objHotelAmenities->save(); + } else { + $this->errors[] = $this->l('Error uploading amenity image.'); + } + } + } + + if (count($this->errors)) { + $this->display = 'edit'; + return; + } + + $conf = $idAmenity ? 4 : 3; + if (Tools::isSubmit('submitHtlAmenityItemAndStay')) { + Tools::redirectAdmin(self::$currentIndex.'&id='.(int)$objHotelAmenities->id.'&id_category='.(int)$idCategory.'&update'.$this->table.'_item&conf='.$conf.'&token='.$this->token); + } else { + Tools::redirectAdmin(self::$currentIndex.'&conf='.$conf.'&token='.$this->token); + } + return; + } + + if (empty($this->errors)) { + parent::postProcess(); + } + } + + public function ajaxProcessDeleteCategory() + { + $response = array('status' => false); + + if ($this->tabAccess['delete']) { + $objHotelAmenities = new HotelAmenities(); + if ($objHotelAmenities->deleteCategory((int)Tools::getValue('id_category'))) { + $response['status'] = true; + } else { + $response['msg'] = $this->l('Error deleting category.'); + } + } else { + $response['msg'] = $this->l('You do not have permission to delete.'); + } + + $this->ajaxDie(json_encode($response)); + } + + public function ajaxProcessDeleteAmenityItem() + { + $response = array('status' => false); + + if ($this->tabAccess['delete']) { + $objHotelAmenities = new HotelAmenities((int)Tools::getValue('id_amenity')); + if (Validate::isLoadedObject($objHotelAmenities) && $objHotelAmenities->delete()) { + $response['status'] = true; + } else { + $response['msg'] = $this->l('Error deleting amenity.'); + } + } else { + $response['msg'] = $this->l('You do not have permission to delete.'); + } + + $this->ajaxDie(json_encode($response)); + } + + public function setMedia() + { + parent::setMedia(); + $this->addJs(_MODULE_DIR_.'hotelreservationsystem/views/js/hotelAmenity.js'); + $this->addCSS(_MODULE_DIR_.'hotelreservationsystem/views/css/hotelAmenity.css'); + } +} diff --git a/modules/hotelreservationsystem/controllers/admin/AdminHotelBedTypesController.php b/modules/hotelreservationsystem/controllers/admin/AdminHotelBedTypesController.php deleted file mode 100644 index 85133052a..000000000 --- a/modules/hotelreservationsystem/controllers/admin/AdminHotelBedTypesController.php +++ /dev/null @@ -1,235 +0,0 @@ -bootstrap = true; - $this->table = 'htl_bed_type'; - $this->className = 'HotelBedType'; - $this->identifier = 'id_bed_type'; - $this->context = Context::getContext(); - $this->lang = true; - - parent::__construct(); - - $this->_new_list_header_design = true; - // field options for global fields - $this->fields_options = array( - 'global' => array( - 'title' => $this->l('Dimension Unit Setting'), - 'icon' => 'icon-cogs', - 'fields' => array( - 'WK_DIMENSION_UNIT' => array( - 'title' => $this->l('Dimension Unit'), - 'type' => 'textLang', - 'lang' => true, - 'required' => true, - 'validation' => 'isGenericName', - 'hint' => $this->l('Enter a dimension unit for the bed types.') - ), - ), - 'submit' => array('title' => $this->l('Save')) - ), - ); - - $this->addRowAction('edit'); - $this->addRowAction('delete'); - $this->bulk_actions = array( - 'delete' => array( - 'text' => $this->l('Delete selected'), - 'confirm' => $this->l('Delete selected items?'), - 'icon' => 'icon-trash' - ) - ); - } - - public function initContent() - { - parent::initContent(); - // to customize the view as per our requirements - if ($this->display != 'add' && $this->display != 'edit') { - $this->content = $this->renderOptions(); - $this->content .= $this->renderList(); - $this->context->smarty->assign('content', $this->content); - } - } - - public function initPageHeaderToolbar() - { - if (!$this->display || $this->display == 'list') { - $this->page_header_toolbar_btn['new_product'] = array( - 'href' => self::$currentIndex.'&add'.$this->table.'&token='.$this->token, - 'desc' => $this->l('Add new', null, null, false), - 'icon' => 'process-icon-new' - ); - } - - parent::initPageHeaderToolbar(); - } - - public function initToolbar() - { - $this->toolbar_btn = array(); - } - - public function renderList() - { - // added here instead of the constructor since the dimension unit will be update afer post processs. - $this->fields_list = array( - 'id_bed_type' => array( - 'title' => $this->l('ID'), - 'align' => 'center', - ), - 'name' => array( - 'title' => $this->l('Name'), - 'align' => 'center', - ), - 'width' => array( - 'title' => $this->l('Width'), - 'align' => 'center', - 'suffix' => Configuration::get('WK_DIMENSION_UNIT', $this->context->language->id) - ), - 'length' => array( - 'title' => $this->l('Lenght'), - 'align' => 'center', - 'suffix' => Configuration::get('WK_DIMENSION_UNIT', $this->context->language->id) - ), - ); - return parent::renderList(); - } - - public function renderForm() - { - if (!$this->loadObject(true)) { - return; - } - - $this->fields_form = array( - 'legend' => array( - 'title' => $this->l('Bed Type'), - 'icon' => 'icon-bed' - ), - 'input' => array( - array( - 'type' => 'text', - 'label' => $this->l('Bed Type Name'), - 'name' => 'name', - 'required' => true, - 'col' => 4, - 'lang' => true, - 'hint' => $this->l('Enter the name of Bed type.') - ), - array( - 'type' => 'text', - 'label' => $this->l('Width'), - 'name' => 'width', - 'required' => true, - 'col' => 4, - 'hint' => $this->l('Enter the width of the Bed type in ').Configuration::get('WK_DIMENSION_UNIT', $this->context->language->id), - 'suffix' => Configuration::get('WK_DIMENSION_UNIT', $this->context->language->id), - ), - array( - 'type' => 'text', - 'label' => $this->l('Length'), - 'name' => 'length', - 'col' => 4, - 'required' => true, - 'hint' => $this->l('Enter the length of the Bed type in ').Configuration::get('WK_DIMENSION_UNIT', $this->context->language->id), - 'suffix' => Configuration::get('WK_DIMENSION_UNIT', $this->context->language->id), - ), - ), - 'submit' => array( - 'title' => $this->l('Save') - ), - 'buttons' => array( - 'save-and-stay' => array( - 'title' => $this->l('Save and stay'), - 'name' => 'submitAdd'.$this->table.'AndStay', - 'type' => 'submit', - 'class' => 'btn btn-default pull-right', - 'icon' => 'process-icon-save', - ), - ), - ); - - return parent::renderForm(); - } - - public function beforeUpdateOptions() - { - $defaultLangId = Configuration::get('PS_LANG_DEFAULT'); - $objDefaultLanguage = Language::getLanguage((int) $defaultLangId); - $languages = Language::getLanguages(false); - if (!trim(Tools::getValue('WK_DIMENSION_UNIT_'.$defaultLangId)) - && Tools::getValue('WK_DIMENSION_UNIT_'.$defaultLangId) - ) { - $this->errors[] = $this->l('Default dimension unit is required at least in ').$objDefaultLanguage['name']; - } else { - foreach ($languages as $lang) { - if (Tools::getValue('WK_DIMENSION_UNIT_'.$lang['id_lang']) - && (!trim(Tools::getValue('WK_DIMENSION_UNIT_'.$lang['id_lang'])) - || !Validate::isGenericName(Tools::getValue('WK_DIMENSION_UNIT_'.$lang['id_lang']))) - ) { - $this->errors[] = $this->l('Invalid dimension unit in ').$lang['name']; - } - - if (!trim(Tools::getValue('WK_DIMENSION_UNIT_'.$lang['id_lang']))) { - $_POST['WK_DIMENSION_UNIT_'.$lang['id_lang']] = Tools::getValue('WK_DIMENSION_UNIT_'.$defaultLangId); - } - } - } - } - - public function processSave() - { - if (!$this->loadObject(true)) { - return; - } - - $defaultLangId = Configuration::get('PS_LANG_DEFAULT'); - $objDefaultLanguage = Language::getLanguage((int) $defaultLangId); - $languages = Language::getLanguages(false); - if (!trim(Tools::getValue('name_'.$defaultLangId))) { - $this->errors[] = $this->l('Bed type name is required at least in ').$objDefaultLanguage['name']; - } else { - foreach ($languages as $lang) { - if (trim(Tools::getValue('name_'.$lang['id_lang'])) && !Validate::isGenericName(Tools::getValue('name_'.$lang['id_lang']))) { - $this->errors[] = $this->l('Invalid bed type name in ').$lang['name']; - } - } - } - - if (!(float) Tools::getValue('width')) { - $this->errors[] = $this->l('The width field is required'); - } - - if (!(float) Tools::getValue('length')) { - $this->errors[] = $this->l('The length field is required'); - } - - return parent::processSave(); - } - -} diff --git a/modules/hotelreservationsystem/controllers/admin/AdminHotelfeaturesController.php b/modules/hotelreservationsystem/controllers/admin/AdminHotelfeaturesController.php deleted file mode 100644 index 9f30938fe..000000000 --- a/modules/hotelreservationsystem/controllers/admin/AdminHotelfeaturesController.php +++ /dev/null @@ -1,321 +0,0 @@ -bootstrap = true; - $this->table = 'htl_features'; - $this->className = 'HotelFeatures'; - $this->identifier = 'id'; - $this->toolbar_title = $this->l('Manage Hotel Features'); - - parent::__construct(); - $this->display = 'view'; - } - - public function initToolbar() - { - parent::initToolbar(); - - $this->page_header_toolbar_btn['addfeatures'] = array( - 'href' => self::$currentIndex.'&add'.$this->table.'&token='.$this->token, - 'desc' => $this->l('Add new Features'), - 'imgclass' => 'new' - ); - } - - public function renderView() - { - $objHotelFeatures = new HotelFeatures(); - $featuresList = $objHotelFeatures->HotelAllCommonFeaturesArray(); - $this->context->smarty->assign('features_list', $featuresList); - return parent::renderView(); - } - - public function renderForm() - { - if (!$this->loadObject(true)) { - return; - } - - $smartyVars = array(); - //lang vars - $languages = Language::getLanguages(false); - $currentLangId = $this->default_form_language ? $this->default_form_language : Configuration::get('PS_LANG_DEFAULT'); - $currentLang = Language::getLanguage((int) $currentLangId); - $smartyVars['languages'] = $languages; - $smartyVars['currentLang'] = $currentLang; - $smartyVars['ps_img_dir'] = _PS_IMG_.'l/'; - if ($id = $this->object->id) { - $smartyVars['edit'] = 1; - if (Validate::isLoadedObject($objFeatures = new HotelFeatures($id))) { - $featureInfo = (array) $objFeatures; - if ($childFeatures = $objFeatures->getChildFeaturesByParentFeatureId($id)) { - $featureInfo['child_features'] = array(); - foreach ($childFeatures as $value) { - $objChildFeatures = new HotelFeatures($value['id']); - $featureInfo['child_features'][] = (array) $objChildFeatures; - } - } - $smartyVars['featureInfo'] = $featureInfo; - } - } - $this->context->smarty->assign($smartyVars); - Media::addJsDef( - array( - 'currentLang' => $currentLang, - 'languages' => $languages, - 'img_dir_l' => _PS_IMG_.'l/', - ) - ); - $this->fields_form = array( - 'submit' => array( - 'title' => $this->l('Save') - ) - ); - return parent::renderForm(); - } - - public function postProcess() - { - if (!$this->loadObject(true)) { - return; - } - - if (Tools::isSubmit('submitHtlFeatures') || Tools::isSubmit('submitHtlFeaturesAndStay')) { - $conf = 3; - if ($parentFeatureId = Tools::getValue('id')) { - $conf = 4; - } - - $pos = Tools::getValue('position'); - - $defaultLangId = Configuration::get('PS_LANG_DEFAULT'); - $objDefaultLanguage = Language::getLanguage((int) $defaultLangId); - $languages = Language::getLanguages(false); - - if (empty($pos) || !Validate::isUnsignedInt($pos)) { - $this->errors[] = $this->l('Position is Invalid.'); - } - - if (!trim(Tools::getValue('parent_ftr_name_'.$defaultLangId))) { - $this->errors[] = $this->l('Parent feature name is required at least in '). - $objDefaultLanguage['name']; - } elseif (!Validate::isGenericName(Tools::getValue('parent_ftr_name_'.$defaultLangId))) { - $this->errors[] = $this->l('Parent feature name is invalid.'); - } else { - foreach ($languages as $lang) { - // validate non required fields - if (trim(Tools::getValue('parent_ftr_name_'.$lang['id_lang']))) { - if (!Validate::isGenericName(Tools::getValue('parent_ftr_name_'.$lang['id_lang']))) { - $this->errors[] = $this->l('Invalid parent feature name in ').$lang['name']; - } - } - } - } - if ($childFeaturesDefLang = Tools::getValue('child_features_'.$defaultLangId)) { - foreach ($childFeaturesDefLang as $kChild => $childftr) { - if (!trim($childftr)) { - $this->errors[] = $this->l('Child features name is required at least in '). - $objDefaultLanguage['name']; - } elseif (!Validate::isGenericName($childftr)) { - $this->errors[] = $this->l('Child features name is invalid : ').Tools::safeOutput($childftr); - } else { - foreach ($languages as $lang) { - if ($childFtrLang = Tools::getValue('child_features_'.$lang['id_lang'])) { - if (!Validate::isGenericName($childFtrLang[$kChild])) { - $this->errors[] = $this->l('Invalid child feature name in ').$lang['name']. - ' : '.Tools::safeOutput($childFtrLang[$kChild]); - } - } - } - } - } - } else { - $this->errors[] = $this->l('Please add atleast one Child features.'); - } - - if (!count($this->errors)) { - if (isset($parentFeatureId) && $parentFeatureId) { - $objHotelFeatures = new HotelFeatures($parentFeatureId); - $childFeatureIds = Tools::getValue('child_feature_id'); - foreach ($languages as $lang) { - if (!trim(Tools::getValue('parent_ftr_name_'.$lang['id_lang']))) { - $objHotelFeatures->name[$lang['id_lang']] = Tools::getValue( - 'parent_ftr_name_'.$defaultLangId - ); - } else { - $objHotelFeatures->name[$lang['id_lang']] = Tools::getValue( - 'parent_ftr_name_'.$lang['id_lang'] - ); - } - } - $objHotelFeatures->active = 1; - $objHotelFeatures->position = $pos; - $objHotelFeatures->parent_feature_id = 0; - $objHotelFeatures->save(); - - if ($childFeaturesDefLang) { - // get previous child features of the parent feature - if ($childFeaturesInfo = $objHotelFeatures->getChildFeaturesByParentFeatureId( - $parentFeatureId - )) { - $prevChildIds = array(); - foreach ($childFeaturesInfo as $row) { - $prevChildIds[] = $row['id']; - } - } - $usedFeatures = array(); - foreach ($childFeaturesDefLang as $key => $childftr) { - $objHotelFeatures = new HotelFeatures(); - // We will only create new child features other wise edit the previous child feature - if ($prevChildIds - && isset($childFeatureIds[$key]) - && in_array($childFeatureIds[$key], $prevChildIds) - ) { - $objHotelFeatures = new HotelFeatures($childFeatureIds[$key]); - // enter child feature id in the used child feature - $usedFeatures[] = $childFeatureIds[$key]; - } - foreach ($languages as $lang) { - if (!trim(Tools::getValue('child_features_'.$lang['id_lang'])[$key])) { - $objHotelFeatures->name[$lang['id_lang']] = $childftr; - } else { - $objHotelFeatures->name[$lang['id_lang']] = Tools::getValue( - 'child_features_'.$lang['id_lang'] - )[$key]; - } - } - $objHotelFeatures->active = 1; - $objHotelFeatures->parent_feature_id = $parentFeatureId; - $objHotelFeatures->save(); - } - // delete the child features which are not used now - $notUsedChilds = array_diff($prevChildIds, $usedFeatures); - if ($notUsedChilds = array_diff($prevChildIds, $usedFeatures)) { - foreach ($notUsedChilds as $value) { - if ($value) { - $objHotelFeatures = new HotelFeatures($value); - $objHotelFeatures->delete(); - } - } - } - if (Tools::isSubmit('submitHtlFeaturesAndStay')) { - Tools::redirectAdmin( - self::$currentIndex.'&id='.(int) $parentFeatureId.'&update'.$this->table. - '&conf='.$conf.'&token='.$this->token - ); - } else { - Tools::redirectAdmin(self::$currentIndex.'&conf='.$conf.'&token='.$this->token); - } - } else { - $this->errors[] = $this->l('Some error has been occurred while saving features.'); - } - } else { - $objHotelFeatures = new HotelFeatures(); - foreach ($languages as $lang) { - if (!trim(Tools::getValue('parent_ftr_name_'.$lang['id_lang']))) { - $objHotelFeatures->name[$lang['id_lang']] = Tools::getValue( - 'parent_ftr_name_'.$defaultLangId - ); - } else { - $objHotelFeatures->name[$lang['id_lang']] = Tools::getValue( - 'parent_ftr_name_'.$lang['id_lang'] - ); - } - } - $objHotelFeatures->active = 1; - $objHotelFeatures->position = $pos; - $objHotelFeatures->parent_feature_id = 0; - $objHotelFeatures->save(); - if ($parentFeatureId = $objHotelFeatures->id) { - if ($childFeaturesDefLang) { - foreach ($childFeaturesDefLang as $key => $childftr) { - $objHotelFeatures = new HotelFeatures(); - foreach ($languages as $lang) { - if (!trim(Tools::getValue('child_features_'.$lang['id_lang'])[$key])) { - $objHotelFeatures->name[$lang['id_lang']] = $childftr; - } else { - $objHotelFeatures->name[$lang['id_lang']] = Tools::getValue( - 'child_features_'.$lang['id_lang'] - )[$key]; - } - } - $objHotelFeatures->active = 1; - $objHotelFeatures->parent_feature_id = $parentFeatureId; - $objHotelFeatures->save(); - } - if (Tools::isSubmit('submitHtlFeaturesAndStay')) { - Tools::redirectAdmin( - self::$currentIndex.'&id='.(int) $parentFeatureId.'&update'.$this->table. - '&conf='.$conf.'&token='.$this->token - ); - } else { - Tools::redirectAdmin(self::$currentIndex.'&conf='.$conf.'&token='.$this->token); - } - } - } else { - $this->errors[] = $this->l('Some error has been occurred while saving features.'); - } - } - } - if ($parentFeatureId) { - $this->display = 'edit'; - } else { - $this->display = 'add'; - } - } - - if (empty($this->errors) || $this->ajax) { - parent::postProcess(); - } - } - - public function ajaxProcessDeleteFeature() - { - $response = array('status' => false); - if ($this->tabAccess['delete']) { - $idFeature = Tools::getValue('feature_id'); - $objHotelFeatures = new HotelFeatures(); - if ($objHotelFeatures->deleteHotelFeatures($idFeature)) { - $response['status'] = true; - } else { - $response['msg'] = $this->l('Some error occurred while deleting feature. Please try again.'); - } - } else { - $response['msg'] = $this->l('You do not have the permission to delete this.'); - } - - $this->ajaxDie(json_encode($response)); - } - - public function setMedia() - { - parent::setMedia(); - - $this->addJs(_MODULE_DIR_.'hotelreservationsystem/views/js/HotelReservationAdmin.js'); - $this->addCSS(_MODULE_DIR_.'hotelreservationsystem/views/css/HotelReservationAdmin.css'); - } -} diff --git a/modules/hotelreservationsystem/define.php b/modules/hotelreservationsystem/define.php index 46ac79645..1f6809c2b 100644 --- a/modules/hotelreservationsystem/define.php +++ b/modules/hotelreservationsystem/define.php @@ -26,8 +26,9 @@ require_once 'classes/HotelRoomType.php'; require_once 'classes/HotelRoomInformation.php'; require_once 'classes/HotelBranchInformation.php'; require_once 'classes/HotelImage.php'; -require_once 'classes/HotelFeatures.php'; -require_once 'classes/HotelBranchFeatures.php'; +require_once 'classes/HotelAmenities.php'; +require_once 'classes/HotelBranchAmenities.php'; +require_once 'classes/HotelRoomTypeAmenities.php'; require_once 'classes/HotelBookingDetail.php'; require_once 'classes/HotelCartBookingData.php'; require_once 'classes/HotelAdvancedPayment.php'; @@ -47,8 +48,6 @@ require_once 'classes/HotelRoomTypeRestrictionDateRange.php'; require_once 'classes/HotelRoomDisableDates.php'; require_once 'classes/HotelBranchRefundRules.php'; -require_once 'classes/HotelBedType.php'; -require_once 'classes/HotelRoomTypeBedType.php'; require_once 'classes/HotelConnectedRoom.php'; // linked products diff --git a/modules/hotelreservationsystem/hotelreservationsystem.php b/modules/hotelreservationsystem/hotelreservationsystem.php index 5246337d7..2c4e74ced 100644 --- a/modules/hotelreservationsystem/hotelreservationsystem.php +++ b/modules/hotelreservationsystem/hotelreservationsystem.php @@ -33,7 +33,7 @@ class HotelReservationSystem extends Module { $this->name = 'hotelreservationsystem'; $this->tab = 'administration'; - $this->version = '1.7.0'; + $this->version = '1.7.1'; $this->author = 'Webkul'; $this->need_instance = 0; $this->bootstrap = true; @@ -48,7 +48,7 @@ class HotelReservationSystem extends Module $resources = array( 'hotels' => array('description' => 'Hotel Branch Information','class' => 'HotelBranchInformation'), 'hotel_room_types' => array('description' => 'Hotel room types','class' => 'HotelRoomType'), - 'hotel_features' => array('description' => 'The hotel features','class' => 'HotelFeatures'), + 'hotel_amenities' => array('description' => 'The hotel amenities', 'class' => 'HotelAmenities'), 'hotel_refund_rules' => array('description' => 'The hotel refund rules','class' => 'HotelOrderRefundRules'), 'hotel_rooms' => array('description' => 'The hotel rooms','class' => 'HotelRoomInformation'), 'feature_prices' => array('description' => 'Feature prices', 'class' => 'HotelRoomTypeFeaturePricing'), @@ -473,12 +473,11 @@ class HotelReservationSystem extends Module $langTables = array( 'htl_room_type_feature_pricing', 'htl_branch_info', - 'htl_features', + 'htl_amenity', 'htl_room_type_global_demand', 'htl_room_type_global_demand_advance_option', 'htl_order_refund_rules', - 'htl_settings_link', - 'htl_bed_type' + 'htl_settings_link' ); //If Admin update new language when we do entry in module all lang tables. HotelHelper::updateLangTables($newIdLang, $langTables); @@ -520,12 +519,11 @@ class HotelReservationSystem extends Module $this->installTab('AdminHotelReservationSystemManagement', 'Hotel Reservation System'); $this->installTab('AdminAddHotel', 'Manage Hotel', 'AdminHotelReservationSystemManagement'); $this->installTab('AdminHotelRoomsBooking', 'Book Now', 'AdminHotelReservationSystemManagement'); - $this->installTab('AdminHotelFeatures', 'Manage Hotel Features', 'AdminHotelReservationSystemManagement'); + $this->installTab('AdminHotelAmenities', 'Manage Amenities', 'AdminHotelReservationSystemManagement'); $this->installTab('AdminOrderRefundRules', 'Manage Order Refund Rules', 'AdminHotelReservationSystemManagement'); $this->installTab('AdminOrderRefundRequests', 'Manage Order Refund Requests', 'AdminHotelReservationSystemManagement'); $this->installTab('AdminHotelConfigurationSetting', 'General Settings', 'AdminHotelReservationSystemManagement'); - $this->installTab('AdminHotelBedTypes', 'Bed Types', 'AdminCatalog'); // Controllers without tabs $this->installTab('AdminHotelGeneralSettings', 'Hotel General Configuration', 'AdminHotelConfigurationSetting', false); $this->installTab('AdminHotelFeaturePricesSettings', 'Advanced Price Rules', 'AdminHotelConfigurationSetting', false); @@ -575,8 +573,7 @@ class HotelReservationSystem extends Module || !$this->callInstallTab() || !$objHtlHelper->insertDefaultHotelEntries() || !$objHtlHelper->createHotelRoomDefaultFeatures() - || !$objHtlHelper->createHotelDefaultBedTypes() - || !$objHtlHelper->insertHotelCommonFeatures() + || !$objHtlHelper->insertHotelCommonAmenities() ) { return false; } diff --git a/modules/hotelreservationsystem/views/css/HotelReservationAdmin.css b/modules/hotelreservationsystem/views/css/HotelReservationAdmin.css index e3b6077b2..9ad222ecb 100644 --- a/modules/hotelreservationsystem/views/css/HotelReservationAdmin.css +++ b/modules/hotelreservationsystem/views/css/HotelReservationAdmin.css @@ -604,4 +604,4 @@ p.room_cat_data margin-top: 15px;} .error-border { outline: rgb(210, 124, 130) solid 1px; - border-radius: 2px;} + border-radius: 2px;} \ No newline at end of file diff --git a/modules/hotelreservationsystem/views/css/hotelAmenity.css b/modules/hotelreservationsystem/views/css/hotelAmenity.css new file mode 100644 index 000000000..624796fb5 --- /dev/null +++ b/modules/hotelreservationsystem/views/css/hotelAmenity.css @@ -0,0 +1,48 @@ +/** + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License version 3.0 + * that is bundled with this package in the file LICENSE.md + * It is also available through the world-wide-web at this URL: + * https://opensource.org/license/osl-3.0-php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to support@qloapps.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade this module to a newer + * versions in the future. If you wish to customize this module for your needs + * please refer to https://store.webkul.com/customisation-guidelines for more information. + * + * @author Webkul IN + * @copyright Since 2010 Webkul + * @license https://opensource.org/license/osl-3.0-php Open Software License version 3.0 + */ + +/* ---- View ---- */ +.htl-amenity-category-heading { + display: flex; + align-items: center; + min-height: 46px; +} +.htl-amenity-category-heading .pull-right { + float: none !important; + margin-left: auto; + order: 2; +} +.htl-amenity-logo-img { + max-height: 32px; + max-width: 32px; +} + +/* ---- Form ---- */ +.htl-amenity-preview { + margin-bottom: 8px; +} +.htl-amenity-preview img { + max-width: 80px; + max-height: 80px; + border: 1px solid #ddd; + padding: 4px; +} diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/1.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/1.jpg new file mode 100644 index 000000000..a3ca11b20 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/1.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/10.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/10.jpg new file mode 100644 index 000000000..548af697d Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/10.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/11.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/11.jpg new file mode 100644 index 000000000..7b76b5c8e Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/11.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/12.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/12.jpg new file mode 100644 index 000000000..12b2e96fc Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/12.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/13.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/13.jpg new file mode 100644 index 000000000..39a77ac74 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/13.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/14.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/14.jpg new file mode 100644 index 000000000..1e627e70b Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/14.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/15.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/15.jpg new file mode 100644 index 000000000..399ba7fb1 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/15.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/16.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/16.jpg new file mode 100644 index 000000000..3cf466634 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/16.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/17.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/17.jpg new file mode 100644 index 000000000..83caa28bc Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/17.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/18.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/18.jpg new file mode 100644 index 000000000..98ae378c3 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/18.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/19.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/19.jpg new file mode 100644 index 000000000..60061d9ee Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/19.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/2.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/2.jpg new file mode 100644 index 000000000..1b93c0b78 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/2.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/20.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/20.jpg new file mode 100644 index 000000000..e4b1ebc4b Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/20.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/21.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/21.jpg new file mode 100644 index 000000000..00ce92b18 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/21.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/22.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/22.jpg new file mode 100644 index 000000000..c575a9575 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/22.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/23.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/23.jpg new file mode 100644 index 000000000..7d8725672 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/23.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/24.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/24.jpg new file mode 100644 index 000000000..b68cad70b Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/24.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/25.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/25.jpg new file mode 100644 index 000000000..94d457477 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/25.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/26.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/26.jpg new file mode 100644 index 000000000..948a7f2c3 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/26.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/27.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/27.jpg new file mode 100644 index 000000000..ab81b6aa4 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/27.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/28.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/28.jpg new file mode 100644 index 000000000..dada6eb54 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/28.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/29.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/29.jpg new file mode 100644 index 000000000..2a51ba4c3 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/29.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/3.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/3.jpg new file mode 100644 index 000000000..81b917dc3 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/3.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/30.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/30.jpg new file mode 100644 index 000000000..5b2be3134 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/30.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/31.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/31.jpg new file mode 100644 index 000000000..55daf3009 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/31.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/32.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/32.jpg new file mode 100644 index 000000000..c12ccfa1d Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/32.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/33.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/33.jpg new file mode 100644 index 000000000..41079f334 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/33.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/34.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/34.jpg new file mode 100644 index 000000000..c3f3b8c61 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/34.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/35.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/35.jpg new file mode 100644 index 000000000..79e4974df Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/35.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/36.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/36.jpg new file mode 100644 index 000000000..a1d02706c Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/36.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/37.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/37.jpg new file mode 100644 index 000000000..485db1b53 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/37.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/38.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/38.jpg new file mode 100644 index 000000000..1e0308503 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/38.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/39.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/39.jpg new file mode 100644 index 000000000..cae4f9409 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/39.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/4.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/4.jpg new file mode 100644 index 000000000..a609dbc90 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/4.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/40.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/40.jpg new file mode 100644 index 000000000..0a3393e40 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/40.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/41.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/41.jpg new file mode 100644 index 000000000..1a46bc56f Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/41.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/42.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/42.jpg new file mode 100644 index 000000000..b8a3981ee Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/42.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/43.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/43.jpg new file mode 100644 index 000000000..53b54e78e Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/43.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/44.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/44.jpg new file mode 100644 index 000000000..620dcccb1 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/44.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/45.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/45.jpg new file mode 100644 index 000000000..cb60b74d2 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/45.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/46.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/46.jpg new file mode 100644 index 000000000..616f13c29 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/46.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/47.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/47.jpg new file mode 100644 index 000000000..76c45c4c6 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/47.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/48.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/48.jpg new file mode 100644 index 000000000..c8b6c160b Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/48.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/49.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/49.jpg new file mode 100644 index 000000000..09df629ca Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/49.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/5.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/5.jpg new file mode 100644 index 000000000..e7126905f Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/5.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/50.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/50.jpg new file mode 100644 index 000000000..ba9f839e7 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/50.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/51.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/51.jpg new file mode 100644 index 000000000..84908cf6d Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/51.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/52.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/52.jpg new file mode 100644 index 000000000..1f5e06ac2 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/52.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/53.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/53.jpg new file mode 100644 index 000000000..9f7c7a6c6 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/53.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/54.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/54.jpg new file mode 100644 index 000000000..0fe4fda70 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/54.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/55.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/55.jpg new file mode 100644 index 000000000..6e28c9627 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/55.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/56.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/56.jpg new file mode 100644 index 000000000..ec18d3d44 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/56.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/57.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/57.jpg new file mode 100644 index 000000000..b8a3981ee Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/57.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/58.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/58.jpg new file mode 100644 index 000000000..080603f14 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/58.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/59.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/59.jpg new file mode 100644 index 000000000..25b3c49c1 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/59.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/6.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/6.jpg new file mode 100644 index 000000000..b108df6ee Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/6.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/60.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/60.jpg new file mode 100644 index 000000000..06009d4c9 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/60.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/61.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/61.jpg new file mode 100644 index 000000000..f5bb8cf86 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/61.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/62.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/62.jpg new file mode 100644 index 000000000..183cde895 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/62.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/63.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/63.jpg new file mode 100644 index 000000000..64b57b651 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/63.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/64.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/64.jpg new file mode 100644 index 000000000..249211644 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/64.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/65.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/65.jpg new file mode 100644 index 000000000..578274a08 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/65.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/66.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/66.jpg new file mode 100644 index 000000000..26b8488a2 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/66.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/67.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/67.jpg new file mode 100644 index 000000000..4faaa8b00 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/67.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/68.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/68.jpg new file mode 100644 index 000000000..18833cabf Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/68.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/7.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/7.jpg new file mode 100644 index 000000000..1951723ba Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/7.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/70.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/70.jpg new file mode 100644 index 000000000..b49af88d2 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/70.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/71.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/71.jpg new file mode 100644 index 000000000..75b97424e Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/71.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/72.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/72.jpg new file mode 100644 index 000000000..561c29fed Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/72.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/73.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/73.jpg new file mode 100644 index 000000000..01dc8c214 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/73.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/74.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/74.jpg new file mode 100644 index 000000000..3b8d81308 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/74.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/75.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/75.jpg new file mode 100644 index 000000000..90cef1519 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/75.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/76.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/76.jpg new file mode 100644 index 000000000..10b2c1703 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/76.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/77.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/77.jpg new file mode 100644 index 000000000..0a183cd6f Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/77.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/78.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/78.jpg new file mode 100644 index 000000000..28f6774ab Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/78.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/79.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/79.jpg new file mode 100644 index 000000000..2982e2450 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/79.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/8.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/8.jpg new file mode 100644 index 000000000..7747b2a7e Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/8.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/80.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/80.jpg new file mode 100644 index 000000000..bfaedda60 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/80.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/81.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/81.jpg new file mode 100644 index 000000000..e32e31eb5 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/81.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/82.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/82.jpg new file mode 100644 index 000000000..c8c206c4e Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/82.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/83.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/83.jpg new file mode 100644 index 000000000..38e9dfa9d Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/83.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/84.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/84.jpg new file mode 100644 index 000000000..dd293ecc6 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/84.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/85.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/85.jpg new file mode 100644 index 000000000..89a3b31dd Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/85.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/86.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/86.jpg new file mode 100644 index 000000000..d8b9236fc Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/86.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/87.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/87.jpg new file mode 100644 index 000000000..d0a005131 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/87.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/88.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/88.jpg new file mode 100644 index 000000000..a8014f8bb Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/88.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/89.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/89.jpg new file mode 100644 index 000000000..41079f334 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/89.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/9.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/9.jpg new file mode 100644 index 000000000..f3b1cc74c Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/9.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/90.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/90.jpg new file mode 100644 index 000000000..7fd04e01d Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/90.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/91.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/91.jpg new file mode 100644 index 000000000..63ab0172d Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/91.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/92.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/92.jpg new file mode 100644 index 000000000..4b98eea26 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/92.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/93.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/93.jpg new file mode 100644 index 000000000..b1dd4f683 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/93.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/94.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/94.jpg new file mode 100644 index 000000000..ac8fde922 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/94.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/95.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/95.jpg new file mode 100644 index 000000000..5a3baa6db Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/95.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/96.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/96.jpg new file mode 100644 index 000000000..12b2e96fc Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/96.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/97.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/97.jpg new file mode 100644 index 000000000..a1d94dd9f Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/97.jpg differ diff --git a/modules/hotelreservationsystem/views/img/hotel_amenities/_default/98.jpg b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/98.jpg new file mode 100644 index 000000000..d403392e0 Binary files /dev/null and b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/98.jpg differ diff --git a/modules/hotelreservationsystem/views/templates/admin/assign_hotel_features/helpers/form/index.php b/modules/hotelreservationsystem/views/img/hotel_amenities/_default/index.php similarity index 100% rename from modules/hotelreservationsystem/views/templates/admin/assign_hotel_features/helpers/form/index.php rename to modules/hotelreservationsystem/views/img/hotel_amenities/_default/index.php diff --git a/modules/hotelreservationsystem/views/templates/admin/assign_hotel_features/helpers/index.php b/modules/hotelreservationsystem/views/img/hotel_amenities/index.php similarity index 100% rename from modules/hotelreservationsystem/views/templates/admin/assign_hotel_features/helpers/index.php rename to modules/hotelreservationsystem/views/img/hotel_amenities/index.php diff --git a/modules/hotelreservationsystem/views/js/HotelReservationAdmin.js b/modules/hotelreservationsystem/views/js/HotelReservationAdmin.js index b3232b15f..4faafa4da 100644 --- a/modules/hotelreservationsystem/views/js/HotelReservationAdmin.js +++ b/modules/hotelreservationsystem/views/js/HotelReservationAdmin.js @@ -954,3 +954,60 @@ function showLangField(select_lang_name, id_lang) $(function() { $('[data-toggle="popover"]').popover() }); + +/* ---- Hotel Featured Amenities (AdminAddHotelController) ---- */ +(function ($) { + var featuredIds = []; + var $select; + var chosenReady = false; + + function syncAmenitiesToFeatured() { + if (!$select || !$select.length) { + return; + } + var existing = {}; + $select.find('option').each(function () { + existing[$(this).val()] = true; + }); + $('input[name="id_amenities[]"]').each(function () { + var $checkbox = $(this); + var id = $checkbox.val(); + var name = $checkbox.siblings('label.tree-toggler').text().trim(); + if ($checkbox.is(':checked')) { + if (!existing[id]) { + var selected = featuredIds.indexOf(parseInt(id)) !== -1; + $select.append($('').val(id).text(name).prop('selected', selected)); + } + } else { + $select.find('option[value="' + id + '"]').remove(); + } + }); + if (chosenReady) { + $select.trigger('chosen:updated'); + } + } + + $(document).on('click', '#hotel-amenities-tree :input[type="checkbox"]', function () { + setTimeout(syncAmenitiesToFeatured, 0); + }); + + $(document).on('click', '#check-all-hotel-amenities-tree, #uncheck-all-hotel-amenities-tree', function () { + setTimeout(syncAmenitiesToFeatured, 0); + }); + + $(document).ready(function () { + featuredIds = (typeof htlFeaturedAmenityIds !== 'undefined') ? htlFeaturedAmenityIds : []; + $select = $('#htl_featured_amenities'); + syncAmenitiesToFeatured(); + + $('a[href="#hotel-features"]').on('shown.bs.tab', function () { + syncAmenitiesToFeatured(); + if (!chosenReady) { + $select.chosen({ disable_search_threshold: 5, search_contains: true }); + chosenReady = true; + } else { + $select.trigger('chosen:updated'); + } + }); + }); +}(jQuery)); diff --git a/modules/hotelreservationsystem/views/js/hotelAmenity.js b/modules/hotelreservationsystem/views/js/hotelAmenity.js new file mode 100644 index 000000000..487f03b77 --- /dev/null +++ b/modules/hotelreservationsystem/views/js/hotelAmenity.js @@ -0,0 +1,103 @@ +/** + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License version 3.0 + * that is bundled with this package in the file LICENSE.md + * It is also available through the world-wide-web at this URL: + * https://opensource.org/license/osl-3.0-php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to support@qloapps.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade this module to a newer + * versions in the future. If you wish to customize this module for your needs + * please refer to https://store.webkul.com/customisation-guidelines for more information. + * + * @author Webkul IN + * @copyright Since 2010 Webkul + * @license https://opensource.org/license/osl-3.0-php Open Software License version 3.0 + */ + +/* ---- AdminHotelAmenitiesController - Form ---- */ +$(document).ready(function () { + $('#htl_logo_type_select').on('change', function () { + if ($(this).val() === 'icon') { + $('#htl_logo_image_row').hide(); + $('#htl_logo_icon_row').show(); + } else { + $('#htl_logo_icon_row').hide(); + $('#htl_logo_image_row').show(); + } + }); + + $('#logo_image-selectbutton').on('click', function () { + $('#logo_image').trigger('click'); + }); + + $('#logo_image-name').on('click', function () { + $('#logo_image').trigger('click'); + }); + + $('#logo_image').on('change', function () { + var files = this.files; + if (files && files.length > 0) { + $('#logo_image-name').val(files[0].name); + } else { + var name = $(this).val().split(/[\\/]/); + $('#logo_image-name').val(name[name.length - 1]); + } + }); +}); + +/* ---- AdminHotelAmenitiesController - View ---- */ +(function ($) { + $(document).on('click', '.htl-delete-category', function (e) { + e.preventDefault(); + if (!confirm(confirm_delete_msg)) { return; } + var $btn = $(this); + $.ajax({ + url: delete_url, + type: 'POST', + data: { + ajax: 1, + action: 'DeleteCategory', + id_category: $btn.data('category-id'), + token: htlAmenityToken + }, + success: function (res) { + var r = $.parseJSON(res); + if (r.status) { + window.location = delete_url + '&conf=1'; + } else { + showErrorMessage(error_delete_msg); + } + } + }); + }); + + $(document).on('click', '.htl-delete-amenity', function (e) { + e.preventDefault(); + if (!confirm(confirm_delete_msg)) { return; } + var $btn = $(this); + $.ajax({ + url: delete_url, + type: 'POST', + data: { + ajax: 1, + action: 'DeleteAmenityItem', + id_amenity: $btn.data('amenity-id'), + token: htlAmenityToken + }, + success: function (res) { + var r = $.parseJSON(res); + if (r.status) { + window.location = delete_url + '&conf=1'; + } else { + showErrorMessage(error_delete_msg); + } + } + }); + }); +}(jQuery)); 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 978872548..244a174f2 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 @@ -95,7 +95,7 @@
  • - {l s='Features' mod='hotelreservationsystem'} + {l s='Amenities' mod='hotelreservationsystem'}
  • {hook h='displayAdminAddHotelFormTab' id_hotel=$hook_arg_id_hotel} @@ -610,22 +610,43 @@
    {hook h='displayAdminAddHotelFormFeaturesTabBefore' id_hotel=$hook_arg_id_hotel} - {if isset($hotel_feature_tree)} +
    +

    {l s='If you want to add a new amenity, please use the following link.'} + + {l s='Manage amenities'} + +

    +
    + {if isset($hotel_amenity_tree)}
    -
    - -{strip} - {addJsDefL name=prnt_ftr_err}{l s='Enter Parent feature name first.' js=1 mod='hotelreservationsystem'}{/addJsDefL} - {addJsDefL name=chld_ftr_err}{l s='Enter at least one child feature.' js=1 mod='hotelreservationsystem'}{/addJsDefL} - {addJsDefL name=chld_ftr_text_err}{l s='Enter child feature name.' js=1 mod='hotelreservationsystem'}{/addJsDefL} - {addJsDefL name=pos_numeric_err}{l s='Position should be numeric.' js=1 mod='hotelreservationsystem'}{/addJsDefL} -{/strip} - -{block name=script} - -{/block} diff --git a/modules/hotelreservationsystem/views/templates/admin/hotel_features/helpers/view/view.tpl b/modules/hotelreservationsystem/views/templates/admin/hotel_features/helpers/view/view.tpl deleted file mode 100644 index a4e59dea7..000000000 --- a/modules/hotelreservationsystem/views/templates/admin/hotel_features/helpers/view/view.tpl +++ /dev/null @@ -1,68 +0,0 @@ -{* -* NOTICE OF LICENSE -* -* This source file is subject to the Open Software License version 3.0 -* that is bundled with this package in the file LICENSE.md -* It is also available through the world-wide-web at this URL: -* https://opensource.org/license/osl-3-0-php -* If you did not receive a copy of the license and are unable to -* obtain it through the world-wide-web, please send an email -* to support@qloapps.com so we can send you a copy immediately. -* -* DISCLAIMER -* -* Do not edit or add to this file if you wish to upgrade this module to a newer -* versions in the future. If you wish to customize this module for your needs -* please refer to https://store.webkul.com/customisation-guidelines for more information. -* -* @author Webkul IN -* @copyright Since 2010 Webkul -* @license https://opensource.org/license/osl-3-0-php Open Software License version 3.0 -*} - -
    -
    - {l s='Hotel Features' mod='hotelreservationsystem'} -
    -
    -
    - {if $features_list} - {foreach from=$features_list item=value} -
    -
    -
    -
    -
    - {l s={$value.name} mod='hotelreservationsyatem'} -     {l s='Edit' mod='hotelreservationsystem'} - -
    -
    -
    -
    -
    -
    - {if isset($value.children) && $value.children} - {foreach from=$value.children item=val} -

    {l s={$val.name} mod='hotelreservationsyatem'}

    - {/foreach} - {/if} -
    -
    -
    - {/foreach} - {else} -
    - {l s='No hotel features found. Start adding new features for the hotels.' mod='hotelreservationsystem'} -
    - {/if} -
    -
    -
    -{strip} - {addJsDef delete_url=$link->getAdminLink('AdminHotelFeatures') js=1 mod='hotelreservationsystem'} - {addJsDefL name=success_delete_msg}{l s='Successfully Deleted.' js=1 mod='hotelreservationsystem'}{/addJsDefL} - {addJsDefL name=error_delete_msg}{l s='Some error occured while deleting feature.Please try again.' js=1 mod='hotelreservationsystem'}{/addJsDefL} - {addJsDefL name=no_feature_warning_txt}{l s='No hotel features found. Start adding new features for the hotels.' js=1 mod='hotelreservationsystem'}{/addJsDefL} - {addJsDefL name=confirm_delete_msg}{l s='Are you sure?' js=1 mod='hotelreservationsystem'}{/addJsDefL} -{/strip} \ No newline at end of file diff --git a/modules/qlocleaner/qlocleaner.php b/modules/qlocleaner/qlocleaner.php index 8b532ef5a..c44060b28 100644 --- a/modules/qlocleaner/qlocleaner.php +++ b/modules/qlocleaner/qlocleaner.php @@ -690,8 +690,8 @@ class QloCleaner extends Module array('htl_room_type_global_demand_lang', 'id_global_demand', 'htl_room_type_global_demand', 'id_global_demand'), array('htl_branch_info_lang', 'id_lang', 'lang', 'id_lang'), array('htl_branch_info_lang', 'id', 'htl_branch_info', 'id'), - array('htl_features_lang', 'id_lang', 'lang', 'id_lang'), - array('htl_features_lang', 'id', 'htl_features', 'id'), + array('htl_amenity_lang', 'id_lang', 'lang', 'id_lang'), + array('htl_amenity_lang', 'id_amenity', 'htl_amenity', 'id_amenity'), array('htl_room_type_demand', 'id_global_demand', 'htl_room_type_global_demand', 'id_global_demand'), array('htl_room_type_demand', 'id_product', 'product', 'id_product'), array('htl_room_type_demand_price', 'id_product', 'product', 'id_product'), @@ -704,7 +704,8 @@ class QloCleaner extends Module array('htl_booking_demands', 'id_htl_booking', 'htl_booking_detail', 'id_htl_booking'), array('htl_cart_booking_data', 'id_order', 'orders', 'id_order'), array('htl_cart_booking_data', 'id_customer', 'customer', 'id_customer'), - array('htl_branch_features', 'id_hotel', 'htl_branch_info', 'id'), + array('htl_branch_amenity', 'id_hotel', 'htl_branch_info', 'id'), + array('htl_branch_amenity', 'amenity_id', 'htl_amenity', 'id_amenity'), array('htl_image', 'id_hotel', 'htl_branch_info', 'id'), array('htl_branch_info', 'id_category', 'category', 'id_category'), array('htl_room_information', 'id_product', 'product', 'id_product'), @@ -727,9 +728,8 @@ class QloCleaner extends Module array('htl_room_type_service_product', 'id_element', 'product', 'id_product'), array('htl_room_type_service_product_price', 'id_product', 'product', 'id_product'), array('htl_room_type_service_product_price', 'id_element', 'product', 'id_product'), - array('htl_bed_type_lang', 'id_lang', 'lang', 'id_lang'), - array('htl_room_type_bed_type', 'id_product', 'product', 'id_product'), - array('htl_room_type_bed_type', 'id_bed_type', 'htl_bed_type', 'id_bed_type'), + array('htl_room_type_amenity', 'id_product', 'product', 'id_product'), + array('htl_room_type_amenity', 'amenity_id', 'htl_amenity', 'id_amenity'), ) ); @@ -813,7 +813,7 @@ class QloCleaner extends Module 'htl_branch_info', 'htl_branch_info_lang', 'htl_image', - 'htl_branch_features', + 'htl_branch_amenity', 'htl_advance_payment', 'htl_branch_refund_rules', 'htl_order_restrict_date', @@ -831,9 +831,7 @@ class QloCleaner extends Module 'htl_room_type_global_demand', 'htl_room_type_service_product', 'htl_room_type_service_product_price', - 'htl_bed_type', - 'htl_bed_type_lang', - 'htl_room_type_bed_type', + 'htl_room_type_amenity', ) ); } diff --git a/modules/wkhotelfilterblock/views/templates/hook/htlfilterblock.tpl b/modules/wkhotelfilterblock/views/templates/hook/htlfilterblock.tpl index 0929ac1f6..7f72fdca6 100644 --- a/modules/wkhotelfilterblock/views/templates/hook/htlfilterblock.tpl +++ b/modules/wkhotelfilterblock/views/templates/hook/htlfilterblock.tpl @@ -24,7 +24,7 @@
    {block name='room_types_amenities_filter'} - {if isset($config) && $config['SHOW_AMENITIES_FILTER'] && $all_feat} + {if isset($config) && $config['SHOW_AMENITIES_FILTER'] && $all_amenities}
    @@ -36,10 +36,10 @@
    - {foreach $all_feat as $feat} + {foreach $all_amenities as $amenity}
    - - {$feat.name} + + {$amenity.name}
    {/foreach}
    diff --git a/modules/wkhotelfilterblock/wkhotelfilterblock.php b/modules/wkhotelfilterblock/wkhotelfilterblock.php index 17226b9a2..b2afe5cbc 100644 --- a/modules/wkhotelfilterblock/wkhotelfilterblock.php +++ b/modules/wkhotelfilterblock/wkhotelfilterblock.php @@ -179,7 +179,7 @@ class wkhotelfilterblock extends Module $this->context->controller->addJS($this->_path.'/views/js/wkhotelfilterblock.js'); $this->context->controller->addCSS($this->_path.'/views/css/wkhotelfilterblock.css'); $id_lang = $this->context->language->id; - $all_feat = FeatureCore::getFeatures($id_lang); + $all_amenities = HotelAmenities::getAmenities($id_lang); $max_adult = HotelRoomType::getMaxAdults($id_hotel); $max_child = HotelRoomType::getMaxChild($id_hotel); @@ -235,7 +235,7 @@ class wkhotelfilterblock extends Module $warning_num = Configuration::get('WK_ROOM_LEFT_WARNING_NUMBER'); $this->context->smarty->assign(array( 'warning_num' => $warning_num, - 'all_feat' => $all_feat, + 'all_amenities' => $all_amenities, 'max_adult' => $max_adult, 'max_child' => $max_child, 'cat_link' => $categoryUrl, diff --git a/themes/hotel-reservation-theme/_partials/room_type_list.tpl b/themes/hotel-reservation-theme/_partials/room_type_list.tpl index aaa0f3ec0..7aadb79ba 100644 --- a/themes/hotel-reservation-theme/_partials/room_type_list.tpl +++ b/themes/hotel-reservation-theme/_partials/room_type_list.tpl @@ -60,7 +60,13 @@ {if !empty($room_v['feature'])}

    {foreach from=$room_v['feature'] key=feat_k item=feat_v} - + {if $feat_v.logo_type == 'icon' && $feat_v.logo} + + {elseif $feat_v.logo_type == 'image' && $feat_v.logo} + + {/if} {/foreach}

    {/if} diff --git a/themes/hotel-reservation-theme/css/category.css b/themes/hotel-reservation-theme/css/category.css index 17cf23feb..93ac147ef 100644 --- a/themes/hotel-reservation-theme/css/category.css +++ b/themes/hotel-reservation-theme/css/category.css @@ -143,7 +143,7 @@ p.capa_txt { .rm_amenities_cont { - margin-bottom: 15px; + margin-bottom: 10px; } .rm_left @@ -155,11 +155,10 @@ p.capa_txt { .rm_amen { - height: 15px; - width: 15px; + width: 20px; display: inline-block; margin-right: 10px; - margin-bottom: 3px; + margin-bottom: 5px; } .rm_price_val diff --git a/themes/hotel-reservation-theme/css/product.css b/themes/hotel-reservation-theme/css/product.css index cee78c595..82d73e3c9 100644 --- a/themes/hotel-reservation-theme/css/product.css +++ b/themes/hotel-reservation-theme/css/product.css @@ -1282,6 +1282,23 @@ Quick View Styles background: #FFFFFF;} .room_info_content span.col-sm-4 { margin-bottom: 5px;} +.room_info_content.row { + line-height: 30px;} +.room_info_content.row .col-sm-4 { + overflow: hidden; + display: flex; + align-items: center; + gap: 5px;} +.room_info_content.row .col-sm-4 .amenity-name { + white-space: nowrap; + overflow: hidden;} +.room_feature_group { + margin-bottom: 15px;} +.room_feature_group .room_info_heading { + display: flex; + align-items: center; + gap: 5px; + margin-bottom: 3px;} .product_wrapper .form-control { background-color: transparent!important; diff --git a/themes/hotel-reservation-theme/product.tpl b/themes/hotel-reservation-theme/product.tpl index 67f4a03fe..b4878c11d 100644 --- a/themes/hotel-reservation-theme/product.tpl +++ b/themes/hotel-reservation-theme/product.tpl @@ -262,51 +262,87 @@
    {/if} {/block} - {block name='product_info_tab_room_bed_type'} - {if isset($selected_bed_types) && $selected_bed_types && isset($bed_types_info) && $bed_types_info} -
    -
    - {l s='Bed Types'} -
    -
    - {foreach $selected_bed_types as $selected_bed_type} - {if isset($bed_types_info[$selected_bed_type])} -

    {$bed_types_info[$selected_bed_type]['name']}: {$bed_types_info[$selected_bed_type]['area']} {l s='sq.'}{$dimension_unit}

    - {/if} - {/foreach} -
    -
    - {/if} - {/block} {block name='product_info_tab_room_features'} - {if isset($features) && $features} + {if isset($room_type_features) && $room_type_features}
    -
    - {l s='Room Features'} -
    -
    - {foreach from=$features key=ftr_k item=ftr_v} -
    -
    - {$ftr_v.name|escape:'html':'UTF-8'} + {assign var="current_feature_name" value=""} + {assign var="current_feature_values" value=""} + {assign var="current_feature_id" value=0} + {foreach from=$room_type_features item=feature} + {if $feature.name != $current_feature_name} + {if $current_feature_name != ""} +
    +
    + {$current_feature_name|escape:'html':'UTF-8'} + {$current_feature_name|escape:'html':'UTF-8'} +
    +
    {$current_feature_values|escape:'html':'UTF-8'}
    + {/if} + {assign var="current_feature_name" value=$feature.name} + {assign var="current_feature_id" value=$feature.id_feature} + {assign var="current_feature_values" value=$feature.value} + {else} + {assign var="current_feature_values" value="`$current_feature_values`, `$feature.value`"} + {/if} + {if $feature@last} +
    +
    + {$current_feature_name|escape:'html':'UTF-8'} + {$current_feature_name|escape:'html':'UTF-8'} +
    +
    {$current_feature_values|escape:'html':'UTF-8'}
    - {/foreach} -
    + {/if} + {/foreach}
    {/if} {/block} {* Block for booking products *} {if isset($id_hotel) && $id_hotel} - {block name='product_info_tab_hotel_features'} - {if isset($hotel_features) && $hotel_features} + {block name='product_info_tab_room_amenities'} + {if isset($room_dynamic_amenities) && $room_dynamic_amenities}
    - {l s='Hotel Features'} + {l s='Room Amenities'}
    - {foreach from=$hotel_features key=ftr_k item=ftr_v} -
    o {$ftr_v|escape:'html':'UTF-8'}
    + {foreach from=$room_dynamic_amenities item=amenity} +
    + {if $amenity.logo_type == 'icon' && $amenity.logo} + + {elseif $amenity.logo_type == 'image' && $amenity.logo} + {$amenity.name|escape:'html':'UTF-8'} + {/if} + {$amenity.name|escape:'html':'UTF-8'} +
    + {/foreach} +
    +
    + {/if} + {/block} + {block name='product_info_tab_hotel_features'} + {if isset($hotel_dynamic_amenities) && $hotel_dynamic_amenities} +
    +
    + {l s='Hotel Amenities'} +
    +
    + {foreach from=$hotel_dynamic_amenities item=amenity} +
    + {if $amenity.logo_type == 'icon' && $amenity.logo} + + {elseif $amenity.logo_type == 'image' && $amenity.logo} + {$amenity.name|escape:'html':'UTF-8'} + {/if} + {$amenity.name|escape:'html':'UTF-8'} +
    {/foreach}