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 / tmpl / default.php

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

1,722 lines 71.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 $ord = $this->ord;
14 $orderrooms = $this->orderrooms;
15 $tars = $this->tars;
16 $payment = $this->payment;
17 $vbo_tn = $this->vbo_tn;
18
19 // availability helper
20 $av_helper = VikBooking::getAvailabilityInstance();
21
22 // room stay dates in case of split stay
23 $room_stay_dates = [];
24 if ($ord['split_stay']) {
25 if ($ord['status'] == 'confirmed') {
26 $room_stay_dates = $av_helper->loadSplitStayBusyRecords($ord['id']);
27 } else {
28 $room_stay_dates = VBOFactory::getConfig()->getArray('split_stay_' . $ord['id'], []);
29 }
30 }
31
32 $currencysymb = VikBooking::getCurrencySymb();
33 $nowdf = VikBooking::getDateFormat();
34 if ($nowdf == "%d/%m/%Y") {
35 $df = 'd/m/Y';
36 } elseif ($nowdf == "%m/%d/%Y") {
37 $df = 'm/d/Y';
38 } else {
39 $df = 'Y/m/d';
40 }
41 $datesep = VikBooking::getDateSeparator();
42 $ptmpl = VikRequest::getString('tmpl', '', 'request');
43 $pitemid = VikRequest::getInt('Itemid', 0, 'request');
44 $bestitemid = VikBooking::findProperItemIdType(['booking']);
45 $now_info = getdate();
46
47 $wdays_map = [
48 JText::translate('VBWEEKDAYZERO'),
49 JText::translate('VBWEEKDAYONE'),
50 JText::translate('VBWEEKDAYTWO'),
51 JText::translate('VBWEEKDAYTHREE'),
52 JText::translate('VBWEEKDAYFOUR'),
53 JText::translate('VBWEEKDAYFIVE'),
54 JText::translate('VBWEEKDAYSIX')
55 ];
56
57 $isdue = 0;
58 $isdue_orig = 0;
59 $imp = 0;
60 $pricenames = array();
61 $optbought = array();
62 $extraservices = array();
63 $roomsnames = array();
64 $is_package = !empty($ord['pkg']) ? true : false;
65 foreach ($orderrooms as $kor => $or) {
66 $num = $kor + 1;
67 $roomsnames[] = $or['name'];
68
69 // determine proper values for this room
70 $room_stay_checkin = $ord['checkin'];
71 $room_stay_checkout = $ord['checkout'];
72 $room_stay_nights = $ord['days'];
73 if ($ord['split_stay'] && count($room_stay_dates) && isset($room_stay_dates[$kor]) && $room_stay_dates[$kor]['idroom'] == $or['idroom']) {
74 $room_stay_checkin = !empty($room_stay_dates[$kor]['checkin_ts']) ? $room_stay_dates[$kor]['checkin_ts'] : $room_stay_dates[$kor]['checkin'];
75 $room_stay_checkout = !empty($room_stay_dates[$kor]['checkout_ts']) ? $room_stay_dates[$kor]['checkout_ts'] : $room_stay_dates[$kor]['checkout'];
76 $room_stay_nights = $av_helper->countNightsOfStay($room_stay_checkin, $room_stay_checkout);
77 // inject nights calculated for this room
78 $room_stay_dates[$kor]['nights'] = $room_stay_nights;
79 }
80
81 if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
82 // package cost or cust_cost may not be inclusive of taxes if prices tax included is off
83 $calctar = VikBooking::sayPackagePlusIva($or['cust_cost'], $or['cust_idiva']);
84 $isdue += $calctar;
85 $isdue_orig += $calctar;
86 $imp += VikBooking::sayPackageMinusIva($or['cust_cost'], $or['cust_idiva']);
87 $pricenames[$num] = (!empty($or['pkg_name']) ? $or['pkg_name'] : (!empty($or['otarplan']) ? $or['otarplan'] : JText::translate('VBOROOMCUSTRATEPLAN')));
88 } elseif (array_key_exists($num, $tars) && is_array($tars[$num])) {
89 $display_rate = $ord['status'] != 'confirmed' && !empty($or['room_cost']) ? $or['room_cost'] : $tars[$num]['cost'];
90 $calctar = VikBooking::sayCostPlusIva($display_rate, $tars[$num]['idprice']);
91 $tars[$num]['calctar'] = $calctar;
92 $isdue += $calctar;
93 $isdue_orig += $or['room_cost'];
94 $imp += VikBooking::sayCostMinusIva($display_rate, $tars[$num]['idprice']);
95 $pricenames[$num] = VikBooking::getPriceName($tars[$num]['idprice'], $vbo_tn);
96 }
97 if (!empty($or['optionals'])) {
98 $stepo = explode(";", $or['optionals']);
99 foreach ($stepo as $roptkey => $one) {
100 if (empty($one)) {
101 continue;
102 }
103 $stept = explode(":", $one);
104 $actopt = VikBooking::getSingleOption($stept[0], $vbo_tn);
105 if (!$actopt) {
106 continue;
107 }
108 $chvar = '';
109 if (!empty($actopt['ageintervals']) && $or['children'] > 0 && strstr($stept[1], '-') != false) {
110 $optagenames = VikBooking::getOptionIntervalsAges($actopt['ageintervals']);
111 $optagepcent = VikBooking::getOptionIntervalsPercentage($actopt['ageintervals']);
112 $optageovrct = VikBooking::getOptionIntervalChildOverrides($actopt, $or['adults'], $or['children']);
113 $child_num = VikBooking::getRoomOptionChildNumber($or['optionals'], $actopt['id'], $roptkey, $or['children']);
114 $optagecosts = VikBooking::getOptionIntervalsCosts(isset($optageovrct['ageintervals_child' . ($child_num + 1)]) ? $optageovrct['ageintervals_child' . ($child_num + 1)] : $actopt['ageintervals']);
115 $agestept = explode('-', $stept[1]);
116 $stept[1] = $agestept[0];
117 $chvar = $agestept[1];
118 if (array_key_exists(($chvar - 1), $optagepcent) && $optagepcent[($chvar - 1)] == 1) {
119 //percentage value of the adults tariff
120 if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
121 $optagecosts[($chvar - 1)] = $or['cust_cost'] * $optagecosts[($chvar - 1)] / 100;
122 } else {
123 $display_rate = !empty($or['room_cost']) ? $or['room_cost'] : $tars[$num]['cost'];
124 $optagecosts[($chvar - 1)] = $display_rate * $optagecosts[($chvar - 1)] / 100;
125 }
126 } elseif (array_key_exists(($chvar - 1), $optagepcent) && $optagepcent[($chvar - 1)] == 2) {
127 //VBO 1.10 - percentage value of room base cost
128 if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
129 $optagecosts[($chvar - 1)] = $or['cust_cost'] * $optagecosts[($chvar - 1)] / 100;
130 } else {
131 $display_rate = isset($tars[$num]['room_base_cost']) ? $tars[$num]['room_base_cost'] : (!empty($or['room_cost']) ? $or['room_cost'] : $tars[$num]['cost']);
132 $optagecosts[($chvar - 1)] = $display_rate * $optagecosts[($chvar - 1)] / 100;
133 }
134 }
135 $actopt['chageintv'] = $chvar;
136 $actopt['name'] .= ' ('.$optagenames[($chvar - 1)].')';
137 $realcost = (intval($actopt['perday']) == 1 ? (floatval($optagecosts[($chvar - 1)]) * $room_stay_nights * $stept[1]) : (floatval($optagecosts[($chvar - 1)]) * $stept[1]));
138 } else {
139 // VBO 1.11 - options percentage cost of the room total fee
140 if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
141 $deftar_basecosts = $or['cust_cost'];
142 } else {
143 $deftar_basecosts = !empty($or['room_cost']) ? $or['room_cost'] : $tars[$num]['cost'];
144 }
145 $actopt['cost'] = (int)$actopt['pcentroom'] ? ($deftar_basecosts * $actopt['cost'] / 100) : $actopt['cost'];
146 //
147 $realcost = (intval($actopt['perday']) == 1 ? ($actopt['cost'] * $room_stay_nights * $stept[1]) : ($actopt['cost'] * $stept[1]));
148 }
149 if (!empty($actopt['maxprice']) && $actopt['maxprice'] > 0 && $realcost > $actopt['maxprice']) {
150 $realcost = $actopt['maxprice'];
151 if (intval($actopt['hmany']) == 1 && intval($stept[1]) > 1) {
152 $realcost = $actopt['maxprice'] * $stept[1];
153 }
154 }
155 if ($actopt['perperson'] == 1) {
156 $realcost = $realcost * $or['adults'];
157 }
158 $tmpopr = VikBooking::sayOptionalsPlusIva($realcost, $actopt['idiva']);
159 $isdue += $tmpopr;
160 $isdue_orig += $tmpopr;
161 $imp += VikBooking::sayOptionalsMinusIva($realcost, $actopt['idiva']);
162 if (!isset($optbought[$num])) {
163 $optbought[$num] = '';
164 }
165 $optbought[$num] .= "<div class=\"vbo-booking-item-row\"><span class=\"vbo-booking-pricename\">".($stept[1] > 1 ? $stept[1] . " " : "") . $actopt['name'] . "</span> <span class=\"vbo-booking-pricedet\"><span class=\"vbo_currency\">" . $currencysymb . "</span> <span class=\"vbo_price\">" . VikBooking::numberFormat($tmpopr) . "</span></span></div>";
166 }
167 }
168
169 // custom extra costs
170 if (!empty($or['extracosts'])) {
171 $extraservices[$num] = '';
172 $cur_extra_costs = json_decode($or['extracosts'], true);
173 foreach ($cur_extra_costs as $eck => $ecv) {
174 $ecplustax = !empty($ecv['idtax']) ? VikBooking::sayOptionalsPlusIva($ecv['cost'], $ecv['idtax']) : $ecv['cost'];
175 $isdue += $ecplustax;
176 $isdue_orig += $ecplustax;
177 $imp += !empty($ecv['idtax']) ? VikBooking::sayOptionalsMinusIva($ecv['cost'], $ecv['idtax']) : $ecv['cost'];
178 $extraservices[$num] .= "<div class=\"vbo-booking-item-row\"><span class=\"vbo-booking-pricename\">".$ecv['name']."</span> <span class=\"vbo-booking-pricedet\"><span class=\"vbo_currency\">" . $currencysymb . "</span> <span class=\"vbo_price\">" . VikBooking::numberFormat($ecplustax) . "</span></span></div>";
179 }
180 }
181 }
182
183 $tax = $isdue - $imp;
184
185 $usedcoupon = false;
186 $origisdue = $isdue;
187 if (strlen((string)$ord['coupon']) > 0) {
188 $usedcoupon = true;
189 $expcoupon = explode(";", $ord['coupon']);
190 $isdue = $isdue - $expcoupon[1];
191 $isdue_orig = $isdue_orig - $expcoupon[1];
192 }
193
194 if ($ord['refund'] > 0) {
195 $isdue -= $ord['refund'];
196 $isdue_orig -= $ord['refund'];
197 }
198
199 //Check whether the booking total amount has changed due to rates modifications for these dates, made after this booking
200 $rooms_total_changed = ($ord['status'] == 'confirmed' && number_format($isdue, 2) != number_format($ord['total'], 2) && number_format($origisdue, 2) != number_format($ord['total'], 2));
201 $only_roomsrates_changed = ($rooms_total_changed === true && number_format($isdue_orig, 2) == number_format($ord['total'], 2));
202
203 //booking modification, cancellation and request
204 $resmodcanc = VikBooking::getReservationModCanc();
205 $resmodcanc = $this->days_to_arrival < 1 ? 0 : $resmodcanc;
206 $resmodcancmin = VikBooking::getReservationModCancMin();
207 $mod_allowed = ($resmodcanc > 1 && $resmodcanc != 3 && $this->days_to_arrival >= $resmodcancmin);
208 $canc_allowed = ($resmodcanc > 1 && $resmodcanc != 2 && $this->is_refundable > 0 && $this->daysadv_refund <= $this->days_to_arrival && $this->days_to_arrival >= $resmodcancmin);
209
210 $ts_info = getdate($ord['ts']);
211 $checkin_info = getdate($ord['checkin']);
212 $checkout_info = getdate($ord['checkout']);
213
214 // the current booking URI
215 $current_booking_uri = JRoute::rewrite('index.php?option=com_vikbooking&view=booking&sid='.(!empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']).'&ts='.$ord['ts'].(!empty($bestitemid) ? '&Itemid='.$bestitemid : (!empty($pitemid) ? '&Itemid='.$pitemid : '')));
216 ?>
217 <a class="vbo-current-booking-uri" href="<?php echo $current_booking_uri; ?>" style="display: none;"></a>
218 <?php
219
220 //print button
221 if ($ord['status'] == 'confirmed' && $ptmpl != 'component') {
222 ?>
223 <div class="vbo-booking-print">
224 <a class="vbo-booking-print-link" href="<?php echo JRoute::rewrite('index.php?option=com_vikbooking&view=booking&sid='.(!empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']).'&ts='.$ord['ts'].'&tmpl=component'.(!empty($bestitemid) ? '&Itemid='.$bestitemid : (!empty($pitemid) ? '&Itemid='.$pitemid : ''))); ?>" target="_blank" title="<?php echo JText::translate('VBOPRINT'); ?>"><?php VikBookingIcons::e('print'); ?></a>
225 </div>
226 <?php
227 }
228
229 if ($ord['status'] == 'confirmed') {
230 $head_css = 'vbo-booking-details-head-confirmed';
231 ?>
232 <h3 class="vbo-booking-details-intro"><?php echo JText::sprintf('VBOYOURBOOKCONFAT', VikBooking::getFrontTitle()); ?></h3>
233 <?php
234 } elseif ($ord['status'] == 'cancelled') {
235 $head_css = 'vbo-booking-details-head-cancelled';
236 } else {
237 $head_css = 'vbo-booking-details-head-pending';
238 }
239 ?>
240
241 <div class="vbo-booking-details-topcontainer">
242
243 <div class="vbo-booking-details-head <?php echo $head_css; ?>">
244 <?php
245 if ($ord['status'] == 'confirmed') {
246 ?>
247 <h4><?php echo JText::translate('VBOYOURBOOKISCONF'); ?></h4>
248 <?php
249 } elseif ($ord['status'] != 'cancelled') {
250 ?>
251 <h4><?php echo JText::translate('VBOYOURBOOKISPEND'); ?></h4>
252 <?php
253 } else {
254 ?>
255 <h4><?php echo JText::translate('VBOYOURBOOKISCANC'); ?></h4>
256 <?php
257 }
258 ?>
259 </div>
260
261 <div class="vbo-paycontainer-pos vbo-paycontainer-pos-top" style="display: none;"></div>
262
263 <div class="vbo-booking-details-midcontainer">
264
265 <div class="vbo-booking-details-bookinfos">
266 <span class="vbvordudatatitle"><?php echo JText::translate('VBORDERDETAILS'); ?></span>
267 <div class="vbo-booking-details-bookinfo">
268 <span class="vbo-booking-details-bookinfo-lbl"><?php echo JText::translate('VBORDEREDON'); ?></span>
269 <span class="vbo-booking-details-bookinfo-val"><?php echo $wdays_map[$ts_info['wday']].', '.date(str_replace("/", $datesep, $df).' H:i', $ord['ts']); ?></span>
270 </div>
271 <?php
272 if (!empty($ord['idorderota']) && !empty($ord['channel'])) {
273 ?>
274 <div class="vbo-booking-details-bookinfo">
275 <span class="vbo-booking-details-bookinfo-lbl"><?php echo JText::translate('VBORDERNUMBER'); ?></span>
276 <span class="vbo-booking-details-bookinfo-val"><?php echo $ord['idorderota']; ?></span>
277 </div>
278 <?php
279 }
280 if ($ord['status'] == 'confirmed') {
281 ?>
282 <div class="vbo-booking-details-bookinfo">
283 <span class="vbo-booking-details-bookinfo-lbl"><?php echo JText::translate('VBCONFIRMNUMB'); ?></span>
284 <span class="vbo-booking-details-bookinfo-val"><?php echo $ord['confirmnumber']; ?></span>
285 </div>
286 <?php
287 }
288 ?>
289 <div class="vbo-booking-details-bookinfo">
290 <span class="vbo-booking-details-bookinfo-lbl"><?php echo JText::translate('VBDAL'); ?></span>
291 <span class="vbo-booking-details-bookinfo-val"><?php echo $wdays_map[$checkin_info['wday']].', '.date(str_replace("/", $datesep, $df).' H:i', $ord['checkin']); ?></span>
292 </div>
293 <div class="vbo-booking-details-bookinfo">
294 <span class="vbo-booking-details-bookinfo-lbl"><?php echo JText::translate('VBAL'); ?></span>
295 <span class="vbo-booking-details-bookinfo-val"><?php echo $wdays_map[$checkout_info['wday']].', '.date(str_replace("/", $datesep, $df).' H:i', $ord['checkout']); ?></span>
296 </div>
297 <div class="vbo-booking-details-bookinfo">
298 <span class="vbo-booking-details-bookinfo-lbl"><?php echo JText::translate('VBDAYS'); ?></span>
299 <span class="vbo-booking-details-bookinfo-val"><?php echo $ord['days']; ?></span>
300 </div>
301 <?php
302 if ($ord['split_stay']) {
303 ?>
304 <div class="vbo-booking-details-bookinfo vbo-booking-details-bookinfo-splitstay">
305 <span class="vbo-booking-details-bookinfo-lbl"><?php VikBookingIcons::e('random'); ?> <?php echo JText::translate('VBO_SPLIT_STAY_RES'); ?></span>
306 </div>
307 <?php
308 }
309 ?>
310 </div>
311
312 <div class="vbo-booking-details-udets">
313 <span class="vbvordudatatitle"><?php echo JText::translate('VBPERSDETS'); ?></span>
314 <div class="vbo-bookingdet-custdata">
315 <?php
316 $custdata_parts = explode("\n", $ord['custdata']);
317 if (count($custdata_parts) > 2 && strpos($custdata_parts[0], ':') !== false && strpos($custdata_parts[1], ':') !== false) {
318 //attempt to format labels and values
319 foreach ($custdata_parts as $custdet) {
320 if (strlen((string)$custdet) < 1) {
321 continue;
322 }
323 $custdet_parts = explode(':', $custdet);
324 $custd_lbl = '';
325 $custd_val = '';
326 if (count($custdet_parts) < 2) {
327 $custd_val = $custdet;
328 } else {
329 $custd_lbl = $custdet_parts[0];
330 unset($custdet_parts[0]);
331 $custd_val = trim(implode(':', $custdet_parts));
332 }
333 ?>
334 <div class="vbo-bookingdet-userdetail">
335 <?php
336 if (strlen((string)$custd_lbl)) {
337 ?>
338 <span class="vbo-bookingdet-userdetail-lbl"><?php echo VikBooking::tnCustomerRawDataLabel($custd_lbl); ?></span>
339 <?php
340 }
341 if (strlen((string)$custd_val)) {
342 ?>
343 <span class="vbo-bookingdet-userdetail-val"><?php echo $custd_val; ?></span>
344 <?php
345 }
346 ?>
347 </div>
348 <?php
349 }
350 } else {
351 echo nl2br($ord['custdata']);
352 }
353 ?>
354 </div>
355 </div>
356 <?php
357 // booking modification, cancellation, pre check-in or modification request (confirmed status only)
358 $precheckin = VikBooking::precheckinEnabled();
359 if ($precheckin) {
360 // make sure the limit of days in advance is reflected
361 $precheckin_mind = VikBooking::precheckinMinOffset();
362 $precheckin_lim_ts = strtotime("+{$precheckin_mind} days 00:00:00");
363 $precheckin = ($precheckin_lim_ts <= $ord['checkin'] || ($precheckin_mind === 1 && time() <= $ord['checkin']));
364 }
365
366 /**
367 * If this is an OTA booking, try to print the OTA logo.
368 *
369 * @since 1.13
370 */
371 $isotabooking = (!empty($ord['idorderota']) && !empty($ord['channel']));
372 $otalogo = false;
373 if ($isotabooking) {
374 $otalogo = VikBooking::getVcmChannelsLogo($ord['channel']);
375 }
376 //
377
378 /**
379 * Booking guest review
380 *
381 * @since 1.13
382 */
383 $canbereviewed = VikBooking::canBookingBeReviewed($ord);
384 //
385
386 if ($ord['status'] == 'confirmed' && ($precheckin || $canbereviewed || $mod_allowed || $canc_allowed || ($resmodcanc === 1 && $this->days_to_arrival >= $resmodcancmin) || $otalogo || count($this->upselling))) {
387 ?>
388 <div class="vbo-booking-details-actions">
389 <div class="vbo-booking-details-actions-inner">
390 <?php
391 if ($otalogo) {
392 ?>
393 <div class="vbo-booking-mod-container vbo-booking-otabooking-wrap">
394 <div class="vbo-booking-mod-inner">
395 <div class="vbo-booking-mod-cmd">
396 <img class="vbo-otabooking-logo" src="<?php echo $otalogo; ?>" alt="<?php echo htmlspecialchars($ord['idorderota']); ?>" title="<?php echo htmlspecialchars($ord['idorderota']); ?>" />
397 </div>
398 </div>
399 </div>
400 <?php
401 }
402 if ($precheckin) {
403 $start_itemid = VikBooking::findProperItemIdType(['booking', 'vikbooking']);
404 ?>
405 <div class="vbo-booking-mod-container">
406 <div class="vbo-booking-mod-inner">
407 <div class="vbo-booking-mod-cmd vbo-booking-precheckin-cmd">
408 <a href="<?php echo JRoute::rewrite('index.php?option=com_vikbooking&view=precheckin&sid='.(!empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']).'&ts='.$ord['ts'].(!empty($pitemid) ? '&Itemid='.$pitemid : (!empty($start_itemid) ? '&Itemid='.$start_itemid : ''))); ?>"><?php VikBookingIcons::e('users'); ?> <?php echo JText::translate('VBOPRECHECKIN'); ?></a>
409 </div>
410 </div>
411 </div>
412 <?php
413 }
414 if ($canbereviewed) {
415 $start_itemid = VikBooking::findProperItemIdType(['booking', 'vikbooking']);
416 ?>
417 <div class="vbo-booking-mod-container">
418 <div class="vbo-booking-mod-inner">
419 <div class="vbo-booking-mod-cmd vbo-booking-review-cmd">
420 <a href="<?php echo JRoute::rewrite('index.php?option=com_vikbooking&view=revstay&sid='.(!empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']).'&ts='.$ord['ts'].(!empty($pitemid) ? '&Itemid='.$pitemid : (!empty($start_itemid) ? '&Itemid='.$start_itemid : ''))); ?>"><?php VikBookingIcons::e('star'); ?> <?php echo JText::translate('VBOLEAVEAREVIEW'); ?></a>
421 </div>
422 </div>
423 </div>
424 <?php
425 }
426 if ($mod_allowed && !$isotabooking && !$ord['split_stay']) {
427 $start_itemid = VikBooking::findProperItemIdType(['vikbooking', 'roomslist']);
428 ?>
429 <div class="vbo-booking-mod-container">
430 <div class="vbo-booking-mod-inner">
431 <div class="vbo-booking-mod-cmd">
432 <a onclick="return confirm('<?php echo addslashes(JText::translate('VBOMODYOURBOOKINGCONF')); ?>');" href="<?php echo JRoute::rewrite('index.php?option=com_vikbooking&view=vikbooking&modify_sid='.$ord['sid'].'&modify_id='.$ord['id'].(!empty($pitemid) ? '&Itemid='.$pitemid : (!empty($start_itemid) ? '&Itemid='.$start_itemid : ''))); ?>"><?php VikBookingIcons::e('edit'); ?> <?php echo JText::translate('VBOMODYOURBOOKING'); ?></a>
433 </div>
434 </div>
435 </div>
436 <?php
437 /**
438 * Suggest room upgrade options, if any.
439 *
440 * @since 1.16.0 (J) - 1.6.0 (WP)
441 */
442 echo $this->loadTemplate('upgrade');
443 }
444 if ($canc_allowed && !$isotabooking) {
445 ?>
446 <div class="vbo-booking-canc-container">
447 <div class="vbo-booking-canc-inner">
448 <div class="vbo-booking-canc-cmd">
449 <span onclick="document.getElementById('vbo-booking-cancform-container').style.display='block';location.hash='bcancf';"><?php VikBookingIcons::e('times-circle'); ?> <?php echo JText::translate('VBOCANCYOURBOOKING'); ?></span>
450 </div>
451 </div>
452 </div>
453 <?php
454 }
455 if ($resmodcanc === 1 && $this->days_to_arrival >= $resmodcancmin && !$isotabooking) {
456 ?>
457 <div class="vbo-booking-mod-container">
458 <div class="vbo-booking-mod-inner">
459 <div class="vbo-booking-mod-cmd">
460 <a onclick="vbOpenCancOrdForm();" href="javascript: void(0);"><?php VikBookingIcons::e('envelope'); ?> <?php echo JText::translate('VBREQUESTCANCMOD'); ?></a>
461 </div>
462 </div>
463 </div>
464 <?php
465 }
466 if (count($this->upselling)) {
467 ?>
468 <div class="vbo-hidein-print vbo-booking-mod-container vbo-booking-upselling-wrap">
469 <div class="vbo-booking-mod-inner">
470 <div class="vbo-booking-mod-cmd">
471 <a onclick="vbGotoUpsell();" href="javascript: void(0);"><?php VikBookingIcons::e('cart-plus'); ?> <?php echo JText::translate('VBOADDEXTRASTOBOOK'); ?></a>
472 </div>
473 </div>
474 </div>
475 <?php
476 }
477 ?>
478 </div>
479 </div>
480 <?php
481 }
482 ?>
483
484 </div>
485
486 <div class="vbo-paycontainer-pos vbo-paycontainer-pos-middle" style="display: none;"></div>
487
488 </div>
489
490 <div class="vbo-booking-rooms-wrapper">
491 <?php
492 foreach ($orderrooms as $kor => $or) {
493 $num = $kor + 1;
494 ?>
495 <div class="vbvordroominfo<?php echo count($orderrooms) > 1 ? ' vbvordroominfo-multi' : ''; ?>">
496 <?php
497 if (strlen((string)$or['img']) > 0) {
498 ?>
499 <div class="vbo-booking-roomphoto">
500 <img src="<?php echo VBO_SITE_URI; ?>resources/uploads/<?php echo $or['img']; ?>"/>
501 </div>
502 <?php
503 }
504 ?>
505 <div class="vbordroomdet">
506 <span class="vbvordroominfotitle"><?php echo $or['name']; ?></span>
507 <div class="vbordroomdetpeople">
508 <span class="vbo-booking-numadults"><?php echo $or['adults']; ?> <?php echo ($or['adults'] == 1 ? JText::translate('VBSEARCHRESADULT') : JText::translate('VBSEARCHRESADULTS')); ?></span>
509 <?php
510 if ($or['children'] > 0) {
511 ?>
512 <span class="vbo-booking-numchildren"><?php echo $or['children']." ".($or['children'] == 1 ? JText::translate('VBSEARCHRESCHILD') : JText::translate('VBSEARCHRESCHILDREN')); ?></span>
513 <?php
514 }
515 ?>
516 </div>
517 <?php
518 if ($ord['split_stay'] && count($room_stay_dates) && isset($room_stay_dates[$kor]) && $room_stay_dates[$kor]['idroom'] == $or['idroom']) {
519 $room_stay_checkin = !empty($room_stay_dates[$kor]['checkin_ts']) ? $room_stay_dates[$kor]['checkin_ts'] : $room_stay_dates[$kor]['checkin'];
520 $room_stay_checkout = !empty($room_stay_dates[$kor]['checkout_ts']) ? $room_stay_dates[$kor]['checkout_ts'] : $room_stay_dates[$kor]['checkout'];
521 $room_stay_nights = $av_helper->countNightsOfStay($room_stay_checkin, $room_stay_checkout);
522 // inject nights calculated for this room
523 $room_stay_dates[$kor]['nights'] = $room_stay_nights;
524 ?>
525 <div class="vbo-booking-splitstay-info">
526 <div class="vbo-booking-splitstay-info-room">
527 <span class="vbo-booking-splitstay-nights"><?php VikBookingIcons::e('moon'); ?> <?php echo $room_stay_nights . ' ' . ($room_stay_nights > 1 ? JText::translate('VBDAYS') : JText::translate('VBDAY')); ?></span>
528 <span class="vbo-booking-splitstay-checkin"><?php VikBookingIcons::e('sign-in'); ?> <?php echo date(str_replace("/", $datesep, $df), $room_stay_checkin); ?></span>
529 <span class="vbo-booking-splitstay-checkout"><?php VikBookingIcons::e('sign-out'); ?> <?php echo date(str_replace("/", $datesep, $df), $room_stay_checkout); ?></span>
530 </div>
531 </div>
532 <?php
533 }
534 if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
535 ?>
536 <div class="vbo-booking-roomrate">
537 <span class="vbvordcoststitlemain">
538 <span class="vbo-booking-pricename"><?php echo $pricenames[$num]; ?></span>
539 <span class="room_cost">
540 <span class="vbo_currency"><?php echo $currencysymb; ?></span>
541 <span class="vbo_price"><?php echo VikBooking::numberFormat($or['cust_cost']); ?></span>
542 </span>
543 </span>
544 </div>
545 <?php
546 } elseif (array_key_exists($num, $tars) && is_array($tars[$num])) {
547 ?>
548 <div class="vbo-booking-roomrate">
549 <span class="vbvordcoststitlemain">
550 <span class="vbo-booking-pricename"><?php echo $pricenames[$num]; ?></span>
551 <span class="room_cost">
552 <span class="vbo_currency"><?php echo $currencysymb; ?></span>
553 <span class="vbo_price"<?php echo $ord['status'] == 'confirmed' && $or['room_cost'] > 0 ? ' data-vborigprice="'.VikBooking::numberFormat($or['room_cost']).'"' : ''; ?>><?php echo VikBooking::numberFormat($tars[$num]['calctar']); ?></span>
554 </span>
555 </span>
556 </div>
557 <?php
558 }
559 ?>
560 </div>
561
562 <?php
563 if ((array_key_exists($num, $optbought) && strlen((string)$optbought[$num]) > 0) || (array_key_exists($num, $extraservices) && strlen((string)$extraservices[$num]) > 0)) {
564 ?>
565 <div class="vbo-booking-room-extras">
566 <?php
567 if (array_key_exists($num, $optbought) && strlen((string)$optbought[$num]) > 0) {
568 ?>
569 <div class="vbo-booking-room-extras-options">
570 <span class="vbvordcoststitle"><?php echo JText::translate('VBOPTS'); ?></span>
571 <div class="vbo-booking-room-extras-options-list"><?php echo $optbought[$num]; ?></div>
572 </div>
573 <?php
574 }
575 if (array_key_exists($num, $extraservices) && strlen((string)$extraservices[$num]) > 0) {
576 ?>
577 <div class="vbo-booking-room-extras-services">
578 <span class="vbvordcoststitle"><?php echo JText::translate('VBOEXTRASERVICES'); ?></span>
579 <div class="vbo-booking-room-extras-services-list"><?php echo $extraservices[$num]; ?></div>
580 </div>
581 <?php
582 }
583 ?>
584 </div>
585 <?php
586 }
587 ?>
588
589 </div>
590 <?php
591 }
592 ?>
593 </div>
594
595 <?php
596 if ($rooms_total_changed === true) {
597 ?>
598 <script type="text/javascript">
599 jQuery(function() {
600 jQuery(".vbo_price").not(".vbo_keepcost").each(function(k, v) {
601 var origp = jQuery(this).attr('data-vborigprice');
602 if (origp !== undefined) {
603 jQuery(this).addClass("vbo_keepcost").text(origp).parent().find(".vbo_currency").addClass("vbo_keepcost");
604 } else {
605 <?php
606 //if only the room rates changed but not the options, keep printing the prices
607 echo !$only_roomsrates_changed ? 'jQuery(this).text("").parent().find(".vbo_currency").text("");' : 'jQuery(this).addClass("vbo_keepcost").parent().find(".vbo_currency").addClass("vbo_keepcost");';
608 ?>
609 }
610 });
611 jQuery(".vbo_currency").not(".vbo_keepcost").each(function(){
612 var cur_txt = jQuery(this).parent("span").html();
613 if (cur_txt) {
614 jQuery(this).parent("span").html(cur_txt.replace(":", ""));
615 } else {
616 var cur_txt = jQuery(this).parent("div").html();
617 if (cur_txt) {
618 jQuery(this).parent("div").html(cur_txt.replace(":", ""));
619 }
620 }
621 });
622 });
623 </script>
624 <?php
625 }
626
627 if ($ord['status'] == 'confirmed' && is_array($payment) && intval($payment['shownotealw']) == 1 && !empty($payment['note'])) {
628 ?>
629 <div class="vbvordpaynote">
630 <?php
631 /**
632 * @wponly we need to let WordPress parse the paragraphs in the message.
633 */
634 if (VBOPlatformDetection::isWordPress()) {
635 echo wpautop($payment['note']);
636 } else {
637 echo $payment['note'];
638 }
639 ?>
640 </div>
641 <?php
642 }
643 ?>
644
645 <div class="vbo-booking-costs-list">
646 <?php
647 $extra_css = $ord['status'] == 'confirmed' ? ' vbo_keepcost' : '';
648 if ($usedcoupon === true) {
649 ?>
650 <div class="vbo-booking-cost-detail vbo-booking-cost-detail-discount">
651 <div class="vbo-booking-cost-lbl">
652 <span><?php echo JText::translate('VBCOUPON') . ' ' . $expcoupon[2]; ?></span>
653 </div>
654 <div class="vbo-booking-cost-val">
655 <span class="vbo-booking-cost-val-number">
656 <span>-</span>
657 <span class="vbo_currency<?php echo $extra_css; ?>"><?php echo $currencysymb; ?></span>
658 <span class="vbo_price<?php echo $extra_css; ?>"><?php echo VikBooking::numberFormat($expcoupon[1]); ?></span>
659 </span>
660 </div>
661 </div>
662 <?php
663 }
664 if ($ord['refund'] > 0) {
665 ?>
666 <div class="vbo-booking-cost-detail vbo-booking-cost-detail-refund">
667 <div class="vbo-booking-cost-lbl">
668 <span><?php echo JText::translate('VBO_AMOUNT_REFUNDED'); ?></span>
669 </div>
670 <div class="vbo-booking-cost-val">
671 <span class="vbo-booking-cost-val-number">
672 <span class="vbo_currency<?php echo $extra_css; ?>"><?php echo $currencysymb; ?></span>
673 <span class="vbo_price<?php echo $extra_css; ?>"><?php echo VikBooking::numberFormat($ord['refund']); ?></span>
674 </span>
675 </div>
676 </div>
677 <?php
678 }
679 ?>
680 <div class="vbo-booking-cost-detail vbo-booking-cost-detail-total">
681 <div class="vbo-booking-cost-lbl">
682 <span><?php echo JText::translate('VBTOTAL'); ?></span>
683 </div>
684 <div class="vbo-booking-cost-val">
685 <span class="vbo-booking-cost-val-number">
686 <span class="vbo_currency<?php echo $extra_css; ?>"><?php echo $currencysymb; ?></span>
687 <span class="vbo_price<?php echo $extra_css; ?>"><?php echo VikBooking::numberFormat(($ord['status'] == 'confirmed' ? $ord['total'] : $isdue)); ?></span>
688 </span>
689 </div>
690 </div>
691 <?php
692 /**
693 * We allow the payment for confirmed bookings when a payment method is assigned, the configuration setting is enabled,
694 * the payment counter is greater than 0 (some tasks will force it to 1 when empty) and the amount paid is greater than
695 * zero but less than the total amount, or when the 'payable' property is greater than zero.
696 *
697 * @since 1.13 (J) - 1.3.0 (WP)
698 *
699 * We no longer need the payment counter to be greater than zero to allow a payment, as the payable amount can be defined by the admin.
700 *
701 * @since 1.14 (J) - 1.4.0 (WP)
702 *
703 * Some OTA bookings using an OTA-Collect business model may look as not entirely paid when they actually are, due to commissions.
704 * However, upselling events are taken into account in case a payable amount is set.
705 *
706 * @since 1.16.5 (J) - 1.6.5 (WP)
707 *
708 * Channels supporting payout notifications will not allow to pay the outstanding balance unless a payable amount is set.
709 *
710 * @since 1.16.9 (J) - 1.6.9 (WP)
711 */
712 $payable = (($ord['totpaid'] > 0.00 && $ord['totpaid'] < $ord['total'] && $ord['paymcount'] > 0) || $ord['payable'] > 0);
713 $ota_will_pay = false;
714 if ($payable && !empty($ord['idorderota']) && !empty($ord['channel']) && $ord['cmms'] && ($ord['total'] - $ord['totpaid'] - $ord['cmms']) < 1) {
715 // the difference of the amount paid is equal to the OTA commissions amount
716 $payable = false;
717 if ($ord['payable'] > 0 && $ord['total'] > $ord['totpaid'] && (int) ($ord['total'] - $ord['totpaid']) == (int) $ord['payable']) {
718 // there must have been an upselling event or a payment request
719 $payable = true;
720 }
721 }
722 if ($payable && $isotabooking && stripos($ord['channel'], 'airbnbapi') === 0 && !((float) $ord['payable'])) {
723 // access OTA payout events
724 $prev_ota_payments = VikBooking::getBookingHistoryInstance($ord['id'])
725 ->getEventsWithData('PO', null, false);
726 if (!$prev_ota_payments) {
727 // the OTA will pay the remaining balance
728 $payable = false;
729 $ota_will_pay = true;
730 }
731 }
732
733 if ($ord['status'] == 'confirmed' && is_array($payment) && VikBooking::multiplePayments() && $ord['total'] > 0 && $payable) {
734 // write again the payment form because the order was not fully paid
735
736 if (VBOPlatformDetection::isWordPress()) {
737 /**
738 * @wponly
739 *
740 * @since 1.0.5
741 */
742 $return_url = JUri::root() . "index.php?option=com_vikbooking&view=booking&sid=" . (!empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']) . "&ts=" . $ord['ts'];
743 $error_url = JUri::root() . "index.php?option=com_vikbooking&view=booking&sid=" . (!empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']) . "&ts=" . $ord['ts'];
744 $notify_url = JUri::root() . "index.php?option=com_vikbooking&task=notifypayment&sid=" . (!empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']) . "&ts=" . $ord['ts']."&tmpl=component";
745 /**
746 * @wponly the URLs must be routed differently for WP
747 */
748 $model = JModel::getInstance('vikbooking', 'shortcodes', 'admin');
749 $itemid = $model->best(array('booking'), (!empty($ord['lang']) ? $ord['lang'] : null));
750 if ($itemid) {
751 $return_url = str_replace(JUri::root(), '', $return_url);
752 $error_url = str_replace(JUri::root(), '', $error_url);
753 $notify_url = str_replace(JUri::root(), '', $notify_url);
754 $return_url = JRoute::rewrite($return_url . "&Itemid={$itemid}", false);
755 $error_url = JRoute::rewrite($error_url . "&Itemid={$itemid}", false);
756 $notify_url = JRoute::rewrite($notify_url . "&Itemid={$itemid}", false);
757 }
758 } else {
759 $return_url = VikBooking::externalroute("index.php?option=com_vikbooking&view=booking&sid=" . (!empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']) . "&ts=" . $ord['ts'], false, (!empty($bestitemid) ? $bestitemid : null));
760 $error_url = VikBooking::externalroute("index.php?option=com_vikbooking&view=booking&sid=" . (!empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']) . "&ts=" . $ord['ts'], false, (!empty($bestitemid) ? $bestitemid : null));
761 $notify_url = VikBooking::externalroute("index.php?option=com_vikbooking&task=notifypayment&sid=" . (!empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']) . "&ts=" . $ord['ts']."&tmpl=component", false, null);
762 }
763
764 $transaction_name = VikBooking::getPaymentName();
765 $remainingamount = $ord['payable'] > 0 ? $ord['payable'] : ($ord['total'] - $ord['totpaid']);
766 $leave_deposit = 0;
767 $percentdeposit = "";
768
769 $array_order = [];
770 $array_order['details'] = $ord;
771 if (empty($array_order['details']['sid']) && !empty($array_order['details']['idorderota']) && !empty($array_order['details']['channel'])) {
772 $array_order['details']['sid'] = $array_order['details']['idorderota'];
773 $ord['sid'] = $ord['idorderota'];
774 }
775 $array_order['customer_email'] = $ord['custmail'];
776 $array_order['account_name'] = VikBooking::getPaypalAcc();
777 $array_order['transaction_currency'] = VikBooking::getCurrencyCodePp();
778 $array_order['rooms_name'] = implode(", ", $roomsnames);
779 $array_order['transaction_name'] = !empty($transaction_name) ? $transaction_name : (JText::translate('VBORDERNUMBER') . ' ' . $ord['id']);
780 $array_order['order_total'] = $remainingamount;
781 $array_order['currency_symb'] = $currencysymb;
782 $array_order['net_price'] = $remainingamount;
783 $array_order['tax'] = 0;
784 $array_order['return_url'] = $return_url;
785 $array_order['error_url'] = $error_url;
786 $array_order['notify_url'] = $notify_url;
787 $array_order['total_to_pay'] = $remainingamount;
788 $array_order['total_net_price'] = $remainingamount;
789 $array_order['total_tax'] = 0;
790 $array_order['leave_deposit'] = $leave_deposit;
791 $array_order['percentdeposit'] = $percentdeposit;
792 $array_order['payment_info'] = $payment;
793 $array_order = array_merge($ord, $array_order);
794 ?>
795 <div class="vbo-booking-cost-detail vbo-booking-cost-detail-amountpaid">
796 <div class="vbo-booking-cost-lbl">
797 <span><?php echo JText::translate('VBAMOUNTPAID'); ?></span>
798 </div>
799 <div class="vbo-booking-cost-val">
800 <span class="vbo-booking-cost-val-number">
801 <span class="vbo_currency vbo_keepcost"><?php echo $currencysymb; ?></span>
802 <span class="vbo_price vbo_keepcost"><?php echo VikBooking::numberFormat($ord['totpaid']); ?></span>
803 </span>
804 </div>
805 </div>
806 <div class="vbo-booking-cost-detail vbo-booking-cost-detail-remainingbalance">
807 <div class="vbo-booking-cost-lbl">
808 <span><?php echo JText::translate('VBTOTALREMAINING'); ?></span>
809 </div>
810 <div class="vbo-booking-cost-val">
811 <span class="vbo-booking-cost-val-number">
812 <span class="vbo_currency vbo_keepcost"><?php echo $currencysymb; ?></span>
813 <span class="vbo_price vbo_keepcost"><?php echo VikBooking::numberFormat($remainingamount); ?></span>
814 </span>
815 </div>
816 </div>
817
818 <div class="vbvordpaybutton">
819 <?php
820 if (VBOPlatformDetection::isWordPress()) {
821 /**
822 * @wponly The payment gateway is now loaded
823 * using the apposite dispatcher.
824 *
825 * @since 1.0.5
826 */
827 JLoader::import('adapter.payment.dispatcher');
828
829 $obj = JPaymentDispatcher::getInstance('vikbooking', $payment['file'], $array_order, $payment['params']);
830 // remember to echo the payment
831 echo $obj->showPayment();
832 } else {
833 /**
834 * @joomlaonly The Payment Factory library will invoke the gateway.
835 *
836 * @since 1.14.3
837 */
838 require_once VBO_ADMIN_PATH . DIRECTORY_SEPARATOR . 'payments' . DIRECTORY_SEPARATOR . 'libraries' . DIRECTORY_SEPARATOR . 'factory.php';
839 $obj = VBOPaymentFactory::getPaymentInstance($payment['file'], $array_order, $payment['params']);
840
841 $obj->showPayment();
842 }
843 ?>
844 </div>
845 <?php
846 } elseif ($ord['status'] == 'confirmed') {
847 if ($ptmpl != 'component' && $ord['total'] > 0 && $ord['totpaid'] > 0.00 && $ord['totpaid'] < $ord['total']) {
848 $remainingamount = $ord['total'] - $ord['totpaid'];
849 ?>
850 <div class="vbo-booking-cost-detail vbo-booking-cost-detail-amountpaid">
851 <div class="vbo-booking-cost-lbl">
852 <span><?php echo JText::translate('VBAMOUNTPAID'); ?></span>
853 </div>
854 <div class="vbo-booking-cost-val">
855 <span class="vbo-booking-cost-val-number">
856 <span class="vbo_currency vbo_keepcost"><?php echo $currencysymb; ?></span>
857 <span class="vbo_price vbo_keepcost"><?php echo VikBooking::numberFormat($ord['totpaid']); ?></span>
858 </span>
859 </div>
860 </div>
861 <?php
862 if (!$ota_will_pay) {
863 ?>
864 <div class="vbo-booking-cost-detail vbo-booking-cost-detail-remainingbalance">
865 <div class="vbo-booking-cost-lbl">
866 <span><?php echo JText::translate('VBTOTALREMAINING'); ?></span>
867 </div>
868 <div class="vbo-booking-cost-val">
869 <span class="vbo-booking-cost-val-number">
870 <span class="vbo_currency vbo_keepcost"><?php echo $currencysymb; ?></span>
871 <span class="vbo_price vbo_keepcost"><?php echo VikBooking::numberFormat($remainingamount); ?></span>
872 </span>
873 </div>
874 </div>
875 <?php
876 }
877 }
878 if ($ptmpl == 'component') {
879 ?>
880 <script type="text/javascript">
881 window.print();
882 </script>
883 <?php
884 }
885 }
886
887 ?>
888 </div>
889 <?php
890
891 // booking modification/cancellation request, cancellation form or upsell animation
892 if (($ord['status'] == 'confirmed' && $resmodcanc > 0 && $this->days_to_arrival >= $resmodcancmin) || count($this->upselling)) {
893 ?>
894 <script type="text/javascript">
895 function vbOpenCancOrdForm() {
896 location.hash = 'bmodreqf';
897 document.getElementById('vbordcancformbox').style.display = 'block';
898 }
899 function vbValidateCancForm() {
900 if (!document.getElementById('vbcancemail').value.match(/\S/)) {
901 document.getElementById('vbformcancemail').style.color='#ff0000';
902 return false;
903 } else {
904 document.getElementById('vbformcancemail').style.color='';
905 }
906 if (!document.getElementById('vbcancreason').value.match(/\S/)) {
907 document.getElementById('vbformcancreason').style.color='#ff0000';
908 return false;
909 } else {
910 document.getElementById('vbformcancreason').style.color='';
911 }
912 return true;
913 }
914 function vbGotoUpsell() {
915 jQuery('html,body').animate({scrollTop: jQuery('.vbo-booking-upsell-container').offset().top - 20}, {duration: 400});
916 }
917 </script>
918 <?php
919 }
920 if ($ord['status'] == 'confirmed' && $resmodcanc === 1 && $this->days_to_arrival >= $resmodcancmin) {
921 ?>
922 <a name="bmodreqf"></a>
923 <div class="vbordcancformbox" id="vbordcancformbox">
924 <div class="vbo-booking-cancform-inner">
925 <h4><?php echo JText::translate('VBREQUESTCANCMOD'); ?></h4>
926 <form action="<?php echo JRoute::rewrite('index.php?option=com_vikbooking'.(!empty($pitemid) ? '&Itemid='.$pitemid : '')); ?>" name="vbcanc" method="post" onsubmit="javascript: return vbValidateCancForm();">
927 <div class="vbordcancform-inner">
928 <div class="vbordcancform-entry">
929 <div class="vbordcancform-entry-label">
930 <label for="vbcancemail" id="vbformcancemail"><?php echo JText::translate('VBREQUESTCANCMODEMAIL'); ?></label>
931 </div>
932 <div class="vbordcancform-entry-inp">
933 <input type="text" class="vbinput" name="email" id="vbcancemail" value="<?php echo $ord['custmail']; ?>"/>
934 </div>
935 </div>
936 <div class="vbordcancform-entry">
937 <div class="vbordcancform-entry-label">
938 <label for="vbcancreason" id="vbformcancreason"><?php echo JText::translate('VBREQUESTCANCMODREASON'); ?></label>
939 </div>
940 <div class="vbordcancform-entry-inp">
941 <textarea name="reason" id="vbcancreason" rows="7" cols="30" class="vbtextarea"></textarea>
942 </div>
943 </div>
944 <div class="vbordcancform-entry-submit">
945 <input type="submit" name="sendrequest" value="<?php echo JText::translate('VBREQUESTCANCMODSUBMIT'); ?>" class="btn vbo-pref-color-btn"/>
946 </div>
947 </div>
948 <?php
949 if (!empty($pitemid)) {
950 ?>
951 <input type="hidden" name="Itemid" value="<?php echo $pitemid; ?>"/>
952 <?php
953 }
954 ?>
955 <input type="hidden" name="sid" value="<?php echo $ord['sid']; ?>"/>
956 <input type="hidden" name="idorder" value="<?php echo $ord['id']; ?>"/>
957 <input type="hidden" name="option" value="com_vikbooking"/>
958 <input type="hidden" name="task" value="cancelrequest"/>
959 <?php echo JHtml::fetch('form.token'); ?>
960 </form>
961 </div>
962 </div>
963 <?php
964 }
965 //booking cancellation
966 if ($ord['status'] == 'confirmed' && $canc_allowed) {
967 ?>
968 <a name="bcancf"></a>
969 <div class="vbo-booking-cancform-container" id="vbo-booking-cancform-container" style="display: none;">
970 <div class="vbo-booking-cancform-inner">
971 <h4><?php echo JText::translate('VBOCANCYOURBOOKING'); ?></h4>
972 <div class="vbo-booking-cancform-details">
973 <div class="vbo-booking-canc-details-policy">
974 <?php echo $this->canc_policy; ?>
975 </div>
976 <form action="<?php echo JRoute::rewrite('index.php?option=com_vikbooking'.(!empty($pitemid) ? '&Itemid='.$pitemid : '')); ?>" name="vbcanc" method="post" onsubmit="javascript: return vbValidateCancForm();">
977 <div class="vbordcancform-inner vbo-booking-canc">
978 <div class="vbordcancform-entry">
979 <div class="vbordcancform-entry-label">
980 <label for="vbcancemail" id="vbformcancemail"><?php echo JText::translate('VBREQUESTCANCMODEMAIL'); ?></label>
981 </div>
982 <div class="vbordcancform-entry-inp">
983 <input type="text" class="vbinput" name="email" id="vbcancemail" value="<?php echo $ord['custmail']; ?>"/>
984 </div>
985 </div>
986 <div class="vbordcancform-entry">
987 <div class="vbordcancform-entry-label">
988 <label for="vbcancreason" id="vbformcancreason"><?php echo JText::translate('VBOCANCBOOKINGREASON'); ?></label>
989 </div>
990 <div class="vbordcancform-entry-inp">
991 <textarea name="reason" id="vbcancreason" rows="7" cols="30" class="vbtextarea"></textarea>
992 </div>
993 </div>
994 <div class="vbo-booking-canc-submit">
995 <input type="submit" name="sendrequest" value="<?php echo JText::translate('VBOCANCYOURBOOKING'); ?>" class="vbo-btn-cancelbooking"/>
996 </div>
997 </div>
998 <?php
999 if (!empty($pitemid)) {
1000 ?>
1001 <input type="hidden" name="Itemid" value="<?php echo $pitemid; ?>"/>
1002 <?php
1003 }
1004 ?>
1005 <input type="hidden" name="sid" value="<?php echo $ord['sid']; ?>"/>
1006 <input type="hidden" name="idorder" value="<?php echo $ord['id']; ?>"/>
1007 <input type="hidden" name="option" value="com_vikbooking"/>
1008 <input type="hidden" name="task" value="docancelbooking"/>
1009 <?php echo JHtml::fetch('form.token'); ?>
1010 </form>
1011 </div>
1012 </div>
1013 </div>
1014 <?php
1015 }
1016
1017 // stand-by booking payment rendering
1018 if (is_array($payment) && $ord['status'] == 'standby') {
1019 // render the selected payment method
1020 $lang = JFactory::getLanguage();
1021 $langtag = substr($lang->getTag(), 0, 2);
1022
1023 if (VBOPlatformDetection::isWordPress()) {
1024 /**
1025 * @wponly
1026 *
1027 * @since 1.0.5
1028 */
1029 $return_url = JUri::root() . "index.php?option=com_vikbooking&view=booking&sid=" . (!empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']) . "&ts=" . $ord['ts']."&lang=".$langtag;
1030 $error_url = JUri::root() . "index.php?option=com_vikbooking&view=booking&sid=" . (!empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']) . "&ts=" . $ord['ts']."&lang=".$langtag;
1031 $notify_url = JUri::root() . "index.php?option=com_vikbooking&task=notifypayment&sid=" . (!empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']) . "&ts=" . $ord['ts']."&lang=".$langtag."&tmpl=component";
1032 /**
1033 * @wponly the URLs must be routed differently for WP
1034 */
1035 $model = JModel::getInstance('vikbooking', 'shortcodes', 'admin');
1036 $itemid = $model->best(array('booking'), (!empty($ord['lang']) ? $ord['lang'] : null));
1037 if ($itemid) {
1038 $return_url = str_replace(JUri::root(), '', $return_url);
1039 $error_url = str_replace(JUri::root(), '', $error_url);
1040 $notify_url = str_replace(JUri::root(), '', $notify_url);
1041 $return_url = JRoute::rewrite($return_url . "&Itemid={$itemid}", false);
1042 $error_url = JRoute::rewrite($error_url . "&Itemid={$itemid}", false);
1043 $notify_url = JRoute::rewrite($notify_url . "&Itemid={$itemid}", false);
1044 }
1045 } else {
1046 $return_url = VikBooking::externalroute("index.php?option=com_vikbooking&view=booking&sid=" . (!empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']) . "&ts=" . $ord['ts'] ."&lang=" . $langtag, false, (!empty($bestitemid) ? $bestitemid : null));
1047 $error_url = VikBooking::externalroute("index.php?option=com_vikbooking&view=booking&sid=" . (!empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']) . "&ts=" . $ord['ts'] ."&lang=" . $langtag, false, (!empty($bestitemid) ? $bestitemid : null));
1048 $notify_url = VikBooking::externalroute("index.php?option=com_vikbooking&task=notifypayment&sid=" . (!empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']) . "&ts=" . $ord['ts'] . "&lang=" . $langtag . "&tmpl=component", false);
1049 }
1050
1051 $transaction_name = VikBooking::getPaymentName();
1052 $leave_deposit = 0;
1053 $percentdeposit = "";
1054
1055 $array_order = [];
1056 $array_order['details'] = $ord;
1057 if (empty($array_order['details']['sid']) && !empty($array_order['details']['idorderota']) && !empty($array_order['details']['channel'])) {
1058 $array_order['details']['sid'] = $array_order['details']['idorderota'];
1059 $ord['sid'] = $ord['idorderota'];
1060 }
1061 $array_order['customer_email'] = $ord['custmail'];
1062 $array_order['account_name'] = VikBooking::getPaypalAcc();
1063 $array_order['transaction_currency'] = VikBooking::getCurrencyCodePp();
1064 $array_order['rooms_name'] = implode(", ", $roomsnames);
1065 $array_order['transaction_name'] = !empty($transaction_name) ? $transaction_name : (JText::translate('VBORDERNUMBER') . ' ' . $ord['id']);
1066 $array_order['order_total'] = $isdue;
1067 $array_order['currency_symb'] = $currencysymb;
1068 $array_order['net_price'] = $imp;
1069 $array_order['tax'] = $tax;
1070 $array_order['return_url'] = $return_url;
1071 $array_order['error_url'] = $error_url;
1072 $array_order['notify_url'] = $notify_url;
1073 $array_order['total_to_pay'] = $isdue;
1074 $array_order['total_net_price'] = $imp;
1075 $array_order['total_tax'] = $tax;
1076 $totalchanged = false;
1077 if ($payment['charge'] > 0.00) {
1078 $totalchanged = true;
1079 if ($payment['ch_disc'] == 1) {
1080 //charge
1081 if ($payment['val_pcent'] == 1) {
1082 //fixed value
1083 $array_order['total_net_price'] += $payment['charge'];
1084 $array_order['total_tax'] += $payment['charge'];
1085 $array_order['total_to_pay'] += $payment['charge'];
1086 $newtotaltopay = $array_order['total_to_pay'];
1087 } else {
1088 //percent value
1089 $percent_net = $array_order['total_net_price'] * $payment['charge'] / 100;
1090 $percent_tax = $array_order['total_tax'] * $payment['charge'] / 100;
1091 $percent_to_pay = $array_order['total_to_pay'] * $payment['charge'] / 100;
1092 $array_order['total_net_price'] += $percent_net;
1093 $array_order['total_tax'] += $percent_tax;
1094 $array_order['total_to_pay'] += $percent_to_pay;
1095 $newtotaltopay = $array_order['total_to_pay'];
1096 }
1097 } else {
1098 //discount
1099 if ($payment['val_pcent'] == 1) {
1100 //fixed value
1101 $array_order['total_net_price'] -= $payment['charge'];
1102 $array_order['total_tax'] -= $payment['charge'];
1103 $array_order['total_to_pay'] -= $payment['charge'];
1104 $newtotaltopay = $array_order['total_to_pay'];
1105 } else {
1106 //percent value
1107 $percent_net = $array_order['total_net_price'] * $payment['charge'] / 100;
1108 $percent_tax = $array_order['total_tax'] * $payment['charge'] / 100;
1109 $percent_to_pay = $array_order['total_to_pay'] * $payment['charge'] / 100;
1110 $array_order['total_net_price'] -= $percent_net;
1111 $array_order['total_tax'] -= $percent_tax;
1112 $array_order['total_to_pay'] -= $percent_to_pay;
1113 $newtotaltopay = $array_order['total_to_pay'];
1114 }
1115 }
1116 }
1117 $percentdeposit = false;
1118 if (!VikBooking::payTotal() && $this->nodep != 1 && VikBooking::allowDepositFromRates($tars)) {
1119 $percentdeposit = VikBooking::getAccPerCent();
1120 $percentdeposit = VikBooking::calcDepositOverride($percentdeposit, $ord['days']);
1121 if ($percentdeposit > 0 && VikBooking::depositAllowedDaysAdv($ord['checkin'])) {
1122 $leave_deposit = 1;
1123 if (VikBooking::getTypeDeposit() == "fixed") {
1124 $array_order['total_to_pay'] = $percentdeposit;
1125 $array_order['total_net_price'] = $percentdeposit;
1126 $array_order['total_tax'] = ($array_order['total_to_pay'] - $array_order['total_net_price']);
1127 } else {
1128 $array_order['total_to_pay'] = $array_order['total_to_pay'] * $percentdeposit / 100;
1129 $array_order['total_net_price'] = $array_order['total_net_price'] * $percentdeposit / 100;
1130 $array_order['total_tax'] = ($array_order['total_to_pay'] - $array_order['total_net_price']);
1131 }
1132 }
1133 }
1134 $array_order['leave_deposit'] = $leave_deposit;
1135 $array_order['percentdeposit'] = $percentdeposit;
1136 $array_order['payment_info'] = $payment;
1137 $array_order = array_merge($ord, $array_order);
1138
1139 if (VBOPlatformDetection::isWordPress()) {
1140 $elapsed_redirect_uri = $return_url;
1141 } else {
1142 $elapsed_redirect_uri = JRoute::rewrite('index.php?option=com_vikbooking&view=booking&sid='.(!empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']).'&ts='.$ord['ts'].(!empty($bestitemid) ? '&Itemid='.$bestitemid : (!empty($pitemid) ? '&Itemid='.$pitemid : '')), false);
1143 }
1144
1145 //Auto Removal Minutes
1146 $minautoremove = VikBooking::getMinutesAutoRemove();
1147 $mins_elapsed = floor(($now_info[0] - $ord['ts']) / 60);
1148 if ($minautoremove > 0 && $minautoremove < 35791) {
1149 /**
1150 * Ensure the timeout milliseconds in 32-bit do not exceed
1151 * the maximum value of 2,147,483,647ms (~35791,39 minutes).
1152 *
1153 * @since 1.16.10 (J) - 1.6.10 (WP)
1154 */
1155 $booktime_info = getdate($ord['ts']);
1156 $booktime_offset = date('Z', $ord['ts']) / 60;
1157 $remainmin = $minautoremove - $mins_elapsed;
1158 $remainmin = $remainmin < 1 ? 1 : $remainmin;
1159 $remainmilsec = intval($remainmin * 60 * 1000) + 100;
1160 $remainmilsec = $remainmilsec < 100 ? 100 : $remainmilsec;
1161 //calculate the values for the timer
1162 $hours_left = $remainmin > 59 ? floor($remainmin / 60) : 0;
1163 $minutes_left = $remainmin - ($hours_left * 60);
1164 $lbl_hour = strtolower(JText::translate('VBHOUR'));
1165 $lbl_hours = strtolower(JText::translate('VBHOURS'));
1166 $lbl_minute = strtolower(JText::translate('VBMINUTE'));
1167 $lbl_minutes = strtolower(JText::translate('VBMINUTES'));
1168 $timer_str = $hours_left > 0 ? '<span id="vbo-timer-hours">'.$hours_left.' '.($hours_left == 1 ? $lbl_hour : $lbl_hours).'</span> ' : '';
1169 $timer_str .= '<span id="vbo-timer-minutes">'.$minutes_left.' '.($minutes_left == 1 ? $lbl_minute : $lbl_minutes).'</span>';
1170 ?>
1171 <script type="text/javascript">
1172 var vboPayTimerLbl = {
1173 "hour": "<?php echo addslashes($lbl_hour); ?>",
1174 "hours": "<?php echo addslashes($lbl_hours); ?>",
1175 "minute": "<?php echo addslashes($lbl_minute); ?>",
1176 "minutes": "<?php echo addslashes($lbl_minutes); ?>"
1177 }
1178 var vboPayTimeout = setTimeout(function() {
1179 document.location.href = '<?php echo $elapsed_redirect_uri; ?>';
1180 }, <?php echo $remainmilsec; ?>);
1181 var vboPayInterval = setInterval("vboRefreshPayTimer()", 60000);
1182 var vboBookInfo = new Date(<?php echo $booktime_info['year']; ?>, <?php echo ($booktime_info['mon'] - 1); ?>, <?php echo $booktime_info['mday']; ?>, <?php echo $booktime_info['hours']; ?>, <?php echo $booktime_info['minutes']; ?>, <?php echo $booktime_info['seconds']; ?>, 0);
1183 var vboPayTimerOffsetSet = false;
1184 function vboPauseTimeout() {
1185 clearTimeout(vboPayTimeout);
1186 }
1187 function vboRefreshPayTimer() {
1188 var vboNow = new Date();
1189 if (!vboPayTimerOffsetSet) {
1190 var tzoffset = vboNow.getTimezoneOffset() * -1 - <?php echo $booktime_offset; ?>;
1191 vboBookInfo.setMinutes(vboBookInfo.getMinutes() + tzoffset);
1192 vboPayTimerOffsetSet = true;
1193 }
1194
1195 var mins_elapsed = Math.floor((vboNow - vboBookInfo) / 1000 / 60);
1196 var remainmin = <?php echo $minautoremove; ?> - mins_elapsed;
1197 var hours_left = remainmin > 59 ? Math.floor(remainmin / 60) : 0;
1198 var minutes_left = remainmin - (hours_left * 60);
1199 if (hours_left < 1 && minutes_left < 1) {
1200 clearInterval(vboPayInterval);
1201 if (document.getElementById('vbo-timer-payment')) {
1202 document.getElementById('vbo-timer-payment').style.display = 'none';
1203 }
1204 return false;
1205 }
1206 if (document.getElementById('vbo-timer-hours')) {
1207 if (hours_left < 1) {
1208 document.getElementById('vbo-timer-hours').style.display = 'none';
1209 } else {
1210 document.getElementById('vbo-timer-hours').innerText = hours_left+' '+(hours_left == 1 ? vboPayTimerLbl['hour'] : vboPayTimerLbl['hours']);
1211 }
1212 }
1213 document.getElementById('vbo-timer-minutes').innerText = minutes_left+' '+(minutes_left == 1 ? vboPayTimerLbl['minute'] : vboPayTimerLbl['minutes']);
1214 }
1215 </script>
1216
1217 <div class="vbo-timer-payment" id="vbo-timer-payment">
1218 <span class="vbo-timer-payment-str">
1219 <?php echo JText::sprintf('VBOTIMERPAYMENTSTR', $timer_str); ?>
1220 </span>
1221 </div>
1222 <?php
1223 }
1224 //
1225
1226 ?>
1227 <div class="vbvordpaybutton">
1228 <?php
1229 if ($totalchanged) {
1230 $chdecimals = $payment['charge'] - (int)$payment['charge'];
1231 ?>
1232 <p class="vbpaymentchangetot">
1233 <span class="vbpaymentnamediff">
1234 <span><?php echo $payment['name']; ?></span>
1235 (<?php echo ($payment['ch_disc'] == 1 ? "+" : "-").($payment['val_pcent'] == 1 ? '<span class="vbo_currency">'.$currencysymb.'</span> ' : '').'<span class="vbo_price">'.VikBooking::numberFormat($payment['charge']).'</span>'.($payment['val_pcent'] == 1 ? '' : " %"); ?>)
1236 </span>
1237 <span class="vborddiffpayment"><span class="vbo_currency"><?php echo $currencysymb; ?></span> <span class="vbo_price"><?php echo VikBooking::numberFormat($newtotaltopay); ?></span></span>
1238 </p>
1239 <?php
1240 }
1241
1242 if (VBOPlatformDetection::isWordPress()) {
1243 /**
1244 * @wponly The payment gateway is now loaded
1245 * using the apposite dispatcher.
1246 *
1247 * @since 1.0.5
1248 */
1249 JLoader::import('adapter.payment.dispatcher');
1250
1251 $obj = JPaymentDispatcher::getInstance('vikbooking', $payment['file'], $array_order, $payment['params']);
1252 // remember to echo the payment
1253 echo $obj->showPayment();
1254 } else {
1255 /**
1256 * @joomlaonly The Payment Factory library will invoke the gateway.
1257 *
1258 * @since 1.14.3
1259 */
1260 require_once VBO_ADMIN_PATH . DIRECTORY_SEPARATOR . 'payments' . DIRECTORY_SEPARATOR . 'libraries' . DIRECTORY_SEPARATOR . 'factory.php';
1261 $obj = VBOPaymentFactory::getPaymentInstance($payment['file'], $array_order, $payment['params']);
1262
1263 $obj->showPayment();
1264 }
1265
1266 ?>
1267 </div>
1268 <?php
1269 }
1270
1271 /**
1272 * Booking review left by the guest
1273 *
1274 * @since 1.13
1275 */
1276 $review = VikBooking::getBookingReview($ord);
1277 if (is_array($review) && count($review)) {
1278 $rev_services = VikBooking::guestReviewsServices();
1279 $raw_rev_services = array();
1280 foreach ($rev_services as $sk => $sn) {
1281 $raw_rev_services[$sn['service_name']] = $sk;
1282 }
1283 // translate services
1284 $vbo_tn->translateContents($rev_services, '#__vikbooking_greview_service');
1285 ?>
1286 <div class="vbo-booking-guest-review">
1287 <div class="vbo-booking-guest-review-inner">
1288 <div class="vbo-booking-guest-review-top">
1289 <div class="vbo-booking-guest-review-time">
1290 <span><?php echo date(str_replace("/", $datesep, $df).' H:i', strtotime($review['dt'])); ?></span>
1291 </div>
1292 <div class="vbo-booking-guest-review-globalscore">
1293 <span><?php echo $review['score']; ?></span>
1294 </div>
1295 </div>
1296 <div class="vbo-booking-guest-review-bottom">
1297 <?php
1298 // scoring per service
1299 if (isset($review['content']['scoring']) && count($review['content']['scoring']) > 1) {
1300 // some services have been reviewed ("review_score" is always present)
1301 ?>
1302 <div class="vbo-booking-guest-review-services-score">
1303 <?php
1304 $counter = 0;
1305 foreach ($review['content']['scoring'] as $servicename => $servicescore) {
1306 if ($servicename == 'review_score') {
1307 // protected keyword for the global review score
1308 $counter++;
1309 continue;
1310 }
1311 $stars_count = floor($servicescore / 2);
1312 ?>
1313 <div class="vbo-booking-guest-review-service-score">
1314 <div class="vbo-booking-guest-review-service-score-inner">
1315 <div class="vbo-booking-guest-review-service-name">
1316 <span><?php echo isset($raw_rev_services[$servicename]) && isset($rev_services[$raw_rev_services[$servicename]]) ? $rev_services[$raw_rev_services[$servicename]]['service_name'] : ucwords(str_replace('_', ' ', $servicename)); ?></span>
1317 </div>
1318 <div class="vbo-booking-guest-review-service-stars">
1319 <?php
1320 for ($i = 1; $i <= $stars_count; $i++) {
1321 VikBookingIcons::e('star', 'vbo-review-star vbo-review-star-full');
1322 }
1323 for ($i = ($stars_count + 1); $i <= 5; $i++) {
1324 VikBookingIcons::e('star', 'vbo-review-star');
1325 }
1326 ?>
1327 </div>
1328 </div>
1329 </div>
1330 <?php
1331 $counter++;
1332 }
1333 ?>
1334 </div>
1335 <?php
1336 } elseif (isset($review['content']['scoring']) && isset($review['content']['scoring']['review_score'])) {
1337 // this is a global score for no services
1338 $stars_count = floor($review['content']['scoring']['review_score'] / 2);
1339 ?>
1340 <div class="vbo-booking-guest-review-services-score vbo-booking-guest-review-singleservice">
1341 <div class="vbo-booking-guest-review-service-name">
1342 <span><?php echo JText::translate('VBOREVIEWYOURRATING'); ?></span>
1343 </div>
1344 <div class="vbo-booking-guest-review-service-stars">
1345 <?php
1346 for ($i = 1; $i <= $stars_count; $i++) {
1347 VikBookingIcons::e('star', 'vbo-review-star vbo-review-star-full');
1348 }
1349 for ($i = ($stars_count + 1); $i <= 5; $i++) {
1350 VikBookingIcons::e('star', 'vbo-review-star');
1351 }
1352 ?>
1353 </div>
1354 </div>
1355 <?php
1356 }
1357 // guest review message
1358 if (isset($review['content']['content']) && !empty($review['content']['content']['message'])) {
1359 ?>
1360 <div class="vbo-booking-guest-review-message">
1361 <p><?php echo nl2br($review['content']['content']['message']); ?></p>
1362 </div>
1363 <?php
1364 }
1365 // owner reply
1366 if (isset($review['content']['reply']) && ((is_string($review['content']['reply']) && !empty($review['content']['reply'])) || (is_array($review['content']['reply']) && !empty($review['content']['reply']['text'])))) {
1367 $reply_text = is_array($review['content']['reply']) && isset($review['content']['reply']['text']) ? $review['content']['reply']['text'] : $review['content']['reply'];
1368 ?>
1369 <div class="vbo-booking-guest-review-owner-reply">
1370 <h5><?php echo JText::translate('VBOGREVOWNREPLY'); ?></h5>
1371 <p><?php echo nl2br($reply_text); ?></p>
1372 </div>
1373 <?php
1374 }
1375 ?>
1376 </div>
1377 </div>
1378 </div>
1379 <?php
1380 }
1381
1382 /**
1383 * Upselling Options/Extras block.
1384 *
1385 * @since 1.13 (J) - 1.3.0 (WP)
1386 */
1387 $tot_upselling = count($this->upselling);
1388 if ($tot_upselling) {
1389 // at least one room has options that can be up-sold
1390 $formatparts = explode(':', VikBooking::getNumberFormatData());
1391 ?>
1392 <div class="vbo-hidein-print vbo-booking-upsell-container">
1393 <h3><?php echo JText::translate('VBOUPSELLTITLE'); ?></h3>
1394 <form method="post" action="<?php echo JRoute::rewrite('index.php?option=com_vikbooking&task=upsellextras' . (!empty($pitemid) ? '&Itemid='.$pitemid : '')); ?>">
1395 <div class="vbo-booking-upsell-inner <?php echo $tot_upselling > 1 ? 'vbo-booking-upsell-inner-multi' : 'vbo-booking-upsell-inner-single'; ?>">
1396 <?php
1397 foreach ($this->upselling as $kor => $uproom) {
1398 if (!isset($uproom->upsellable) || !count($uproom->upsellable)) {
1399 // no upsellable options for this room
1400 continue;
1401 }
1402 ?>
1403 <div class="vbo-booking-upsell-room-wrap">
1404 <?php
1405 if ($tot_upselling > 1) {
1406 // write the room name and adults/children in case of multiple rooms booked
1407 ?>
1408 <h5 class="vbo-booking-upsell-room-details">
1409 <span class="vbo-booking-upsell-room-name"><?php echo $uproom->name; ?></span>
1410 <span class="vbo-booking-upsell-room-adults"><?php echo $uproom->adults; ?> <?php echo ($uproom->adults == 1 ? JText::translate('VBSEARCHRESADULT') : JText::translate('VBSEARCHRESADULTS')); ?></span>
1411 <?php
1412 if ($orderrooms[$kor]['children'] > 0) {
1413 ?>
1414 <span class="vbo-booking-upsell-room-children"><?php echo $orderrooms[$kor]['children'] . " " . ($orderrooms[$kor]['children'] == 1 ? JText::translate('VBSEARCHRESCHILD') : JText::translate('VBSEARCHRESCHILDREN')); ?></span>
1415 <?php
1416 }
1417 ?>
1418 </h5>
1419 <?php
1420 }
1421 ?>
1422 <div class="vbo-upsell-options-wrap">
1423 <?php
1424 // determine proper nights of stay
1425 $room_stay_nights = $ord['days'];
1426 if ($ord['split_stay'] && count($room_stay_dates) && isset($room_stay_dates[$kor]) && $room_stay_dates[$kor]['idroom'] == $uproom->id) {
1427 $room_stay_nights = $room_stay_dates[$kor]['nights'];
1428 }
1429
1430 foreach ($uproom->upsellable as $o) {
1431 if ((int)$o['pcentroom']) {
1432 // make sure we have a cost for the room, or we should skip this type of option for "incomplete" bookings
1433 if (!isset($orderrooms[$kor]) || (empty($orderrooms[$kor]['cust_cost']) && empty($orderrooms[$kor]['room_cost']))) {
1434 continue;
1435 }
1436 $o['cost'] = ((!empty($orderrooms[$kor]['cust_cost']) ? $orderrooms[$kor]['cust_cost'] : $orderrooms[$kor]['room_cost']) * $o['cost'] / 100);
1437 }
1438 $optcost = intval($o['perday']) == 1 ? ($o['cost'] * $room_stay_nights) : $o['cost'];
1439 if (!empty($o['maxprice']) && $o['maxprice'] > 0 && $optcost > $o['maxprice']) {
1440 $optcost = $o['maxprice'];
1441 }
1442 if ($o['perperson'] == 1) {
1443 $optcost = $optcost * $orderrooms[$kor]['adults'];
1444 }
1445 $optcost = $optcost * 1;
1446 $optquaninp = '';
1447 $optquanbtn = '';
1448 if (intval($o['hmany']) == 1) {
1449 if (intval($o['maxquant']) > 0) {
1450 $optquaninp = "<select id=\"vboaddextra-{$kor}-{$o['id']}\">\n";
1451 for ($ojj = 0; $ojj <= intval($o['maxquant']); $ojj++) {
1452 $optquaninp .= "<option value=\"" . $ojj . "\">" . $ojj . "</option>\n";
1453 }
1454 $optquaninp .= "</select>\n";
1455 } else {
1456 $optquaninp = "<input type=\"number\" min=\"0\" step=\"any\" id=\"vboaddextra-{$kor}-{$o['id']}\" value=\"0\" size=\"5\"/>";
1457 }
1458 $optquanbtn = '<button type="button" class="btn vbo-pref-color-btn" onclick="vboAddExtra(' . $kor . ', ' . $o['id'] . ', -1);"><i class="' . VikBookingIcons::i('cart-plus') . '"></i> ' . JText::translate('VBOUPSELLADD') . '</button>';
1459 } else {
1460 $optquanbtn = '<button type="button" class="btn vbo-pref-color-btn" onclick="vboAddExtra(' . $kor . ', ' . $o['id'] . ', 1);"><i class="' . VikBookingIcons::i('cart-plus') . '"></i> ' . JText::translate('VBOUPSELLADD') . '</button>';
1461 }
1462 ?>
1463 <div class="vbo-upsell-option-entry" id="vbo-option-upsell-<?php echo $kor . '-' . $o['id']; ?>">
1464 <?php
1465 if (!empty($o['img'])) {
1466 ?>
1467 <div class="vbo-upsell-option-entry-img">
1468 <?php echo '<img class="maxthirty" src="' . VBO_SITE_URI . 'resources/uploads/' . $o['img'] . '"/>'; ?>
1469 </div>
1470 <?php
1471 }
1472 ?>
1473 <div class="vbo-upsell-option-entry-name">
1474 <span><?php echo $o['name']; ?></span>
1475 <?php
1476 if (!empty($o['descr'])) {
1477 ?>
1478 <div class="vbo-upsell-option-entry-descr">
1479 <?php echo $o['descr']; ?>
1480 </div>
1481 <?php
1482 }
1483 $floatoptprice = VikBooking::sayOptionalsPlusIva($optcost, $o['idiva']);
1484 ?>
1485 </div>
1486 <div class="vbo-upsell-option-entry-cost" data-currency="<?php echo $currencysymb; ?>" data-floatprice="<?php echo (float)$floatoptprice; ?>">
1487 <span class="vbo_currency"><?php echo $currencysymb; ?></span>
1488 <span class="vbo_price"><?php echo VikBooking::numberFormat($floatoptprice); ?></span>
1489 </div>
1490 <div class="vbo-upsell-option-entry-input">
1491 <?php echo $optquaninp; ?>
1492 </div>
1493 <div class="vbo-option-upsell-add">
1494 <?php echo $optquanbtn; ?>
1495 </div>
1496 </div>
1497 <?php
1498 }
1499 ?>
1500 </div>
1501 <div class="vbo-room-upsell-cart" id="vbo-room-upsell-cart-<?php echo $kor; ?>"></div>
1502 </div>
1503 <?php
1504 }
1505 ?>
1506 </div>
1507 <input type="hidden" name="task" value="upsellextras">
1508 <input type="hidden" name="sid" value="<?php echo !empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']; ?>">
1509 <input type="hidden" name="ts" value="<?php echo $ord['ts']; ?>">
1510 <div class="vbo-booking-upsell-confirm" style="display: none;">
1511 <div class="vbo-booking-upsell-confirm-inner">
1512 <div class="vbo-booking-upsell-confirm-total">
1513 <span class="vbo-booking-upsell-confirm-txt"><?php echo JText::translate('VBTOTAL'); ?></span>
1514 <span class="vbo_currency vbo-booking-upsell-confirm-currency"><?php echo $currencysymb; ?></span>
1515 <span class="vbo_price vbo-booking-upsell-confirm-amount"></span>
1516 </div>
1517 <div class="vbo-booking-upsell-confirm-btn">
1518 <button type="submit" class="btn btn-large vbo-pref-color-btn" onclick="return confirm('<?php echo addslashes(JText::translate('VBOUPSELLCONFIRM')); ?>');"><?php VikBookingIcons::e('check-circle'); ?> <?php echo JText::translate('VBOUPSELLUPDATE'); ?></button>
1519 </div>
1520 </div>
1521 </div>
1522 </form>
1523 </div>
1524
1525 <script type="text/javascript">
1526 var vbototextras = 0;
1527 function vboAddExtra(kor, optid, quant) {
1528 if (quant < 0) {
1529 // get the quantity from the input/select tag
1530 quant = jQuery('#vboaddextra-' + kor + '-' + optid).val();
1531 if (!quant || isNaN(quant)) {
1532 console.error('input not found', kor, optid, quant);
1533 return false;
1534 }
1535 if (quant < 1) {
1536 alert('<?php echo addslashes(JText::translate('VBOUPSELLQUANTOPT0')); ?>');
1537 return false;
1538 }
1539 }
1540 var cartelem = jQuery('#vbo-room-upsell-option-' + kor + '-' + optid);
1541 if (cartelem.length) {
1542 // remove element from cart if already existed for later appending it to the cart again
1543 vboRemoveExtra(kor, optid);
1544 }
1545 // add element to the cart
1546 var optelem = jQuery('#vbo-option-upsell-' + kor + '-' + optid);
1547 if (!optelem.length) {
1548 console.error('option not found', kor, optid);
1549 return false;
1550 }
1551 // price
1552 var optprice = parseFloat(optelem.find('.vbo-upsell-option-entry-cost').attr('data-floatprice')) * quant;
1553 //
1554 var newcartelem = '<div class="vbo-room-upsell-cart-option" id="vbo-room-upsell-option-' + kor + '-' + optid + '" data-floatprice="' + optprice + '">';
1555 newcartelem += '<div class="vbo-room-upsell-cart-option-name">' + optelem.find('.vbo-upsell-option-entry-name span').text() + (quant > 1 ? ' (x' + quant + ')' : '') + '</div>';
1556 if (quant < 2) {
1557 // single quantity can take the formatted option price
1558 newcartelem += '<div class="vbo-room-upsell-cart-option-cost">' + optelem.find('.vbo-upsell-option-entry-cost').html() + '</div>';
1559 } else {
1560 // multiple quantities should multiply the single raw cost not formatted
1561 var optcurrency = optelem.find('.vbo-upsell-option-entry-cost').attr('data-currency');
1562 newcartelem += '<div class="vbo-room-upsell-cart-option-cost">' + optcurrency + ' ' + optprice.toFixed(<?php echo (int)$formatparts[0]; ?>) + '</div>';
1563 }
1564 // increase global total
1565 vbototextras += optprice;
1566 //
1567 newcartelem += '<div class="vbo-room-upsell-cart-option-rm"><button type="button" class="btn btn-danger" onclick="vboRemoveExtra(' + kor + ', ' + optid + ');"><i class="<?php echo VikBookingIcons::i('trash-alt'); ?>"></i></button></div>';
1568 // the necessary input field that will be submitted with the form
1569 newcartelem += '<input type="hidden" name="addopt[' + kor + '][' + optid + ']" value="' + quant + '"/>';
1570 //
1571 newcartelem += '</div>';
1572 // append new element to the cart and make sure the full class is set
1573 jQuery('#vbo-room-upsell-cart-' + kor).append(newcartelem).addClass('vbo-room-upsell-cart-full');
1574 // highlight the option so that we can see it was reserved by adding a class to the container
1575 optelem.addClass('vbo-option-upsell-addedtocart');
1576 // display the save button
1577 jQuery('.vbo-booking-upsell-confirm').fadeIn();
1578 // refresh total
1579 vboRefreshTotal();
1580 }
1581 function vboRemoveExtra(kor, optid) {
1582 var cartelem = jQuery('#vbo-room-upsell-option-' + kor + '-' + optid);
1583 if (!cartelem.length) {
1584 console.error('could not find option to remove from the cart', kor, optid);
1585 return false;
1586 }
1587 // decrease global total
1588 vbototextras -= parseFloat(cartelem.attr('data-floatprice'));
1589 //
1590 cartelem.remove();
1591 // remove class that highlights that the option was reserved
1592 jQuery('#vbo-option-upsell-' + kor + '-' + optid).removeClass('vbo-option-upsell-addedtocart');
1593 // check if the cart for this room is no longer full
1594 if (!jQuery('#vbo-room-upsell-cart-' + kor).find('.vbo-room-upsell-cart-option').length) {
1595 jQuery('#vbo-room-upsell-cart-' + kor).removeClass('vbo-room-upsell-cart-full');
1596 }
1597 // hide the save button if no options in the cart
1598 if (!jQuery('.vbo-room-upsell-cart-option').length) {
1599 jQuery('.vbo-booking-upsell-confirm').fadeOut();
1600 }
1601 // refresh total
1602 vboRefreshTotal();
1603 }
1604 function vboRefreshTotal() {
1605 jQuery('.vbo-booking-upsell-confirm-amount').text(vbototextras.toFixed(<?php echo (int)$formatparts[0]; ?>));
1606 }
1607 </script>
1608 <?php
1609 }
1610
1611 /**
1612 * Render the chat with the front-end handler 'vikbooking'.
1613 * OTA bookings cannot be displayed in front-end so we cannot
1614 * use any other chat handler. Chat can be disabled from config.
1615 * Using the chat via front-end imposes the guest to be the sender.
1616 *
1617 * @since 1.12 (J) - 1.1.7 (WP)
1618 */
1619 $messaging = null;
1620 if (VikBooking::chatEnabled() > 0) {
1621 // -1 means that VCM is not enabled
1622 $chat_available = true;
1623 // check if chat can still be displayed to the guest
1624 $chat_params = VikBooking::getChatParams();
1625 if (!isset($chat_params->res_status) || !in_array($ord['status'], $chat_params->res_status)) {
1626 // chat is disabled for this reservation status
1627 $chat_available = false;
1628 }
1629 if (isset($chat_params->av_type) && isset($chat_params->av_days)) {
1630 // check days of validity after checkin or checkout
1631 $chat_lim_ts = $chat_params->av_type == 'checkin' ? strtotime("+{$chat_params->av_days} days", $ord['checkin']) : strtotime("+{$chat_params->av_days} days", $ord['checkout']);
1632 // compare limits at midnight
1633 $now_midnight = mktime(0, 0, 0, date('n'), date('j'), date('Y'));
1634 $lim_midnight = mktime(0, 0, 0, date('n', $chat_lim_ts), date('j', $chat_lim_ts), date('Y', $chat_lim_ts));
1635 if ($now_midnight > $lim_midnight) {
1636 // limit date is in the past
1637 $chat_available = false;
1638 }
1639 }
1640 if ($chat_available) {
1641 // attempt to get the class instance
1642 $messaging = VikBooking::getVcmChatInstance($ord['id'], 'vikbooking');
1643 }
1644 }
1645 if (!is_null($messaging)) {
1646 $tot_unread = VCMChatHandler::countUnreadMessages($ord['id']);
1647 ?>
1648 <div class="vbo-booking-chat-wrap vbo-booking-chat-closed">
1649 <div class="vbo-booking-chat-inner">
1650 <div class="vbo-booking-chat-control" data-message-count="<?php echo $tot_unread; ?>"><?php VikBookingIcons::e('commenting'); ?></div>
1651 <div class="vbo-booking-chat-container" style="display: none;">
1652 <h4 class="vbo-booking-chat-intro"><?php echo JText::sprintf('VBOCHATWITH', VikBooking::getFrontTitle()); ?></h4>
1653 <?php echo $messaging->renderChat(); ?>
1654 </div>
1655 </div>
1656 </div>
1657 <script type="text/javascript">
1658 jQuery(function() {
1659 jQuery('.vbo-booking-chat-control').click(function() {
1660 jQuery(this).remove();
1661 jQuery('.vbo-booking-chat-wrap').removeClass('vbo-booking-chat-closed');
1662 jQuery('.vbo-booking-chat-container').fadeIn(400, function() {
1663 // animate to that position
1664 jQuery('html,body').animate({scrollTop: jQuery('.vbo-booking-chat-container').offset().top - 20}, {duration: 400});
1665 if (typeof VCMChat !== 'undefined') {
1666 VCMChat.getInstance().scrollToBottom();
1667 }
1668 });
1669 });
1670 jQuery(window).on('chatsync', function(e) {
1671 // VCMChat event listener to update notifications badge for new messages
1672 var newNotifications = e.detail.notifications;
1673 var currentMessages = parseInt(jQuery('.vbo-booking-chat-control').attr('data-message-count'));
1674 jQuery('.vbo-booking-chat-control').attr('data-message-count', (newNotifications + currentMessages));
1675 });
1676 });
1677 </script>
1678 <?php
1679 }
1680
1681 /**
1682 * If necessary, move the payment form onto the selected position.
1683 *
1684 * @since 1.14 (J) - 1.4.0 (WP)
1685 */
1686 if (is_array($this->payment) && $this->payment['outposition'] != 'bottom') {
1687 // move the payment window, if available
1688 ?>
1689 <script type="text/javascript">
1690
1691 jQuery(function() {
1692
1693 var payment_output = jQuery('.vbvordpaybutton').first(),
1694 payment_notes = jQuery('.vbvordpaynote').first(),
1695 payment_ctimer = jQuery('.vbo-timer-payment').first(),
1696 payment_wrappr = jQuery('.vbo-paycontainer-pos-<?php echo $this->payment['outposition']; ?>').first();
1697
1698 if (payment_output.length && payment_wrappr.length) {
1699 // display final target
1700 payment_wrappr.show();
1701
1702 if (payment_notes.length) {
1703 // prepend notes first
1704 payment_notes.prependTo(payment_wrappr);
1705 }
1706
1707 if (payment_ctimer.length) {
1708 // prepend countdown timer first
1709 payment_ctimer.prependTo(payment_wrappr);
1710 }
1711
1712 // append payment output
1713 payment_output.appendTo(payment_wrappr);
1714 }
1715
1716 });
1717
1718 </script>
1719 <?php
1720 }
1721 //
1722