| @@ -1,0 +1,579 @@ | ||
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * @package VikBooking | |
| 4 | + * @subpackage com_vikbooking | |
| 5 | + * @author Alessio Gaggii - e4j - Extensionsforjoomla.com | |
| 6 | + * @copyright Copyright (C) 2018 e4j - Extensionsforjoomla.com. All rights reserved. | |
| 7 | + * @license GNU General Public License version 2 or later; see LICENSE | |
| 8 | + * @link https://vikwp.com | |
| 9 | + */ | |
| 10 | + | |
| 11 | +defined('ABSPATH') or die('No script kiddies please!'); | |
| 12 | + | |
| 13 | +// import Joomla view library | |
| 14 | +jimport('joomla.application.component.view'); | |
| 15 | + | |
| 16 | +class VikBookingViewImportbftpp extends JViewVikBooking | |
| 17 | +{ | |
| 18 | + function display($tpl = null) | |
| 19 | + { | |
| 20 | + // Set the toolbar | |
| 21 | + $this->addToolBar(); | |
| 22 | + | |
| 23 | + $dbo = JFactory::getDbo(); | |
| 24 | + | |
| 25 | + // make sure there is at least one room-type in order to allow the bookings import | |
| 26 | + $setup_completed = 0; | |
| 27 | + $vbo_rooms = array(); | |
| 28 | + $q = "SELECT `id`,`name` FROM `#__vikbooking_rooms`;"; | |
| 29 | + $dbo->setQuery($q); | |
| 30 | + $dbo->execute(); | |
| 31 | + if ($dbo->getNumRows()) { | |
| 32 | + $records = $dbo->loadAssocList(); | |
| 33 | + foreach ($records as $record) { | |
| 34 | + $vbo_rooms[$record['id']] = $record['name']; | |
| 35 | + } | |
| 36 | + // change flag for setup completed | |
| 37 | + $setup_completed = 1; | |
| 38 | + } | |
| 39 | + | |
| 40 | + // process actions | |
| 41 | + $plugins = VikBooking::canImportBookingsFromThirdPartyPlugins(); | |
| 42 | + $tpbookings = array(); | |
| 43 | + $tprooms = array(); | |
| 44 | + $tpp = VikRequest::getString('tpp', '', 'request'); | |
| 45 | + $bimported = array(); | |
| 46 | + if (!empty($tpp) && $setup_completed && is_array($plugins) && isset($plugins[$tpp])) { | |
| 47 | + // grab the import information for this third party plugin | |
| 48 | + $bimported = get_option("vikbooking_importbftpp_{$tpp}", null); | |
| 49 | + $bimported = !empty($bimported) ? json_decode($bimported, true) : array(); | |
| 50 | + $bimported = !is_array($bimported) ? array() : $bimported; | |
| 51 | + | |
| 52 | + // load bookings from this third party plugin | |
| 53 | + switch ($tpp) { | |
| 54 | + case 'mphb': | |
| 55 | + // read bookings data | |
| 56 | + $q = "SELECT `p`.`ID`,`p`.`post_date`,`p`.`post_status`,`pm`.`meta_key`,`pm`.`meta_value` FROM `#__posts` AS `p` LEFT JOIN `#__postmeta` `pm` ON `p`.`ID`=`pm`.`post_id` WHERE `p`.`post_type`=" . $dbo->quote('mphb_booking') . " ORDER BY `p`.`post_date` DESC;"; | |
| 57 | + $dbo->setQuery($q); | |
| 58 | + $dbo->execute(); | |
| 59 | + if (!$dbo->getNumRows()) { | |
| 60 | + // no bookings found | |
| 61 | + break; | |
| 62 | + } | |
| 63 | + | |
| 64 | + // build records | |
| 65 | + $records = $dbo->loadAssocList(); | |
| 66 | + foreach ($records as $record) { | |
| 67 | + if (empty($record['ID'])) { | |
| 68 | + continue; | |
| 69 | + } | |
| 70 | + | |
| 71 | + // raw booking structure | |
| 72 | + if (!isset($tpbookings[$record['ID']])) { | |
| 73 | + $tpbookings[$record['ID']] = array( | |
| 74 | + 'id' => $record['ID'], | |
| 75 | + 'dt' => $record['post_date'], | |
| 76 | + 'last_import' => null, | |
| 77 | + 'status' => $record['post_status'], | |
| 78 | + 'metas' => array(), | |
| 79 | + 'rooms_metas' => array(), | |
| 80 | + 'room_ids' => array(), | |
| 81 | + 'room_parties' => array(), | |
| 82 | + 'infos' => array(), | |
| 83 | + ); | |
| 84 | + } | |
| 85 | + | |
| 86 | + // push meta assoc | |
| 87 | + $tpbookings[$record['ID']]['metas'][$record['meta_key']] = $record['meta_value']; | |
| 88 | + | |
| 89 | + // gather booking information | |
| 90 | + if (stripos($record['meta_key'], 'first_name') !== false) { | |
| 91 | + $tpbookings[$record['ID']]['infos']['first_name'] = $record['meta_value']; | |
| 92 | + } | |
| 93 | + if (stripos($record['meta_key'], 'last_name') !== false) { | |
| 94 | + $tpbookings[$record['ID']]['infos']['last_name'] = $record['meta_value']; | |
| 95 | + } | |
| 96 | + if (stripos($record['meta_key'], 'email') !== false) { | |
| 97 | + $tpbookings[$record['ID']]['infos']['email'] = $record['meta_value']; | |
| 98 | + } | |
| 99 | + if (stripos($record['meta_key'], 'check_in') !== false) { | |
| 100 | + $tpbookings[$record['ID']]['infos']['checkin'] = $record['meta_value']; | |
| 101 | + } | |
| 102 | + if (stripos($record['meta_key'], 'check_out') !== false) { | |
| 103 | + $tpbookings[$record['ID']]['infos']['checkout'] = $record['meta_value']; | |
| 104 | + } | |
| 105 | + if (stripos($record['meta_key'], 'phone') !== false && !empty($record['meta_value'])) { | |
| 106 | + $tpbookings[$record['ID']]['infos']['phone'] = $record['meta_value']; | |
| 107 | + } | |
| 108 | + if (stripos($record['meta_key'], 'city') !== false && !empty($record['meta_value'])) { | |
| 109 | + $tpbookings[$record['ID']]['infos']['city'] = $record['meta_value']; | |
| 110 | + } | |
| 111 | + if (stripos($record['meta_key'], 'address') !== false && !empty($record['meta_value'])) { | |
| 112 | + $tpbookings[$record['ID']]['infos']['address'] = $record['meta_value']; | |
| 113 | + } | |
| 114 | + if (stripos($record['meta_key'], 'zip') !== false && !empty($record['meta_value'])) { | |
| 115 | + $tpbookings[$record['ID']]['infos']['zip'] = $record['meta_value']; | |
| 116 | + } | |
| 117 | + if (stripos($record['meta_key'], 'country') !== false && !empty($record['meta_value'])) { | |
| 118 | + $tpbookings[$record['ID']]['infos']['country'] = $record['meta_value']; | |
| 119 | + } | |
| 120 | + if (stripos($record['meta_key'], 'total_price') !== false && !empty($record['meta_value'])) { | |
| 121 | + $tpbookings[$record['ID']]['infos']['total'] = $record['meta_value']; | |
| 122 | + } | |
| 123 | + if (stripos($record['meta_key'], 'language') !== false && !empty($record['meta_value'])) { | |
| 124 | + $tpbookings[$record['ID']]['infos']['language'] = $record['meta_value']; | |
| 125 | + } | |
| 126 | + | |
| 127 | + // check whether this booking was already imported | |
| 128 | + if (count($bimported)) { | |
| 129 | + foreach ($bimported as $old_import) { | |
| 130 | + if (!isset($old_import['bids']) || !isset($old_import['dt']) || !is_array($old_import['bids'])) { | |
| 131 | + continue; | |
| 132 | + } | |
| 133 | + if (in_array($record['ID'], $old_import['bids'])) { | |
| 134 | + // last import date found | |
| 135 | + $tpbookings[$record['ID']]['last_import'] = $old_import['dt']; | |
| 136 | + break; | |
| 137 | + } | |
| 138 | + } | |
| 139 | + } | |
| 140 | + } | |
| 141 | + | |
| 142 | + // grab room info details | |
| 143 | + $q = "SELECT `p`.`ID`,`p`.`post_parent`,`pm`.`meta_key`,`pm`.`meta_value` FROM `#__posts` AS `p` LEFT JOIN `#__postmeta` `pm` ON `p`.`ID`=`pm`.`post_id` WHERE `p`.`post_parent` IN (" . implode(', ', array_keys($tpbookings)) . ") AND `p`.`post_type`=" . $dbo->quote('mphb_reserved_room') . " ORDER BY `p`.`post_parent` ASC;"; | |
| 144 | + $dbo->setQuery($q); | |
| 145 | + $dbo->execute(); | |
| 146 | + if ($dbo->getNumRows()) { | |
| 147 | + $rooms_data = $dbo->loadAssocList(); | |
| 148 | + $rooms_meta_assoc = array(); | |
| 149 | + foreach ($rooms_data as $room_data) { | |
| 150 | + if (!isset($tpbookings[$room_data['post_parent']])) { | |
| 151 | + continue; | |
| 152 | + } | |
| 153 | + // push rooms meta assoc | |
| 154 | + $tpbookings[$room_data['post_parent']]['rooms_metas'][$room_data['meta_key']] = $room_data['meta_value']; | |
| 155 | + if (stripos($room_data['meta_key'], 'mphb_room_id') !== false) { | |
| 156 | + // push room identifier | |
| 157 | + array_push($tpbookings[$room_data['post_parent']]['room_ids'], $room_data['meta_value']); | |
| 158 | + // save post ID for this room booked | |
| 159 | + $rooms_meta_assoc[$room_data['ID']] = $room_data['meta_value']; | |
| 160 | + } | |
| 161 | + } | |
| 162 | + foreach ($rooms_meta_assoc as $rmetapid => $rmetarid) { | |
| 163 | + foreach ($rooms_data as $room_data) { | |
| 164 | + if (!isset($tpbookings[$room_data['post_parent']])) { | |
| 165 | + continue; | |
| 166 | + } | |
| 167 | + if ($rmetapid == $room_data['ID'] && stripos($room_data['meta_key'], 'adults') !== false) { | |
| 168 | + if (!isset($tpbookings[$room_data['post_parent']]['room_parties'][$rmetarid])) { | |
| 169 | + $tpbookings[$room_data['post_parent']]['room_parties'][$rmetarid] = array( | |
| 170 | + 'adults' => 1, | |
| 171 | + 'children' => 0, | |
| 172 | + ); | |
| 173 | + } | |
| 174 | + // update room party adults | |
| 175 | + $tpbookings[$room_data['post_parent']]['room_parties'][$rmetarid]['adults'] = (int)$room_data['meta_value']; | |
| 176 | + } | |
| 177 | + if ($rmetapid == $room_data['ID'] && stripos($room_data['meta_key'], 'children') !== false) { | |
| 178 | + if (!isset($tpbookings[$room_data['post_parent']]['room_parties'][$rmetarid])) { | |
| 179 | + $tpbookings[$room_data['post_parent']]['room_parties'][$rmetarid] = array( | |
| 180 | + 'adults' => 1, | |
| 181 | + 'children' => 0, | |
| 182 | + ); | |
| 183 | + } | |
| 184 | + // update room party children | |
| 185 | + $tpbookings[$room_data['post_parent']]['room_parties'][$rmetarid]['children'] = (int)$room_data['meta_value']; | |
| 186 | + } | |
| 187 | + } | |
| 188 | + } | |
| 189 | + } | |
| 190 | + | |
| 191 | + // build the third party rooms relations | |
| 192 | + $q = "SELECT `ID`,`post_title` FROM `#__posts` WHERE `post_type`=" . $dbo->quote('mphb_room') . ";"; | |
| 193 | + $dbo->setQuery($q); | |
| 194 | + $dbo->execute(); | |
| 195 | + if ($dbo->getNumRows()) { | |
| 196 | + $records = $dbo->loadAssocList(); | |
| 197 | + foreach ($records as $record) { | |
| 198 | + $tprooms[$record['ID']] = $record['post_title']; | |
| 199 | + } | |
| 200 | + } | |
| 201 | + | |
| 202 | + // unset all bookings with no rooms found, with non existing rooms or without required information | |
| 203 | + foreach ($tpbookings as $bid => $booking) { | |
| 204 | + if (!count($booking['room_ids'])) { | |
| 205 | + unset($tpbookings[$bid]); | |
| 206 | + continue; | |
| 207 | + } | |
| 208 | + foreach ($booking['room_ids'] as $tprid) { | |
| 209 | + if (!isset($tprooms[$tprid])) { | |
| 210 | + unset($tpbookings[$bid]); | |
| 211 | + break 2; | |
| 212 | + } | |
| 213 | + } | |
| 214 | + // make sure the check-in and check-out dates are defined | |
| 215 | + if (empty($booking['infos']['checkin']) || empty($booking['infos']['checkout'])) { | |
| 216 | + unset($tpbookings[$bid]); | |
| 217 | + continue; | |
| 218 | + } | |
| 219 | + } | |
| 220 | + break; | |
| 221 | + default: | |
| 222 | + // plugin unsupported | |
| 223 | + break; | |
| 224 | + } | |
| 225 | + | |
| 226 | + // check whether some bookings have been requested for import | |
| 227 | + $do_import = VikRequest::getInt('do_import', 0, 'request'); | |
| 228 | + $tpp_rooms_map = VikRequest::getVar('tpp_rooms', array(), 'request', 'array'); | |
| 229 | + $vbo_rooms_map = VikRequest::getVar('vbo_rooms', array(), 'request', 'array'); | |
| 230 | + $tpp_bids = VikRequest::getVar('tpp_bids', array(), 'request', 'array'); | |
| 231 | + if ($do_import && is_array($tpp_rooms_map) && is_array($vbo_rooms_map) && is_array($tpp_bids) && count($vbo_rooms_map) && count($tpp_bids)) { | |
| 232 | + // let this method proceed with the import | |
| 233 | + $this->importThirdPartyReservations($tpp, $tpbookings, $tpp_rooms_map, $vbo_rooms_map, $tpp_bids); | |
| 234 | + } | |
| 235 | + } | |
| 236 | + | |
| 237 | + $this->setup_completed = $setup_completed; | |
| 238 | + $this->vbo_rooms = $vbo_rooms; | |
| 239 | + $this->plugins = $plugins; | |
| 240 | + $this->tpbookings = $tpbookings; | |
| 241 | + $this->tprooms = $tprooms; | |
| 242 | + $this->tpp = $tpp; | |
| 243 | + | |
| 244 | + // Display the template | |
| 245 | + parent::display($tpl); | |
| 246 | + } | |
| 247 | + | |
| 248 | + /** | |
| 249 | + * Do the import of the requested bookings like if this was a task of a controller. | |
| 250 | + * | |
| 251 | + * @param string $tpp the name of the third party plugin. | |
| 252 | + * @param array $tpbookings all third party bookings read. | |
| 253 | + * @param array $tpp_rooms_map third party room IDs involved. | |
| 254 | + * @param array $vbo_rooms_map corresponding VBO room IDs selected. | |
| 255 | + * @param array $tpp_bids selected reservation IDs (as keys). | |
| 256 | + * | |
| 257 | + * @return mixed void on success by redirecting the page, false on failure by setting a system error message. | |
| 258 | + * | |
| 259 | + * @since 1.3.5 | |
| 260 | + */ | |
| 261 | + private function importThirdPartyReservations($tpp, $tpbookings, $tpp_rooms_map, $vbo_rooms_map, $tpp_bids) | |
| 262 | + { | |
| 263 | + // set the execution time to 5 minutes | |
| 264 | + @ini_set('max_execution_time', 300); | |
| 265 | + | |
| 266 | + | |
| 267 | + $dbo = JFactory::getDbo(); | |
| 268 | + $app = JFactory::getApplication(); | |
| 269 | + | |
| 270 | + // date format | |
| 271 | + $vbo_df = VikBooking::getDateFormat(true); | |
| 272 | + if ($vbo_df == "%d/%m/%Y") { | |
| 273 | + $vbo_df = 'd/m/Y'; | |
| 274 | + } elseif ($vbo_df == "%m/%d/%Y") { | |
| 275 | + $vbo_df = 'm/d/Y'; | |
| 276 | + } else { | |
| 277 | + $vbo_df = 'Y/m/d'; | |
| 278 | + } | |
| 279 | + | |
| 280 | + // check-in/check-out times | |
| 281 | + $pcheckinh = 0; | |
| 282 | + $pcheckinm = 0; | |
| 283 | + $pcheckouth = 0; | |
| 284 | + $pcheckoutm = 0; | |
| 285 | + $timeopst = VikBooking::getTimeOpenStore(); | |
| 286 | + if (is_array($timeopst)) { | |
| 287 | + $opent = VikBooking::getHoursMinutes($timeopst[0]); | |
| 288 | + $closet = VikBooking::getHoursMinutes($timeopst[1]); | |
| 289 | + $pcheckinh = $opent[0]; | |
| 290 | + $pcheckinm = $opent[1]; | |
| 291 | + $pcheckouth = $closet[0]; | |
| 292 | + $pcheckoutm = $closet[1]; | |
| 293 | + } | |
| 294 | + | |
| 295 | + // Assign room specific unit | |
| 296 | + $set_room_indexes = VikBooking::autoRoomUnit(); | |
| 297 | + | |
| 298 | + // vars validation | |
| 299 | + if (empty($tpp)) { | |
| 300 | + VikError::raiseWarning('', 'Missing third party plugin name'); | |
| 301 | + return false; | |
| 302 | + } | |
| 303 | + if (!is_array($tpbookings) || !count($tpbookings)) { | |
| 304 | + VikError::raiseWarning('', 'No reservations found from third party plugin'); | |
| 305 | + return false; | |
| 306 | + } | |
| 307 | + | |
| 308 | + // build the rooms mapping data | |
| 309 | + $rooms_mapping = array(); | |
| 310 | + foreach ($tpp_rooms_map as $k => $v) { | |
| 311 | + if (empty($vbo_rooms_map[$k])) { | |
| 312 | + continue; | |
| 313 | + } | |
| 314 | + $rooms_mapping[$v] = $vbo_rooms_map[$k]; | |
| 315 | + } | |
| 316 | + if (!count($rooms_mapping)) { | |
| 317 | + VikError::raiseWarning('', 'No corresponding rooms of Vik Booking selected'); | |
| 318 | + return false; | |
| 319 | + } | |
| 320 | + | |
| 321 | + // loop over the requested bookings for import | |
| 322 | + $tot_bookings_imported = 0; | |
| 323 | + $bookings_imported_ids = array(); | |
| 324 | + foreach ($tpp_bids as $tpbid => $val) { | |
| 325 | + if (!isset($tpbookings[$tpbid])) { | |
| 326 | + // booking not read | |
| 327 | + continue; | |
| 328 | + } | |
| 329 | + | |
| 330 | + // build customer raw data | |
| 331 | + $custdata = ''; | |
| 332 | + $first_name = null; | |
| 333 | + $last_name = null; | |
| 334 | + $email = null; | |
| 335 | + $phone = null; | |
| 336 | + $country = null; | |
| 337 | + $customer_extrainfo = array(); | |
| 338 | + if (!empty($tpbookings[$tpbid]['infos']['first_name'])) { | |
| 339 | + $custdata .= JText::translate('VBCUSTOMERFIRSTNAME') . ': ' . $tpbookings[$tpbid]['infos']['first_name'] . "\n"; | |
| 340 | + $first_name = $tpbookings[$tpbid]['infos']['first_name']; | |
| 341 | + } | |
| 342 | + if (!empty($tpbookings[$tpbid]['infos']['last_name'])) { | |
| 343 | + $custdata .= JText::translate('VBCUSTOMERLASTNAME') . ': ' . $tpbookings[$tpbid]['infos']['last_name'] . "\n"; | |
| 344 | + $last_name = $tpbookings[$tpbid]['infos']['last_name']; | |
| 345 | + } | |
| 346 | + if (!empty($tpbookings[$tpbid]['infos']['email'])) { | |
| 347 | + $custdata .= JText::translate('VBCUSTOMEREMAIL') . ': ' . $tpbookings[$tpbid]['infos']['email'] . "\n"; | |
| 348 | + $email = $tpbookings[$tpbid]['infos']['email']; | |
| 349 | + } | |
| 350 | + if (!empty($tpbookings[$tpbid]['infos']['phone'])) { | |
| 351 | + $custdata .= JText::translate('VBCUSTOMERPHONE') . ': ' . $tpbookings[$tpbid]['infos']['phone'] . "\n"; | |
| 352 | + $phone = $tpbookings[$tpbid]['infos']['phone']; | |
| 353 | + } | |
| 354 | + if (!empty($tpbookings[$tpbid]['infos']['address'])) { | |
| 355 | + $custdata .= JText::translate('ORDER_ADDRESS') . ': ' . $tpbookings[$tpbid]['infos']['address'] . "\n"; | |
| 356 | + $customer_extrainfo['address'] = $tpbookings[$tpbid]['infos']['address']; | |
| 357 | + } | |
| 358 | + if (!empty($tpbookings[$tpbid]['infos']['zip'])) { | |
| 359 | + $custdata .= JText::translate('ORDER_ZIP') . ': ' . $tpbookings[$tpbid]['infos']['zip'] . "\n"; | |
| 360 | + $customer_extrainfo['zip'] = $tpbookings[$tpbid]['infos']['zip']; | |
| 361 | + } | |
| 362 | + if (!empty($tpbookings[$tpbid]['infos']['city'])) { | |
| 363 | + $custdata .= JText::translate('ORDER_CITY') . ': ' . $tpbookings[$tpbid]['infos']['city'] . "\n"; | |
| 364 | + $customer_extrainfo['city'] = $tpbookings[$tpbid]['infos']['city']; | |
| 365 | + } | |
| 366 | + if (!empty($tpbookings[$tpbid]['infos']['country'])) { | |
| 367 | + $custdata .= JText::translate('VBCUSTOMERCOUNTRY') . ': ' . $tpbookings[$tpbid]['infos']['country'] . "\n"; | |
| 368 | + $country = $tpbookings[$tpbid]['infos']['country']; | |
| 369 | + } | |
| 370 | + $custdata = rtrim($custdata, "\n"); | |
| 371 | + | |
| 372 | + // build stay dates and tot nights | |
| 373 | + $checkin_ts = VikBooking::getDateTimestamp(date($vbo_df, strtotime($tpbookings[$tpbid]['infos']['checkin'])), $pcheckinh, $pcheckinm); | |
| 374 | + $checkout_ts = VikBooking::getDateTimestamp(date($vbo_df, strtotime($tpbookings[$tpbid]['infos']['checkout'])), $pcheckouth, $pcheckoutm); | |
| 375 | + if (!$checkin_ts || !$checkout_ts) { | |
| 376 | + VikError::raiseWarning('', 'Invalid dates for third party reservation #' . $tpbid); | |
| 377 | + continue; | |
| 378 | + } | |
| 379 | + $tot_nights = $this->countReservationNights($tpbookings[$tpbid]['infos']['checkin'], $tpbookings[$tpbid]['infos']['checkout']); | |
| 380 | + | |
| 381 | + // prepare customer record | |
| 382 | + $cpin = VikBooking::getCPinIstance(); | |
| 383 | + $cpin->is_admin = true; | |
| 384 | + if (count($customer_extrainfo)) { | |
| 385 | + $cpin->setCustomerExtraInfo($customer_extrainfo); | |
| 386 | + } | |
| 387 | + // adjust the country code | |
| 388 | + $country = $cpin->get3CharCountry($country); | |
| 389 | + // save customer details | |
| 390 | + $cpin->saveCustomerDetails($first_name, $last_name, $email, $phone, $country, array()); | |
| 391 | + | |
| 392 | + // check booking status | |
| 393 | + $new_status = 'confirmed'; | |
| 394 | + if (stripos($tpbookings[$tpbid]['status'], 'cancel') !== false || stripos($tpbookings[$tpbid]['status'], 'abandon') !== false) { | |
| 395 | + $new_status = 'cancelled'; | |
| 396 | + } elseif (stripos($tpbookings[$tpbid]['status'], 'pending') !== false) { | |
| 397 | + $new_status = 'standby'; | |
| 398 | + } | |
| 399 | + | |
| 400 | + // store busy record(s) by making sure we know the VBO room ID | |
| 401 | + $booking_busy_ids = array(); | |
| 402 | + if ($new_status == 'confirmed') { | |
| 403 | + foreach ($tpbookings[$tpbid]['room_ids'] as $orid => $tprid) { | |
| 404 | + if (!isset($rooms_mapping[$tprid])) { | |
| 405 | + // corresponding room ID not found, unset the key | |
| 406 | + unset($tpbookings[$tpbid]['room_ids'][$orid]); | |
| 407 | + continue; | |
| 408 | + } | |
| 409 | + $q = "INSERT INTO `#__vikbooking_busy` (`idroom`,`checkin`,`checkout`,`realback`) VALUES(" . (int)$rooms_mapping[$tprid] . ", {$checkin_ts}, {$checkout_ts}, {$checkout_ts});"; | |
| 410 | + $dbo->setQuery($q); | |
| 411 | + $dbo->execute(); | |
| 412 | + $lid = $dbo->insertid(); | |
| 413 | + if (!empty($lid)) { | |
| 414 | + array_push($booking_busy_ids, $lid); | |
| 415 | + } else { | |
| 416 | + unset($tpbookings[$tpbid]['room_ids'][$orid]); | |
| 417 | + } | |
| 418 | + } | |
| 419 | + } | |
| 420 | + | |
| 421 | + // make sure some rooms were booked | |
| 422 | + if ($new_status == 'confirmed' && !count($booking_busy_ids)) { | |
| 423 | + VikError::raiseWarning('', 'Could not occupy rooms for third party reservation #' . $tpbid); | |
| 424 | + continue; | |
| 425 | + } | |
| 426 | + | |
| 427 | + // store reservation | |
| 428 | + $res_obj = new stdClass; | |
| 429 | + $res_obj->custdata = $custdata; | |
| 430 | + $res_obj->ts = strtotime($tpbookings[$tpbid]['dt']); | |
| 431 | + $res_obj->status = $new_status; | |
| 432 | + $res_obj->days = $tot_nights; | |
| 433 | + $res_obj->checkin = $checkin_ts; | |
| 434 | + $res_obj->checkout = $checkout_ts; | |
| 435 | + $res_obj->custmail = $email; | |
| 436 | + $res_obj->sid = VikBooking::getSecretLink(); | |
| 437 | + $res_obj->roomsnum = count($tpbookings[$tpbid]['room_ids']); | |
| 438 | + $res_obj->total = !empty($tpbookings[$tpbid]['infos']['total']) ? (float)$tpbookings[$tpbid]['infos']['total'] : 0; | |
| 439 | + $res_obj->country = $country; | |
| 440 | + $res_obj->phone = $phone; | |
| 441 | + $res_obj->closure = 0; | |
| 442 | + | |
| 443 | + $dbo->insertObject('#__vikbooking_orders', $res_obj, 'id'); | |
| 444 | + if (!isset($res_obj->id) || empty($res_obj->id)) { | |
| 445 | + VikError::raiseWarning('', 'Could not import third party reservation #' . $tpbid); | |
| 446 | + continue; | |
| 447 | + } | |
| 448 | + $newoid = $res_obj->id; | |
| 449 | + | |
| 450 | + // check if some of the rooms booked have shared calendars | |
| 451 | + if ($new_status == 'confirmed') { | |
| 452 | + foreach ($tpbookings[$tpbid]['room_ids'] as $orid => $tprid) { | |
| 453 | + // we do this before storing the relation records | |
| 454 | + VikBooking::updateSharedCalendars($newoid, array($rooms_mapping[$tprid]), $checkin_ts, $checkout_ts); | |
| 455 | + } | |
| 456 | + | |
| 457 | + // Confirmation Number | |
| 458 | + $confirmnumber = VikBooking::generateConfirmNumber($newoid, true); | |
| 459 | + | |
| 460 | + // store relations between busy records and new booking | |
| 461 | + foreach ($booking_busy_ids as $lid) { | |
| 462 | + $q = "INSERT INTO `#__vikbooking_ordersbusy` (`idorder`, `idbusy`) VALUES(" . (int)$newoid . ", " . (int)$lid . ");"; | |
| 463 | + $dbo->setQuery($q); | |
| 464 | + $dbo->execute(); | |
| 465 | + } | |
| 466 | + } | |
| 467 | + | |
| 468 | + // write room records | |
| 469 | + foreach ($tpbookings[$tpbid]['room_ids'] as $orid => $tprid) { | |
| 470 | + // Assign room specific unit | |
| 471 | + $room_indexes_usemap = array(); | |
| 472 | + $room_indexes = $set_room_indexes === true ? VikBooking::getRoomUnitNumsAvailable(array('id' => $newoid, 'checkin' => $checkin_ts, 'checkout' => $checkout_ts), $rooms_mapping[$tprid]) : array(); | |
| 473 | + $use_ind_key = 0; | |
| 474 | + if (count($room_indexes)) { | |
| 475 | + if (!array_key_exists($rooms_mapping[$tprid], $room_indexes_usemap)) { | |
| 476 | + $room_indexes_usemap[$rooms_mapping[$tprid]] = $use_ind_key; | |
| 477 | + } else { | |
| 478 | + $use_ind_key = $room_indexes_usemap[$rooms_mapping[$tprid]]; | |
| 479 | + } | |
| 480 | + } | |
| 481 | + | |
| 482 | + // room cost and room party | |
| 483 | + $r_cust_cost = !empty($tpbookings[$tpbid]['infos']['total']) ? ($tpbookings[$tpbid]['infos']['total'] / count($tpbookings[$tpbid]['room_ids'])) : 0; | |
| 484 | + $room_adults = isset($tpbookings[$tpbid]['room_parties'][$tprid]) && isset($tpbookings[$tpbid]['room_parties'][$tprid]['adults']) ? (int)$tpbookings[$tpbid]['room_parties'][$tprid]['adults'] : 1; | |
| 485 | + $room_children = isset($tpbookings[$tpbid]['room_parties'][$tprid]) && isset($tpbookings[$tpbid]['room_parties'][$tprid]['children']) ? (int)$tpbookings[$tpbid]['room_parties'][$tprid]['children'] : 0; | |
| 486 | + | |
| 487 | + $order_room_obj = new stdClass; | |
| 488 | + $order_room_obj->idorder = $newoid; | |
| 489 | + $order_room_obj->idroom = $rooms_mapping[$tprid]; | |
| 490 | + $order_room_obj->adults = $room_adults; | |
| 491 | + $order_room_obj->children = $room_children; | |
| 492 | + $order_room_obj->idtar = null; | |
| 493 | + $order_room_obj->roomindex = count($room_indexes) ? (int)$room_indexes[$use_ind_key] : null; | |
| 494 | + $order_room_obj->cust_cost = $r_cust_cost; | |
| 495 | + | |
| 496 | + $dbo->insertObject('#__vikbooking_ordersrooms', $order_room_obj, 'id'); | |
| 497 | + | |
| 498 | + // Assign room specific unit | |
| 499 | + if (count($room_indexes)) { | |
| 500 | + $room_indexes_usemap[$rooms_mapping[$tprid]]++; | |
| 501 | + } | |
| 502 | + } | |
| 503 | + | |
| 504 | + // Assign Customer Booking | |
| 505 | + $cpin->saveCustomerBooking($newoid); | |
| 506 | + | |
| 507 | + // Booking History | |
| 508 | + VikBooking::getBookingHistoryInstance()->setBid($newoid)->store('NB', JText::translate('VBO_IMPBFTPP_BOOKHIST_DESCR') . " ({$tpbid})"); | |
| 509 | + | |
| 510 | + // increase bookings counter | |
| 511 | + $tot_bookings_imported++; | |
| 512 | + | |
| 513 | + // store third party booking ID | |
| 514 | + array_push($bookings_imported_ids, $tpbid); | |
| 515 | + } | |
| 516 | + | |
| 517 | + if (!$tot_bookings_imported) { | |
| 518 | + VikError::raiseWarning('', JText::sprintf('VBO_IMPBFTPP_IMPORT_TOTRES', $tot_bookings_imported)); | |
| 519 | + return false; | |
| 520 | + } | |
| 521 | + | |
| 522 | + // update option containing the imported bookings for this third party plugin | |
| 523 | + $bimported = get_option("vikbooking_importbftpp_{$tpp}", null); | |
| 524 | + $bimported = !empty($bimported) ? json_decode($bimported, true) : array(); | |
| 525 | + $bimported = !is_array($bimported) ? array() : $bimported; | |
| 526 | + // push new import data | |
| 527 | + array_push($bimported, array( | |
| 528 | + 'dt' => date('Y-m-d H:i:s'), | |
| 529 | + 'bids' => $bookings_imported_ids, | |
| 530 | + )); | |
| 531 | + update_option("vikbooking_importbftpp_{$tpp}", json_encode($bimported)); | |
| 532 | + | |
| 533 | + // redirect to Vik Booking - All Bookings page by setting a success message | |
| 534 | + $app->enqueueMessage(JText::sprintf('VBO_IMPBFTPP_IMPORT_TOTRES', $tot_bookings_imported)); | |
| 535 | + $app->redirect('index.php?option=com_vikbooking&task=orders'); | |
| 536 | + | |
| 537 | + // do not let the View be rendered | |
| 538 | + exit; | |
| 539 | + } | |
| 540 | + | |
| 541 | + /** | |
| 542 | + * Counts the total number of nights of stay from the given stay dates. | |
| 543 | + * | |
| 544 | + * @param string $checkin parsable checkin date into a timestamp. | |
| 545 | + * @param string $checkout parsable checkout date into a timestamp. | |
| 546 | + * | |
| 547 | + * @return int the total number of nights of stay. | |
| 548 | + */ | |
| 549 | + private function countReservationNights($checkin, $checkout) | |
| 550 | + { | |
| 551 | + $nights = 1; | |
| 552 | + $in_ts = strtotime($checkin); | |
| 553 | + $out_ts = strtotime($checkout); | |
| 554 | + | |
| 555 | + if (!$in_ts || !$out_ts || $in_ts >= $out_ts) { | |
| 556 | + return $nights; | |
| 557 | + } | |
| 558 | + | |
| 559 | + $in_info = getdate($in_ts); | |
| 560 | + $nights = 0; | |
| 561 | + while (date('Y-m-d', $in_info[0]) != date('Y-m-d', $out_ts)) { | |
| 562 | + $nights++; | |
| 563 | + $in_info = getdate(mktime(0, 0, 0, $in_info['mon'], ($in_info['mday'] + 1), $in_info['year'])); | |
| 564 | + } | |
| 565 | + | |
| 566 | + return $nights < 1 ? 1 : $nights; | |
| 567 | + } | |
| 568 | + | |
| 569 | + /** | |
| 570 | + * Sets the toolbar | |
| 571 | + */ | |
| 572 | + protected function addToolBar() | |
| 573 | + { | |
| 574 | + JToolBarHelper::title(JText::translate('VBOMAINIMPORTBFTPPTITLE'), 'vikbooking'); | |
| 575 | + JToolBarHelper::cancel( 'canceldash', JText::translate('VBBACK')); | |
| 576 | + JToolBarHelper::spacer(); | |
| 577 | + } | |
| 578 | + | |
| 579 | +} | |