PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.7.2
VikBooking Hotel Booking Engine & PMS v1.7.2
1.8.16 1.8.15 1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 All 37 releases
vikbooking / site / views / booking / view.html.php

view.html.php in VikBooking Hotel Booking Engine & PMS 1.7.2, at site/views/booking/view.html.php

400 lines 14.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 jimport('joomla.application.component.view');
14
15 class VikbookingViewBooking extends JViewVikBooking
16 {
17 public function display($tpl = null)
18 {
19 $dbo = JFactory::getDbo();
20 $app = JFactory::getApplication();
21 $document = JFactory::getDocument();
22 $vbo_tn = VikBooking::getTranslator();
23
24 // validation of data and availability before the rendering
25 $sid = VikRequest::getString('sid', '', 'request');
26 $ts = VikRequest::getString('ts', '', 'request');
27 if (empty($sid) || empty($ts)) {
28 showSelectVb(JText::translate('VBINSUFDATA'));
29 return;
30 }
31
32 $q = "SELECT `o`.*,(SELECT SUM(`or`.`adults`) FROM `#__vikbooking_ordersrooms` AS `or` WHERE `or`.`idorder`=`o`.`id`) AS `tot_adults` FROM `#__vikbooking_orders` AS `o` WHERE (`o`.`sid`=" . $dbo->quote($sid) . " OR `o`.`idorderota`=" . $dbo->quote($sid) . ") AND `o`.`ts`=" . $dbo->quote($ts);
33 $dbo->setQuery($q, 0, 1);
34 $order = $dbo->loadAssoc();
35 if (!$order) {
36 showSelectVb(JText::translate('VBORDERNOTFOUND'));
37 return;
38 }
39
40 // availability helper
41 $av_helper = VikBooking::getAvailabilityInstance();
42
43 // room stay dates in case of split stay
44 $room_stay_dates = [];
45 if ($order['split_stay']) {
46 if ($order['status'] == 'confirmed') {
47 $room_stay_dates = $av_helper->loadSplitStayBusyRecords($order['id']);
48 } else {
49 $room_stay_dates = VBOFactory::getConfig()->getArray('split_stay_' . $order['id'], []);
50 }
51 }
52
53 if ($order['status'] == 'confirmed') {
54 // prepare impression data for channels
55 $impressiondata = $order;
56 $q = "SELECT `or`.`idtar`,`d`.`idprice`,`p`.`idiva`,`t`.`aliq`,`t`.`taxcap` FROM `#__vikbooking_ordersrooms` AS `or` " .
57 "LEFT JOIN `#__vikbooking_dispcost` `d` ON `d`.`id`=`or`.`idtar` " .
58 "LEFT JOIN `#__vikbooking_prices` `p` ON `p`.`id`=`d`.`idprice` " .
59 "LEFT JOIN `#__vikbooking_iva` `t` ON `t`.`id`=`p`.`idiva` " .
60 "WHERE `or`.`idorder`='".$order['id']."' ORDER BY `t`.`aliq` ASC";
61 $dbo->setQuery($q, 0, 1);
62 $taxdata = $dbo->loadAssoc();
63 if ($taxdata) {
64 $taxes = 0;
65 if (!empty($taxdata['aliq'])) {
66 $realtotal = round(($order['total'] / ((100 + $taxdata['aliq']) / 100)), 2);
67 $taxes = round(($order['total'] - $realtotal), 2);
68 /**
69 * Tax Cap implementation.
70 *
71 * @since 1.12
72 */
73 if ($taxdata['taxcap'] > 0 && $taxes > $taxdata['taxcap']) {
74 $realtotal = $order['total'] - $taxdata['taxcap'];
75 $taxes = $taxdata['taxcap'];
76 }
77 $impressiondata['total'] = $realtotal;
78 }
79 $impressiondata['taxes'] = $taxes;
80 $impressiondata['fees'] = 0;
81 }
82 VikBooking::invokeChannelManager(true, $impressiondata);
83 // end prepare impression data for channels
84 } elseif ($order['status'] == 'standby') {
85 $roomavail = false;
86
87 $q = $dbo->getQuery(true)
88 ->select($dbo->qn('or') . '.*')
89 ->select($dbo->qn('r.units'))
90 ->from($dbo->qn('#__vikbooking_ordersrooms', 'or'))
91 ->leftJoin($dbo->qn('#__vikbooking_rooms', 'r') . ' ON ' . $dbo->qn('or.idroom') . ' = ' . $dbo->qn('r.id'))
92 ->where($dbo->qn('or.idorder') . ' = ' . (int)$order['id'])
93 ->order($dbo->qn('or.id') . ' ASC');
94
95 $dbo->setQuery($q);
96 $orderrooms = $dbo->loadAssocList();
97
98 /**
99 * Even if redundant, we read the eventually occupied records by this booking ID to ensure
100 * server-side cache will not produce a booking cancellation after receiving a valid payment.
101 * An eventual list of busy record IDs is passed to the method for checking if the room is
102 * available, because the status of the reservation may actually be confirmed already.
103 *
104 * @since 1.16.9 (J) - 1.6.9 (WP)
105 */
106 $dbo->setQuery(
107 $dbo->getQuery(true)
108 ->select($dbo->qn('idbusy'))
109 ->from($dbo->qn('#__vikbooking_ordersbusy'))
110 ->where($dbo->qn('idorder') . ' = ' . (int)$order['id'])
111 );
112 $skip_busy_ids = array_column($dbo->loadAssocList(), 'idbusy');
113
114 foreach ($orderrooms as $kor => $or) {
115 // determine proper values for this room
116 $room_stay_checkin = $order['checkin'];
117 $room_stay_checkout = $order['checkout'];
118 if ($order['split_stay'] && $room_stay_dates && isset($room_stay_dates[$kor]) && $room_stay_dates[$kor]['idroom'] == $or['idroom']) {
119 $room_stay_checkin = !empty($room_stay_dates[$kor]['checkin_ts']) ? $room_stay_dates[$kor]['checkin_ts'] : $room_stay_dates[$kor]['checkin'];
120 $room_stay_checkout = !empty($room_stay_dates[$kor]['checkout_ts']) ? $room_stay_dates[$kor]['checkout_ts'] : $room_stay_dates[$kor]['checkout'];
121 }
122
123 // make sure room is still available
124 $roomavail = VikBooking::roomBookable($or['idroom'], $or['units'], $room_stay_checkin, $room_stay_checkout, $skip_busy_ids);
125 if (!$roomavail) {
126 break;
127 }
128 }
129
130 $today_midnight = mktime(0, 0, 0, date('n'), date('j'), date('Y'));
131 $autoremove = false;
132 if ($today_midnight > $order['checkin']) {
133 $roomavail = false;
134 }
135 $minautoremove = VikBooking::getMinutesAutoRemove();
136 $mins_elapsed = floor((time() - $order['ts']) / 60);
137 if ($minautoremove > 0 && $mins_elapsed > $minautoremove) {
138 $roomavail = false;
139 $autoremove = true;
140 }
141
142 /**
143 * Make sure not to cancel an OTA pending reservation.
144 *
145 * @since 1.15.4 (J) - 1.5.10 (WP)
146 */
147 $is_ota_pending = (!empty($order['type']) && !empty($order['channel']));
148
149 if ($roomavail || $is_ota_pending) {
150 // invoke channel impression
151 VikBooking::invokeChannelManager(false);
152 //
153 } else {
154 // set the booking to cancelled
155 $q = "UPDATE `#__vikbooking_orders` SET `status`='cancelled' WHERE `id`=".(int)$order['id'].";";
156 $dbo->setQuery($q);
157 $dbo->execute();
158 // update status in the array
159 $order['status'] = 'cancelled';
160 //
161 $q = "DELETE FROM `#__vikbooking_tmplock` WHERE `idorder`=" . (int)$order['id'] . ";";
162 $dbo->setQuery($q);
163 $dbo->execute();
164 $q = "SELECT * FROM `#__vikbooking_ordersbusy` WHERE `idorder`=".(int)$order['id'].";";
165 $dbo->setQuery($q);
166 $ordbusy = $dbo->loadAssocList();
167 if ($ordbusy) {
168 foreach ($ordbusy as $ob) {
169 $q = "DELETE FROM `#__vikbooking_busy` WHERE `id`=".(int)$ob['idbusy'].";";
170 $dbo->setQuery($q);
171 $dbo->execute();
172 }
173 }
174 $q = "DELETE FROM `#__vikbooking_ordersbusy` WHERE `idorder`=".(int)$order['id'].";";
175 $dbo->setQuery($q);
176 $dbo->execute();
177
178 /**
179 * We now save onto a var the full error message to understand what made the booking become cancelled.
180 * This way, by checking the booking history it will be easy to understand the cause of the issue.
181 *
182 * @since October 15th 2020
183 */
184 $history_err_descr = '';
185 if ($today_midnight > $order['checkin']) {
186 $history_err_descr = JText::translate('VBOBOOKNOLONGERPAYABLE');
187 } elseif ($autoremove === true) {
188 $history_err_descr = JText::translate('VBOERRAUTOREMOVED');
189 } else {
190 $history_err_descr = JText::translate('VBERRREPSEARCH');
191 }
192 if (!empty($history_err_descr)) {
193 VikError::raiseWarning('', $history_err_descr);
194 }
195
196 //Booking History
197 VikBooking::getBookingHistoryInstance()->setBid($order['id'])->store('CA', $history_err_descr);
198 //
199 }
200 }
201
202 // render the booking details
203
204 // set noindex instruction for robots
205 $document->setMetaData('robots', 'noindex,follow');
206
207 // load jQuery
208 if (VikBooking::loadJquery()) {
209 JHtml::fetch('jquery.framework', true, true);
210 }
211
212 $tars = [];
213 $cookie = $app->input->cookie;
214 $pcheckin = $order['checkin'];
215 $pcheckout = $order['checkout'];
216 $secdiff = $pcheckout - $pcheckin;
217 $daysdiff = $secdiff / 86400;
218 if (is_int($daysdiff)) {
219 if ($daysdiff < 1) {
220 $daysdiff = 1;
221 }
222 } else {
223 if ($daysdiff < 1) {
224 $daysdiff = 1;
225 } else {
226 $sum = floor($daysdiff) * 86400;
227 $newdiff = $secdiff - $sum;
228 $maxhmore = VikBooking::getHoursMoreRb() * 3600;
229 if ($maxhmore >= $newdiff) {
230 $daysdiff = floor($daysdiff);
231 } else {
232 $daysdiff = ceil($daysdiff);
233 }
234 }
235 }
236 $is_package = !empty($order['pkg']) ? true : false;
237 $orderrooms = [];
238 $q = "SELECT `or`.`idroom`,`or`.`adults`,`or`.`children`,`or`.`idtar`,`or`.`optionals`,`or`.`roomindex`,`or`.`pkg_id`,`or`.`pkg_name`,`or`.`cust_cost`,`or`.`cust_idiva`,`or`.`extracosts`,`or`.`room_cost`,`or`.`otarplan`,`r`.`id` AS `r_reference_id`,`r`.`name`,`r`.`img`,`r`.`idcarat`,`r`.`fromadult`,`r`.`toadult` FROM `#__vikbooking_ordersrooms` AS `or`,`#__vikbooking_rooms` AS `r` WHERE `or`.`idorder`='".$order['id']."' AND `or`.`idroom`=`r`.`id` ORDER BY `or`.`id` ASC;";
239 $dbo->setQuery($q);
240 $orderrooms = $dbo->loadAssocList();
241 if ($orderrooms) {
242 $vbo_tn->translateContents($orderrooms, '#__vikbooking_rooms', array('id' => 'r_reference_id'));
243 foreach ($orderrooms as $kor => $or) {
244 $num = $kor + 1;
245 if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
246 //package or custom cost set from the back-end
247 continue;
248 }
249 $q = "SELECT `t`.*,`p`.`name`,`p`.`free_cancellation`,`p`.`canc_deadline`,`p`.`canc_policy` FROM `#__vikbooking_dispcost` AS `t` LEFT JOIN `#__vikbooking_prices` AS `p` ON `t`.`idprice`=`p`.`id` WHERE `t`.`id`=" . (int)$or['idtar'] . ";";
250 $dbo->setQuery($q);
251 $tar = $dbo->loadAssocList();
252 if (!$tar) {
253 continue;
254 }
255 $vbo_tn->translateContents($tar, '#__vikbooking_prices', array('id' => 'idprice'));
256
257 // determine proper values for this room
258 $room_stay_checkin = $order['checkin'];
259 $room_stay_checkout = $order['checkout'];
260 $room_stay_nights = $order['days'];
261 if ($order['split_stay'] && count($room_stay_dates) && isset($room_stay_dates[$kor]) && $room_stay_dates[$kor]['idroom'] == $or['idroom']) {
262 $room_stay_checkin = !empty($room_stay_dates[$kor]['checkin_ts']) ? $room_stay_dates[$kor]['checkin_ts'] : $room_stay_dates[$kor]['checkin'];
263 $room_stay_checkout = !empty($room_stay_dates[$kor]['checkout_ts']) ? $room_stay_dates[$kor]['checkout_ts'] : $room_stay_dates[$kor]['checkout'];
264 $room_stay_nights = $av_helper->countNightsOfStay($room_stay_checkin, $room_stay_checkout);
265 }
266
267 // apply seasonal rates
268 $tar = VikBooking::applySeasonsRoom($tar, $room_stay_checkin, $room_stay_checkout);
269
270 // apply OBP rules
271 $tar = VBORoomHelper::getInstance()->applyOBPRules($tar, $or, $or['adults']);
272
273 // push tariffs
274 $tars[$num] = $tar[0];
275 }
276 }
277
278 $days_to_arrival = 0;
279 $now_info = getdate();
280 $checkin_info = getdate($order['checkin']);
281 if ($now_info[0] < $checkin_info[0]) {
282 while ($now_info[0] < $checkin_info[0]) {
283 if (!($now_info['mday'] != $checkin_info['mday'] || $now_info['mon'] != $checkin_info['mon'] || $now_info['year'] != $checkin_info['year'])) {
284 break;
285 }
286 $days_to_arrival++;
287 $now_info = getdate(mktime(0, 0, 0, $now_info['mon'], ($now_info['mday'] + 1), $now_info['year']));
288 }
289 }
290
291 $is_refundable = 0;
292 $daysadv_refund_arr = [];
293 $daysadv_refund = 0;
294 $canc_policy = '';
295 foreach ($tars as $num => $tar) {
296 if ($tar['free_cancellation'] < 1) {
297 // if at least one rate plan is non-refundable, the whole reservation cannot be cancelled
298 $is_refundable = 0;
299 $daysadv_refund_arr = [];
300 break;
301 }
302 $is_refundable = 1;
303 $daysadv_refund_arr[] = $tar['canc_deadline'];
304 }
305
306 // get the rate plan with the lowest cancellation deadline
307 $daysadv_refund = count($daysadv_refund_arr) > 0 ? min($daysadv_refund_arr) : $daysadv_refund;
308 if ($daysadv_refund > 0) {
309 foreach ($tars as $num => $tar) {
310 if ($tar['free_cancellation'] > 0 && $tar['canc_deadline'] == $daysadv_refund) {
311 //get the cancellation policy from the first rate plan with free cancellation and same cancellation deadline
312 $canc_policy = $tar['canc_policy'];
313 break;
314 }
315 }
316 }
317
318 $payment = "";
319 if (!empty($order['idpayment'])) {
320 $exppay = explode('=', $order['idpayment']);
321 $payment = VikBooking::getPayment($exppay[0], $vbo_tn);
322 }
323 $pnodep = VikRequest::getString('nodep', '', 'request');
324 $cnodep = $cookie->get('vboFA', '', 'string');
325 $nodep = intval($pnodep) > 0 || intval($cnodep) > 0 ? 1 : 0;
326
327 /**
328 * Upselling extra services only for non-cancelled bookings
329 * with a check-out date in the future.
330 *
331 * @since 1.13.0 (J) - 1.3.0 (WP)
332 */
333 $upselling = [];
334 if ($order['status'] != 'cancelled' && VikBooking::upsellingEnabled() && $order['checkout'] > time()) {
335 $upsell_data = [];
336 foreach ($orderrooms as $kor => $or) {
337 $room_data = new stdClass;
338 $room_data->id = $or['idroom'];
339 $room_data->name = $or['name'];
340 $room_data->img = $or['img'];
341 $room_data->adults = $or['adults'];
342 $room_data->children = $or['children'];
343 $room_data->nights = $order['days'];
344 $room_data->options = [];
345 if (!empty($or['optionals'])) {
346 $optids = explode(';', $or['optionals']);
347 foreach ($optids as $optid) {
348 if (!empty($optid)) {
349 // the : may express the quantity
350 $optidparts = explode(':', $optid);
351 array_push($room_data->options, (int)$optidparts[0]);
352 }
353 }
354 }
355 array_push($upsell_data, $room_data);
356 }
357 $upselling = VikBooking::loadUpsellingData(
358 $upsell_data,
359 array(
360 'id' => $order['id'],
361 'checkin' => $order['checkin'],
362 'checkout' => $order['checkout'],
363 ),
364 $vbo_tn
365 );
366 }
367
368 /**
369 * Trigger first tracking conversion on booking.
370 *
371 * @since 1.16.3 (J) - 1.6.3 (WP)
372 */
373 VikBooking::getTracker()->triggerBookingConversion($order);
374
375 $this->ord = $order;
376 $this->orderrooms = $orderrooms;
377 $this->tars = $tars;
378 $this->days_to_arrival = $days_to_arrival;
379 $this->is_refundable = $is_refundable;
380 $this->daysadv_refund = $daysadv_refund;
381 $this->canc_policy = $canc_policy;
382 $this->payment = $payment;
383 $this->nodep = $nodep;
384 $this->upselling = $upselling;
385 $this->vbo_tn = $vbo_tn;
386
387 // theme
388 $theme = VikBooking::getTheme();
389 if ($theme != 'default') {
390 $thdir = VBO_SITE_PATH . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . $theme . DIRECTORY_SEPARATOR . 'booking';
391 if (is_dir($thdir)) {
392 $this->_setPath('template', $thdir . DIRECTORY_SEPARATOR);
393 }
394 }
395 //
396
397 parent::display($tpl);
398 }
399 }
400