PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.4
VikBooking Hotel Booking Engine & PMS v1.6.4
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.6.4, at site/views/booking/view.html.php

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