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

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