PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.5
VikBooking Hotel Booking Engine & PMS v1.6.5
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.6.5, at site/views/booking/tmpl/default.php

1,690 lines 70.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 $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 (!count($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 *
705 * @since 1.16.5 (J) - 1.6.5 (WP)
706 */
707 $payable = (($ord['totpaid'] > 0.00 && $ord['totpaid'] < $ord['total'] && $ord['paymcount'] > 0) || $ord['payable'] > 0);
708 if ($payable && !empty($ord['idorderota']) && !empty($ord['channel']) && $ord['cmms'] && ($ord['total'] - $ord['totpaid'] - $ord['cmms']) < 1) {
709 // the difference of the amount paid is equal to the OTA commissions amount
710 $payable = false;
711 }
712
713 if ($ord['status'] == 'confirmed' && is_array($payment) && VikBooking::multiplePayments() && $ord['total'] > 0 && $payable) {
714 // write again the payment form because the order was not fully paid
715
716 if (VBOPlatformDetection::isWordPress()) {
717 /**
718 * @wponly
719 *
720 * @since 1.0.5
721 */
722 $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'];
723 $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'];
724 $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";
725 /**
726 * @wponly the URLs must be routed differently for WP
727 */
728 $model = JModel::getInstance('vikbooking', 'shortcodes', 'admin');
729 $itemid = $model->best(array('booking'), (!empty($ord['lang']) ? $ord['lang'] : null));
730 if ($itemid) {
731 $return_url = str_replace(JUri::root(), '', $return_url);
732 $error_url = str_replace(JUri::root(), '', $error_url);
733 $notify_url = str_replace(JUri::root(), '', $notify_url);
734 $return_url = JRoute::rewrite($return_url . "&Itemid={$itemid}", false);
735 $error_url = JRoute::rewrite($error_url . "&Itemid={$itemid}", false);
736 $notify_url = JRoute::rewrite($notify_url . "&Itemid={$itemid}", false);
737 }
738 } else {
739 $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));
740 $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));
741 $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);
742 }
743
744 $transaction_name = VikBooking::getPaymentName();
745 $remainingamount = $ord['payable'] > 0 ? $ord['payable'] : ($ord['total'] - $ord['totpaid']);
746 $leave_deposit = 0;
747 $percentdeposit = "";
748
749 $array_order = [];
750 $array_order['details'] = $ord;
751 if (empty($array_order['details']['sid']) && !empty($array_order['details']['idorderota']) && !empty($array_order['details']['channel'])) {
752 $array_order['details']['sid'] = $array_order['details']['idorderota'];
753 $ord['sid'] = $ord['idorderota'];
754 }
755 $array_order['customer_email'] = $ord['custmail'];
756 $array_order['account_name'] = VikBooking::getPaypalAcc();
757 $array_order['transaction_currency'] = VikBooking::getCurrencyCodePp();
758 $array_order['rooms_name'] = implode(", ", $roomsnames);
759 $array_order['transaction_name'] = !empty($transaction_name) ? $transaction_name : (JText::translate('VBORDERNUMBER') . ' ' . $ord['id']);
760 $array_order['order_total'] = $remainingamount;
761 $array_order['currency_symb'] = $currencysymb;
762 $array_order['net_price'] = $remainingamount;
763 $array_order['tax'] = 0;
764 $array_order['return_url'] = $return_url;
765 $array_order['error_url'] = $error_url;
766 $array_order['notify_url'] = $notify_url;
767 $array_order['total_to_pay'] = $remainingamount;
768 $array_order['total_net_price'] = $remainingamount;
769 $array_order['total_tax'] = 0;
770 $array_order['leave_deposit'] = $leave_deposit;
771 $array_order['percentdeposit'] = $percentdeposit;
772 $array_order['payment_info'] = $payment;
773 $array_order = array_merge($ord, $array_order);
774 ?>
775 <div class="vbo-booking-cost-detail vbo-booking-cost-detail-amountpaid">
776 <div class="vbo-booking-cost-lbl">
777 <span><?php echo JText::translate('VBAMOUNTPAID'); ?></span>
778 </div>
779 <div class="vbo-booking-cost-val">
780 <span class="vbo-booking-cost-val-number">
781 <span class="vbo_currency vbo_keepcost"><?php echo $currencysymb; ?></span>
782 <span class="vbo_price vbo_keepcost"><?php echo VikBooking::numberFormat($ord['totpaid']); ?></span>
783 </span>
784 </div>
785 </div>
786 <div class="vbo-booking-cost-detail vbo-booking-cost-detail-remainingbalance">
787 <div class="vbo-booking-cost-lbl">
788 <span><?php echo JText::translate('VBTOTALREMAINING'); ?></span>
789 </div>
790 <div class="vbo-booking-cost-val">
791 <span class="vbo-booking-cost-val-number">
792 <span class="vbo_currency vbo_keepcost"><?php echo $currencysymb; ?></span>
793 <span class="vbo_price vbo_keepcost"><?php echo VikBooking::numberFormat($remainingamount); ?></span>
794 </span>
795 </div>
796 </div>
797
798 <div class="vbvordpaybutton">
799 <?php
800 if (VBOPlatformDetection::isWordPress()) {
801 /**
802 * @wponly The payment gateway is now loaded
803 * using the apposite dispatcher.
804 *
805 * @since 1.0.5
806 */
807 JLoader::import('adapter.payment.dispatcher');
808
809 $obj = JPaymentDispatcher::getInstance('vikbooking', $payment['file'], $array_order, $payment['params']);
810 // remember to echo the payment
811 echo $obj->showPayment();
812 } else {
813 /**
814 * @joomlaonly The Payment Factory library will invoke the gateway.
815 *
816 * @since 1.14.3
817 */
818 require_once VBO_ADMIN_PATH . DIRECTORY_SEPARATOR . 'payments' . DIRECTORY_SEPARATOR . 'libraries' . DIRECTORY_SEPARATOR . 'factory.php';
819 $obj = VBOPaymentFactory::getPaymentInstance($payment['file'], $array_order, $payment['params']);
820
821 $obj->showPayment();
822 }
823 ?>
824 </div>
825 <?php
826 } elseif ($ord['status'] == 'confirmed') {
827 if ($ptmpl != 'component' && $ord['total'] > 0 && $ord['totpaid'] > 0.00 && $ord['totpaid'] < $ord['total']) {
828 $remainingamount = $ord['total'] - $ord['totpaid'];
829 ?>
830 <div class="vbo-booking-cost-detail vbo-booking-cost-detail-amountpaid">
831 <div class="vbo-booking-cost-lbl">
832 <span><?php echo JText::translate('VBAMOUNTPAID'); ?></span>
833 </div>
834 <div class="vbo-booking-cost-val">
835 <span class="vbo-booking-cost-val-number">
836 <span class="vbo_currency vbo_keepcost"><?php echo $currencysymb; ?></span>
837 <span class="vbo_price vbo_keepcost"><?php echo VikBooking::numberFormat($ord['totpaid']); ?></span>
838 </span>
839 </div>
840 </div>
841 <div class="vbo-booking-cost-detail vbo-booking-cost-detail-remainingbalance">
842 <div class="vbo-booking-cost-lbl">
843 <span><?php echo JText::translate('VBTOTALREMAINING'); ?></span>
844 </div>
845 <div class="vbo-booking-cost-val">
846 <span class="vbo-booking-cost-val-number">
847 <span class="vbo_currency vbo_keepcost"><?php echo $currencysymb; ?></span>
848 <span class="vbo_price vbo_keepcost"><?php echo VikBooking::numberFormat($remainingamount); ?></span>
849 </span>
850 </div>
851 </div>
852 <?php
853 }
854 if ($ptmpl == 'component') {
855 ?>
856 <script type="text/javascript">
857 window.print();
858 </script>
859 <?php
860 }
861 }
862
863 ?>
864 </div>
865 <?php
866
867 // booking modification/cancellation request, cancellation form or upsell animation
868 if (($ord['status'] == 'confirmed' && $resmodcanc > 0 && $this->days_to_arrival >= $resmodcancmin) || count($this->upselling)) {
869 ?>
870 <script type="text/javascript">
871 function vbOpenCancOrdForm() {
872 location.hash = 'bmodreqf';
873 document.getElementById('vbordcancformbox').style.display = 'block';
874 }
875 function vbValidateCancForm() {
876 if (!document.getElementById('vbcancemail').value.match(/\S/)) {
877 document.getElementById('vbformcancemail').style.color='#ff0000';
878 return false;
879 } else {
880 document.getElementById('vbformcancemail').style.color='';
881 }
882 if (!document.getElementById('vbcancreason').value.match(/\S/)) {
883 document.getElementById('vbformcancreason').style.color='#ff0000';
884 return false;
885 } else {
886 document.getElementById('vbformcancreason').style.color='';
887 }
888 return true;
889 }
890 function vbGotoUpsell() {
891 jQuery('html,body').animate({scrollTop: jQuery('.vbo-booking-upsell-container').offset().top - 20}, {duration: 400});
892 }
893 </script>
894 <?php
895 }
896 if ($ord['status'] == 'confirmed' && $resmodcanc === 1 && $this->days_to_arrival >= $resmodcancmin) {
897 ?>
898 <a name="bmodreqf"></a>
899 <div class="vbordcancformbox" id="vbordcancformbox">
900 <div class="vbo-booking-cancform-inner">
901 <h4><?php echo JText::translate('VBREQUESTCANCMOD'); ?></h4>
902 <form action="<?php echo JRoute::rewrite('index.php?option=com_vikbooking'.(!empty($pitemid) ? '&Itemid='.$pitemid : '')); ?>" name="vbcanc" method="post" onsubmit="javascript: return vbValidateCancForm();">
903 <div class="vbordcancform-inner">
904 <div class="vbordcancform-entry">
905 <div class="vbordcancform-entry-label">
906 <label for="vbcancemail" id="vbformcancemail"><?php echo JText::translate('VBREQUESTCANCMODEMAIL'); ?></label>
907 </div>
908 <div class="vbordcancform-entry-inp">
909 <input type="text" class="vbinput" name="email" id="vbcancemail" value="<?php echo $ord['custmail']; ?>"/>
910 </div>
911 </div>
912 <div class="vbordcancform-entry">
913 <div class="vbordcancform-entry-label">
914 <label for="vbcancreason" id="vbformcancreason"><?php echo JText::translate('VBREQUESTCANCMODREASON'); ?></label>
915 </div>
916 <div class="vbordcancform-entry-inp">
917 <textarea name="reason" id="vbcancreason" rows="7" cols="30" class="vbtextarea"></textarea>
918 </div>
919 </div>
920 <div class="vbordcancform-entry-submit">
921 <input type="submit" name="sendrequest" value="<?php echo JText::translate('VBREQUESTCANCMODSUBMIT'); ?>" class="btn vbo-pref-color-btn"/>
922 </div>
923 </div>
924 <?php
925 if (!empty($pitemid)) {
926 ?>
927 <input type="hidden" name="Itemid" value="<?php echo $pitemid; ?>"/>
928 <?php
929 }
930 ?>
931 <input type="hidden" name="sid" value="<?php echo $ord['sid']; ?>"/>
932 <input type="hidden" name="idorder" value="<?php echo $ord['id']; ?>"/>
933 <input type="hidden" name="option" value="com_vikbooking"/>
934 <input type="hidden" name="task" value="cancelrequest"/>
935 </form>
936 </div>
937 </div>
938 <?php
939 }
940 //booking cancellation
941 if ($ord['status'] == 'confirmed' && $canc_allowed) {
942 ?>
943 <a name="bcancf"></a>
944 <div class="vbo-booking-cancform-container" id="vbo-booking-cancform-container" style="display: none;">
945 <div class="vbo-booking-cancform-inner">
946 <h4><?php echo JText::translate('VBOCANCYOURBOOKING'); ?></h4>
947 <div class="vbo-booking-cancform-details">
948 <div class="vbo-booking-canc-details-policy">
949 <?php echo $this->canc_policy; ?>
950 </div>
951 <form action="<?php echo JRoute::rewrite('index.php?option=com_vikbooking'.(!empty($pitemid) ? '&Itemid='.$pitemid : '')); ?>" name="vbcanc" method="post" onsubmit="javascript: return vbValidateCancForm();">
952 <div class="vbordcancform-inner vbo-booking-canc">
953 <div class="vbordcancform-entry">
954 <div class="vbordcancform-entry-label">
955 <label for="vbcancemail" id="vbformcancemail"><?php echo JText::translate('VBREQUESTCANCMODEMAIL'); ?></label>
956 </div>
957 <div class="vbordcancform-entry-inp">
958 <input type="text" class="vbinput" name="email" id="vbcancemail" value="<?php echo $ord['custmail']; ?>"/>
959 </div>
960 </div>
961 <div class="vbordcancform-entry">
962 <div class="vbordcancform-entry-label">
963 <label for="vbcancreason" id="vbformcancreason"><?php echo JText::translate('VBOCANCBOOKINGREASON'); ?></label>
964 </div>
965 <div class="vbordcancform-entry-inp">
966 <textarea name="reason" id="vbcancreason" rows="7" cols="30" class="vbtextarea"></textarea>
967 </div>
968 </div>
969 <div class="vbo-booking-canc-submit">
970 <input type="submit" name="sendrequest" value="<?php echo JText::translate('VBOCANCYOURBOOKING'); ?>" class="vbo-btn-cancelbooking"/>
971 </div>
972 </div>
973 <?php
974 if (!empty($pitemid)) {
975 ?>
976 <input type="hidden" name="Itemid" value="<?php echo $pitemid; ?>"/>
977 <?php
978 }
979 ?>
980 <input type="hidden" name="sid" value="<?php echo $ord['sid']; ?>"/>
981 <input type="hidden" name="idorder" value="<?php echo $ord['id']; ?>"/>
982 <input type="hidden" name="option" value="com_vikbooking"/>
983 <input type="hidden" name="task" value="docancelbooking"/>
984 </form>
985 </div>
986 </div>
987 </div>
988 <?php
989 }
990
991 // stand-by booking payment rendering
992 if (is_array($payment) && $ord['status'] == 'standby') {
993 // render the selected payment method
994 $lang = JFactory::getLanguage();
995 $langtag = substr($lang->getTag(), 0, 2);
996
997 if (VBOPlatformDetection::isWordPress()) {
998 /**
999 * @wponly
1000 *
1001 * @since 1.0.5
1002 */
1003 $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;
1004 $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;
1005 $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";
1006 /**
1007 * @wponly the URLs must be routed differently for WP
1008 */
1009 $model = JModel::getInstance('vikbooking', 'shortcodes', 'admin');
1010 $itemid = $model->best(array('booking'), (!empty($ord['lang']) ? $ord['lang'] : null));
1011 if ($itemid) {
1012 $return_url = str_replace(JUri::root(), '', $return_url);
1013 $error_url = str_replace(JUri::root(), '', $error_url);
1014 $notify_url = str_replace(JUri::root(), '', $notify_url);
1015 $return_url = JRoute::rewrite($return_url . "&Itemid={$itemid}", false);
1016 $error_url = JRoute::rewrite($error_url . "&Itemid={$itemid}", false);
1017 $notify_url = JRoute::rewrite($notify_url . "&Itemid={$itemid}", false);
1018 }
1019 } else {
1020 $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));
1021 $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));
1022 $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);
1023 }
1024
1025 $transaction_name = VikBooking::getPaymentName();
1026 $leave_deposit = 0;
1027 $percentdeposit = "";
1028
1029 $array_order = [];
1030 $array_order['details'] = $ord;
1031 if (empty($array_order['details']['sid']) && !empty($array_order['details']['idorderota']) && !empty($array_order['details']['channel'])) {
1032 $array_order['details']['sid'] = $array_order['details']['idorderota'];
1033 $ord['sid'] = $ord['idorderota'];
1034 }
1035 $array_order['customer_email'] = $ord['custmail'];
1036 $array_order['account_name'] = VikBooking::getPaypalAcc();
1037 $array_order['transaction_currency'] = VikBooking::getCurrencyCodePp();
1038 $array_order['rooms_name'] = implode(", ", $roomsnames);
1039 $array_order['transaction_name'] = !empty($transaction_name) ? $transaction_name : (JText::translate('VBORDERNUMBER') . ' ' . $ord['id']);
1040 $array_order['order_total'] = $isdue;
1041 $array_order['currency_symb'] = $currencysymb;
1042 $array_order['net_price'] = $imp;
1043 $array_order['tax'] = $tax;
1044 $array_order['return_url'] = $return_url;
1045 $array_order['error_url'] = $error_url;
1046 $array_order['notify_url'] = $notify_url;
1047 $array_order['total_to_pay'] = $isdue;
1048 $array_order['total_net_price'] = $imp;
1049 $array_order['total_tax'] = $tax;
1050 $totalchanged = false;
1051 if ($payment['charge'] > 0.00) {
1052 $totalchanged = true;
1053 if ($payment['ch_disc'] == 1) {
1054 //charge
1055 if ($payment['val_pcent'] == 1) {
1056 //fixed value
1057 $array_order['total_net_price'] += $payment['charge'];
1058 $array_order['total_tax'] += $payment['charge'];
1059 $array_order['total_to_pay'] += $payment['charge'];
1060 $newtotaltopay = $array_order['total_to_pay'];
1061 } else {
1062 //percent value
1063 $percent_net = $array_order['total_net_price'] * $payment['charge'] / 100;
1064 $percent_tax = $array_order['total_tax'] * $payment['charge'] / 100;
1065 $percent_to_pay = $array_order['total_to_pay'] * $payment['charge'] / 100;
1066 $array_order['total_net_price'] += $percent_net;
1067 $array_order['total_tax'] += $percent_tax;
1068 $array_order['total_to_pay'] += $percent_to_pay;
1069 $newtotaltopay = $array_order['total_to_pay'];
1070 }
1071 } else {
1072 //discount
1073 if ($payment['val_pcent'] == 1) {
1074 //fixed value
1075 $array_order['total_net_price'] -= $payment['charge'];
1076 $array_order['total_tax'] -= $payment['charge'];
1077 $array_order['total_to_pay'] -= $payment['charge'];
1078 $newtotaltopay = $array_order['total_to_pay'];
1079 } else {
1080 //percent value
1081 $percent_net = $array_order['total_net_price'] * $payment['charge'] / 100;
1082 $percent_tax = $array_order['total_tax'] * $payment['charge'] / 100;
1083 $percent_to_pay = $array_order['total_to_pay'] * $payment['charge'] / 100;
1084 $array_order['total_net_price'] -= $percent_net;
1085 $array_order['total_tax'] -= $percent_tax;
1086 $array_order['total_to_pay'] -= $percent_to_pay;
1087 $newtotaltopay = $array_order['total_to_pay'];
1088 }
1089 }
1090 }
1091 $percentdeposit = false;
1092 if (!VikBooking::payTotal() && $this->nodep != 1 && VikBooking::allowDepositFromRates($tars)) {
1093 $percentdeposit = VikBooking::getAccPerCent();
1094 $percentdeposit = VikBooking::calcDepositOverride($percentdeposit, $ord['days']);
1095 if ($percentdeposit > 0 && VikBooking::depositAllowedDaysAdv($ord['checkin'])) {
1096 $leave_deposit = 1;
1097 if (VikBooking::getTypeDeposit() == "fixed") {
1098 $array_order['total_to_pay'] = $percentdeposit;
1099 $array_order['total_net_price'] = $percentdeposit;
1100 $array_order['total_tax'] = ($array_order['total_to_pay'] - $array_order['total_net_price']);
1101 } else {
1102 $array_order['total_to_pay'] = $array_order['total_to_pay'] * $percentdeposit / 100;
1103 $array_order['total_net_price'] = $array_order['total_net_price'] * $percentdeposit / 100;
1104 $array_order['total_tax'] = ($array_order['total_to_pay'] - $array_order['total_net_price']);
1105 }
1106 }
1107 }
1108 $array_order['leave_deposit'] = $leave_deposit;
1109 $array_order['percentdeposit'] = $percentdeposit;
1110 $array_order['payment_info'] = $payment;
1111 $array_order = array_merge($ord, $array_order);
1112
1113 if (VBOPlatformDetection::isWordPress()) {
1114 $elapsed_redirect_uri = $return_url;
1115 } else {
1116 $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);;
1117 }
1118
1119 //Auto Removal Minutes
1120 $minautoremove = VikBooking::getMinutesAutoRemove();
1121 $mins_elapsed = floor(($now_info[0] - $ord['ts']) / 60);
1122 if ($minautoremove > 0) {
1123 $booktime_info = getdate($ord['ts']);
1124 $booktime_offset = date('Z', $ord['ts']) / 60;
1125 $remainmin = $minautoremove - $mins_elapsed;
1126 $remainmin = $remainmin < 1 ? 1 : $remainmin;
1127 $remainmilsec = intval($remainmin * 60 * 1000) + 100;
1128 $remainmilsec = $remainmilsec < 100 ? 100 : $remainmilsec;
1129 //calculate the values for the timer
1130 $hours_left = $remainmin > 59 ? floor($remainmin / 60) : 0;
1131 $minutes_left = $remainmin - ($hours_left * 60);
1132 $lbl_hour = strtolower(JText::translate('VBHOUR'));
1133 $lbl_hours = strtolower(JText::translate('VBHOURS'));
1134 $lbl_minute = strtolower(JText::translate('VBMINUTE'));
1135 $lbl_minutes = strtolower(JText::translate('VBMINUTES'));
1136 $timer_str = $hours_left > 0 ? '<span id="vbo-timer-hours">'.$hours_left.' '.($hours_left == 1 ? $lbl_hour : $lbl_hours).'</span> ' : '';
1137 $timer_str .= '<span id="vbo-timer-minutes">'.$minutes_left.' '.($minutes_left == 1 ? $lbl_minute : $lbl_minutes).'</span>';
1138 ?>
1139 <script type="text/javascript">
1140 var vboPayTimerLbl = {
1141 "hour": "<?php echo addslashes($lbl_hour); ?>",
1142 "hours": "<?php echo addslashes($lbl_hours); ?>",
1143 "minute": "<?php echo addslashes($lbl_minute); ?>",
1144 "minutes": "<?php echo addslashes($lbl_minutes); ?>"
1145 }
1146 var vboPayTimeout = setTimeout(function() {
1147 document.location.href = '<?php echo $elapsed_redirect_uri; ?>';
1148 }, <?php echo $remainmilsec; ?>);
1149 var vboPayInterval = setInterval("vboRefreshPayTimer()", 60000);
1150 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);
1151 var vboPayTimerOffsetSet = false;
1152 function vboPauseTimeout() {
1153 clearTimeout(vboPayTimeout);
1154 }
1155 function vboRefreshPayTimer() {
1156 var vboNow = new Date();
1157 if (!vboPayTimerOffsetSet) {
1158 var tzoffset = vboNow.getTimezoneOffset() * -1 - <?php echo $booktime_offset; ?>;
1159 vboBookInfo.setMinutes(vboBookInfo.getMinutes() + tzoffset);
1160 vboPayTimerOffsetSet = true;
1161 }
1162
1163 var mins_elapsed = Math.floor((vboNow - vboBookInfo) / 1000 / 60);
1164 var remainmin = <?php echo $minautoremove; ?> - mins_elapsed;
1165 var hours_left = remainmin > 59 ? Math.floor(remainmin / 60) : 0;
1166 var minutes_left = remainmin - (hours_left * 60);
1167 if (hours_left < 1 && minutes_left < 1) {
1168 clearInterval(vboPayInterval);
1169 if (document.getElementById('vbo-timer-payment')) {
1170 document.getElementById('vbo-timer-payment').style.display = 'none';
1171 }
1172 return false;
1173 }
1174 if (document.getElementById('vbo-timer-hours')) {
1175 if (hours_left < 1) {
1176 document.getElementById('vbo-timer-hours').style.display = 'none';
1177 } else {
1178 document.getElementById('vbo-timer-hours').innerText = hours_left+' '+(hours_left == 1 ? vboPayTimerLbl['hour'] : vboPayTimerLbl['hours']);
1179 }
1180 }
1181 document.getElementById('vbo-timer-minutes').innerText = minutes_left+' '+(minutes_left == 1 ? vboPayTimerLbl['minute'] : vboPayTimerLbl['minutes']);
1182 }
1183 </script>
1184
1185 <div class="vbo-timer-payment" id="vbo-timer-payment">
1186 <span class="vbo-timer-payment-str">
1187 <?php echo JText::sprintf('VBOTIMERPAYMENTSTR', $timer_str); ?>
1188 </span>
1189 </div>
1190 <?php
1191 }
1192 //
1193
1194 ?>
1195 <div class="vbvordpaybutton">
1196 <?php
1197 if ($totalchanged) {
1198 $chdecimals = $payment['charge'] - (int)$payment['charge'];
1199 ?>
1200 <p class="vbpaymentchangetot">
1201 <span class="vbpaymentnamediff">
1202 <span><?php echo $payment['name']; ?></span>
1203 (<?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 ? '' : " %"); ?>)
1204 </span>
1205 <span class="vborddiffpayment"><span class="vbo_currency"><?php echo $currencysymb; ?></span> <span class="vbo_price"><?php echo VikBooking::numberFormat($newtotaltopay); ?></span></span>
1206 </p>
1207 <?php
1208 }
1209
1210 if (VBOPlatformDetection::isWordPress()) {
1211 /**
1212 * @wponly The payment gateway is now loaded
1213 * using the apposite dispatcher.
1214 *
1215 * @since 1.0.5
1216 */
1217 JLoader::import('adapter.payment.dispatcher');
1218
1219 $obj = JPaymentDispatcher::getInstance('vikbooking', $payment['file'], $array_order, $payment['params']);
1220 // remember to echo the payment
1221 echo $obj->showPayment();
1222 } else {
1223 /**
1224 * @joomlaonly The Payment Factory library will invoke the gateway.
1225 *
1226 * @since 1.14.3
1227 */
1228 require_once VBO_ADMIN_PATH . DIRECTORY_SEPARATOR . 'payments' . DIRECTORY_SEPARATOR . 'libraries' . DIRECTORY_SEPARATOR . 'factory.php';
1229 $obj = VBOPaymentFactory::getPaymentInstance($payment['file'], $array_order, $payment['params']);
1230
1231 $obj->showPayment();
1232 }
1233
1234 ?>
1235 </div>
1236 <?php
1237 }
1238
1239 /**
1240 * Booking review left by the guest
1241 *
1242 * @since 1.13
1243 */
1244 $review = VikBooking::getBookingReview($ord);
1245 if (is_array($review) && count($review)) {
1246 $rev_services = VikBooking::guestReviewsServices();
1247 $raw_rev_services = array();
1248 foreach ($rev_services as $sk => $sn) {
1249 $raw_rev_services[$sn['service_name']] = $sk;
1250 }
1251 // translate services
1252 $vbo_tn->translateContents($rev_services, '#__vikbooking_greview_service');
1253 ?>
1254 <div class="vbo-booking-guest-review">
1255 <div class="vbo-booking-guest-review-inner">
1256 <div class="vbo-booking-guest-review-top">
1257 <div class="vbo-booking-guest-review-time">
1258 <span><?php echo date(str_replace("/", $datesep, $df).' H:i', strtotime($review['dt'])); ?></span>
1259 </div>
1260 <div class="vbo-booking-guest-review-globalscore">
1261 <span><?php echo $review['score']; ?></span>
1262 </div>
1263 </div>
1264 <div class="vbo-booking-guest-review-bottom">
1265 <?php
1266 // scoring per service
1267 if (isset($review['content']['scoring']) && count($review['content']['scoring']) > 1) {
1268 // some services have been reviewed ("review_score" is always present)
1269 ?>
1270 <div class="vbo-booking-guest-review-services-score">
1271 <?php
1272 $counter = 0;
1273 foreach ($review['content']['scoring'] as $servicename => $servicescore) {
1274 if ($servicename == 'review_score') {
1275 // protected keyword for the global review score
1276 $counter++;
1277 continue;
1278 }
1279 $stars_count = floor($servicescore / 2);
1280 ?>
1281 <div class="vbo-booking-guest-review-service-score">
1282 <div class="vbo-booking-guest-review-service-score-inner">
1283 <div class="vbo-booking-guest-review-service-name">
1284 <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>
1285 </div>
1286 <div class="vbo-booking-guest-review-service-stars">
1287 <?php
1288 for ($i = 1; $i <= $stars_count; $i++) {
1289 VikBookingIcons::e('star', 'vbo-review-star vbo-review-star-full');
1290 }
1291 for ($i = ($stars_count + 1); $i <= 5; $i++) {
1292 VikBookingIcons::e('star', 'vbo-review-star');
1293 }
1294 ?>
1295 </div>
1296 </div>
1297 </div>
1298 <?php
1299 $counter++;
1300 }
1301 ?>
1302 </div>
1303 <?php
1304 } elseif (isset($review['content']['scoring']) && isset($review['content']['scoring']['review_score'])) {
1305 // this is a global score for no services
1306 $stars_count = floor($review['content']['scoring']['review_score'] / 2);
1307 ?>
1308 <div class="vbo-booking-guest-review-services-score vbo-booking-guest-review-singleservice">
1309 <div class="vbo-booking-guest-review-service-name">
1310 <span><?php echo JText::translate('VBOREVIEWYOURRATING'); ?></span>
1311 </div>
1312 <div class="vbo-booking-guest-review-service-stars">
1313 <?php
1314 for ($i = 1; $i <= $stars_count; $i++) {
1315 VikBookingIcons::e('star', 'vbo-review-star vbo-review-star-full');
1316 }
1317 for ($i = ($stars_count + 1); $i <= 5; $i++) {
1318 VikBookingIcons::e('star', 'vbo-review-star');
1319 }
1320 ?>
1321 </div>
1322 </div>
1323 <?php
1324 }
1325 // guest review message
1326 if (isset($review['content']['content']) && !empty($review['content']['content']['message'])) {
1327 ?>
1328 <div class="vbo-booking-guest-review-message">
1329 <p><?php echo nl2br($review['content']['content']['message']); ?></p>
1330 </div>
1331 <?php
1332 }
1333 // owner reply
1334 if (isset($review['content']['reply']) && ((is_string($review['content']['reply']) && !empty($review['content']['reply'])) || (is_array($review['content']['reply']) && !empty($review['content']['reply']['text'])))) {
1335 $reply_text = is_array($review['content']['reply']) && isset($review['content']['reply']['text']) ? $review['content']['reply']['text'] : $review['content']['reply'];
1336 ?>
1337 <div class="vbo-booking-guest-review-owner-reply">
1338 <h5><?php echo JText::translate('VBOGREVOWNREPLY'); ?></h5>
1339 <p><?php echo nl2br($reply_text); ?></p>
1340 </div>
1341 <?php
1342 }
1343 ?>
1344 </div>
1345 </div>
1346 </div>
1347 <?php
1348 }
1349
1350 /**
1351 * Upselling Options/Extras block.
1352 *
1353 * @since 1.13 (J) - 1.3.0 (WP)
1354 */
1355 $tot_upselling = count($this->upselling);
1356 if ($tot_upselling) {
1357 // at least one room has options that can be up-sold
1358 $formatparts = explode(':', VikBooking::getNumberFormatData());
1359 ?>
1360 <div class="vbo-hidein-print vbo-booking-upsell-container">
1361 <h3><?php echo JText::translate('VBOUPSELLTITLE'); ?></h3>
1362 <form method="post" action="<?php echo JRoute::rewrite('index.php?option=com_vikbooking&task=upsellextras' . (!empty($pitemid) ? '&Itemid='.$pitemid : '')); ?>">
1363 <div class="vbo-booking-upsell-inner <?php echo $tot_upselling > 1 ? 'vbo-booking-upsell-inner-multi' : 'vbo-booking-upsell-inner-single'; ?>">
1364 <?php
1365 foreach ($this->upselling as $kor => $uproom) {
1366 if (!isset($uproom->upsellable) || !count($uproom->upsellable)) {
1367 // no upsellable options for this room
1368 continue;
1369 }
1370 ?>
1371 <div class="vbo-booking-upsell-room-wrap">
1372 <?php
1373 if ($tot_upselling > 1) {
1374 // write the room name and adults/children in case of multiple rooms booked
1375 ?>
1376 <h5 class="vbo-booking-upsell-room-details">
1377 <span class="vbo-booking-upsell-room-name"><?php echo $uproom->name; ?></span>
1378 <span class="vbo-booking-upsell-room-adults"><?php echo $uproom->adults; ?> <?php echo ($uproom->adults == 1 ? JText::translate('VBSEARCHRESADULT') : JText::translate('VBSEARCHRESADULTS')); ?></span>
1379 <?php
1380 if ($orderrooms[$kor]['children'] > 0) {
1381 ?>
1382 <span class="vbo-booking-upsell-room-children"><?php echo $orderrooms[$kor]['children'] . " " . ($orderrooms[$kor]['children'] == 1 ? JText::translate('VBSEARCHRESCHILD') : JText::translate('VBSEARCHRESCHILDREN')); ?></span>
1383 <?php
1384 }
1385 ?>
1386 </h5>
1387 <?php
1388 }
1389 ?>
1390 <div class="vbo-upsell-options-wrap">
1391 <?php
1392 // determine proper nights of stay
1393 $room_stay_nights = $ord['days'];
1394 if ($ord['split_stay'] && count($room_stay_dates) && isset($room_stay_dates[$kor]) && $room_stay_dates[$kor]['idroom'] == $uproom->id) {
1395 $room_stay_nights = $room_stay_dates[$kor]['nights'];
1396 }
1397
1398 foreach ($uproom->upsellable as $o) {
1399 if ((int)$o['pcentroom']) {
1400 // make sure we have a cost for the room, or we should skip this type of option for "incomplete" bookings
1401 if (!isset($orderrooms[$kor]) || (empty($orderrooms[$kor]['cust_cost']) && empty($orderrooms[$kor]['room_cost']))) {
1402 continue;
1403 }
1404 $o['cost'] = ((!empty($orderrooms[$kor]['cust_cost']) ? $orderrooms[$kor]['cust_cost'] : $orderrooms[$kor]['room_cost']) * $o['cost'] / 100);
1405 }
1406 $optcost = intval($o['perday']) == 1 ? ($o['cost'] * $room_stay_nights) : $o['cost'];
1407 if (!empty($o['maxprice']) && $o['maxprice'] > 0 && $optcost > $o['maxprice']) {
1408 $optcost = $o['maxprice'];
1409 }
1410 if ($o['perperson'] == 1) {
1411 $optcost = $optcost * $orderrooms[$kor]['adults'];
1412 }
1413 $optcost = $optcost * 1;
1414 $optquaninp = '';
1415 $optquanbtn = '';
1416 if (intval($o['hmany']) == 1) {
1417 if (intval($o['maxquant']) > 0) {
1418 $optquaninp = "<select id=\"vboaddextra-{$kor}-{$o['id']}\">\n";
1419 for ($ojj = 0; $ojj <= intval($o['maxquant']); $ojj++) {
1420 $optquaninp .= "<option value=\"" . $ojj . "\">" . $ojj . "</option>\n";
1421 }
1422 $optquaninp .= "</select>\n";
1423 } else {
1424 $optquaninp = "<input type=\"number\" min=\"0\" step=\"any\" id=\"vboaddextra-{$kor}-{$o['id']}\" value=\"0\" size=\"5\"/>";
1425 }
1426 $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>';
1427 } else {
1428 $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>';
1429 }
1430 ?>
1431 <div class="vbo-upsell-option-entry" id="vbo-option-upsell-<?php echo $kor . '-' . $o['id']; ?>">
1432 <?php
1433 if (!empty($o['img'])) {
1434 ?>
1435 <div class="vbo-upsell-option-entry-img">
1436 <?php echo '<img class="maxthirty" src="' . VBO_SITE_URI . 'resources/uploads/' . $o['img'] . '"/>'; ?>
1437 </div>
1438 <?php
1439 }
1440 ?>
1441 <div class="vbo-upsell-option-entry-name">
1442 <span><?php echo $o['name']; ?></span>
1443 <?php
1444 if (!empty($o['descr'])) {
1445 ?>
1446 <div class="vbo-upsell-option-entry-descr">
1447 <?php echo $o['descr']; ?>
1448 </div>
1449 <?php
1450 }
1451 $floatoptprice = VikBooking::sayOptionalsPlusIva($optcost, $o['idiva']);
1452 ?>
1453 </div>
1454 <div class="vbo-upsell-option-entry-cost" data-currency="<?php echo $currencysymb; ?>" data-floatprice="<?php echo (float)$floatoptprice; ?>">
1455 <span class="vbo_currency"><?php echo $currencysymb; ?></span>
1456 <span class="vbo_price"><?php echo VikBooking::numberFormat($floatoptprice); ?></span>
1457 </div>
1458 <div class="vbo-upsell-option-entry-input">
1459 <?php echo $optquaninp; ?>
1460 </div>
1461 <div class="vbo-option-upsell-add">
1462 <?php echo $optquanbtn; ?>
1463 </div>
1464 </div>
1465 <?php
1466 }
1467 ?>
1468 </div>
1469 <div class="vbo-room-upsell-cart" id="vbo-room-upsell-cart-<?php echo $kor; ?>"></div>
1470 </div>
1471 <?php
1472 }
1473 ?>
1474 </div>
1475 <input type="hidden" name="task" value="upsellextras">
1476 <input type="hidden" name="sid" value="<?php echo !empty($ord['idorderota']) && !empty($ord['channel']) ? $ord['idorderota'] : $ord['sid']; ?>">
1477 <input type="hidden" name="ts" value="<?php echo $ord['ts']; ?>">
1478 <div class="vbo-booking-upsell-confirm" style="display: none;">
1479 <div class="vbo-booking-upsell-confirm-inner">
1480 <div class="vbo-booking-upsell-confirm-total">
1481 <span class="vbo-booking-upsell-confirm-txt"><?php echo JText::translate('VBTOTAL'); ?></span>
1482 <span class="vbo_currency vbo-booking-upsell-confirm-currency"><?php echo $currencysymb; ?></span>
1483 <span class="vbo_price vbo-booking-upsell-confirm-amount"></span>
1484 </div>
1485 <div class="vbo-booking-upsell-confirm-btn">
1486 <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>
1487 </div>
1488 </div>
1489 </div>
1490 </form>
1491 </div>
1492
1493 <script type="text/javascript">
1494 var vbototextras = 0;
1495 function vboAddExtra(kor, optid, quant) {
1496 if (quant < 0) {
1497 // get the quantity from the input/select tag
1498 quant = jQuery('#vboaddextra-' + kor + '-' + optid).val();
1499 if (!quant || isNaN(quant)) {
1500 console.error('input not found', kor, optid, quant);
1501 return false;
1502 }
1503 if (quant < 1) {
1504 alert('<?php echo addslashes(JText::translate('VBOUPSELLQUANTOPT0')); ?>');
1505 return false;
1506 }
1507 }
1508 var cartelem = jQuery('#vbo-room-upsell-option-' + kor + '-' + optid);
1509 if (cartelem.length) {
1510 // remove element from cart if already existed for later appending it to the cart again
1511 vboRemoveExtra(kor, optid);
1512 }
1513 // add element to the cart
1514 var optelem = jQuery('#vbo-option-upsell-' + kor + '-' + optid);
1515 if (!optelem.length) {
1516 console.error('option not found', kor, optid);
1517 return false;
1518 }
1519 // price
1520 var optprice = parseFloat(optelem.find('.vbo-upsell-option-entry-cost').attr('data-floatprice')) * quant;
1521 //
1522 var newcartelem = '<div class="vbo-room-upsell-cart-option" id="vbo-room-upsell-option-' + kor + '-' + optid + '" data-floatprice="' + optprice + '">';
1523 newcartelem += '<div class="vbo-room-upsell-cart-option-name">' + optelem.find('.vbo-upsell-option-entry-name span').text() + (quant > 1 ? ' (x' + quant + ')' : '') + '</div>';
1524 if (quant < 2) {
1525 // single quantity can take the formatted option price
1526 newcartelem += '<div class="vbo-room-upsell-cart-option-cost">' + optelem.find('.vbo-upsell-option-entry-cost').html() + '</div>';
1527 } else {
1528 // multiple quantities should multiply the single raw cost not formatted
1529 var optcurrency = optelem.find('.vbo-upsell-option-entry-cost').attr('data-currency');
1530 newcartelem += '<div class="vbo-room-upsell-cart-option-cost">' + optcurrency + ' ' + optprice.toFixed(<?php echo (int)$formatparts[0]; ?>) + '</div>';
1531 }
1532 // increase global total
1533 vbototextras += optprice;
1534 //
1535 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>';
1536 // the necessary input field that will be submitted with the form
1537 newcartelem += '<input type="hidden" name="addopt[' + kor + '][' + optid + ']" value="' + quant + '"/>';
1538 //
1539 newcartelem += '</div>';
1540 // append new element to the cart and make sure the full class is set
1541 jQuery('#vbo-room-upsell-cart-' + kor).append(newcartelem).addClass('vbo-room-upsell-cart-full');
1542 // highlight the option so that we can see it was reserved by adding a class to the container
1543 optelem.addClass('vbo-option-upsell-addedtocart');
1544 // display the save button
1545 jQuery('.vbo-booking-upsell-confirm').fadeIn();
1546 // refresh total
1547 vboRefreshTotal();
1548 }
1549 function vboRemoveExtra(kor, optid) {
1550 var cartelem = jQuery('#vbo-room-upsell-option-' + kor + '-' + optid);
1551 if (!cartelem.length) {
1552 console.error('could not find option to remove from the cart', kor, optid);
1553 return false;
1554 }
1555 // decrease global total
1556 vbototextras -= parseFloat(cartelem.attr('data-floatprice'));
1557 //
1558 cartelem.remove();
1559 // remove class that highlights that the option was reserved
1560 jQuery('#vbo-option-upsell-' + kor + '-' + optid).removeClass('vbo-option-upsell-addedtocart');
1561 // check if the cart for this room is no longer full
1562 if (!jQuery('#vbo-room-upsell-cart-' + kor).find('.vbo-room-upsell-cart-option').length) {
1563 jQuery('#vbo-room-upsell-cart-' + kor).removeClass('vbo-room-upsell-cart-full');
1564 }
1565 // hide the save button if no options in the cart
1566 if (!jQuery('.vbo-room-upsell-cart-option').length) {
1567 jQuery('.vbo-booking-upsell-confirm').fadeOut();
1568 }
1569 // refresh total
1570 vboRefreshTotal();
1571 }
1572 function vboRefreshTotal() {
1573 jQuery('.vbo-booking-upsell-confirm-amount').text(vbototextras.toFixed(<?php echo (int)$formatparts[0]; ?>));
1574 }
1575 </script>
1576 <?php
1577 }
1578
1579 /**
1580 * Render the chat with the front-end handler 'vikbooking'.
1581 * OTA bookings cannot be displayed in front-end so we cannot
1582 * use any other chat handler. Chat can be disabled from config.
1583 * Using the chat via front-end imposes the guest to be the sender.
1584 *
1585 * @since 1.12 (J) - 1.1.7 (WP)
1586 */
1587 $messaging = null;
1588 if (VikBooking::chatEnabled() > 0) {
1589 // -1 means that VCM is not enabled
1590 $chat_available = true;
1591 // check if chat can still be displayed to the guest
1592 $chat_params = VikBooking::getChatParams();
1593 if (!isset($chat_params->res_status) || !in_array($ord['status'], $chat_params->res_status)) {
1594 // chat is disabled for this reservation status
1595 $chat_available = false;
1596 }
1597 if (isset($chat_params->av_type) && isset($chat_params->av_days)) {
1598 // check days of validity after checkin or checkout
1599 $chat_lim_ts = $chat_params->av_type == 'checkin' ? strtotime("+{$chat_params->av_days} days", $ord['checkin']) : strtotime("+{$chat_params->av_days} days", $ord['checkout']);
1600 // compare limits at midnight
1601 $now_midnight = mktime(0, 0, 0, date('n'), date('j'), date('Y'));
1602 $lim_midnight = mktime(0, 0, 0, date('n', $chat_lim_ts), date('j', $chat_lim_ts), date('Y', $chat_lim_ts));
1603 if ($now_midnight > $lim_midnight) {
1604 // limit date is in the past
1605 $chat_available = false;
1606 }
1607 }
1608 if ($chat_available) {
1609 // attempt to get the class instance
1610 $messaging = VikBooking::getVcmChatInstance($ord['id'], 'vikbooking');
1611 }
1612 }
1613 if (!is_null($messaging)) {
1614 $tot_unread = VCMChatHandler::countUnreadMessages($ord['id']);
1615 ?>
1616 <div class="vbo-booking-chat-wrap vbo-booking-chat-closed">
1617 <div class="vbo-booking-chat-inner">
1618 <div class="vbo-booking-chat-control" data-message-count="<?php echo $tot_unread; ?>"><?php VikBookingIcons::e('commenting'); ?></div>
1619 <div class="vbo-booking-chat-container" style="display: none;">
1620 <h4 class="vbo-booking-chat-intro"><?php echo JText::sprintf('VBOCHATWITH', VikBooking::getFrontTitle()); ?></h4>
1621 <?php echo $messaging->renderChat(); ?>
1622 </div>
1623 </div>
1624 </div>
1625 <script type="text/javascript">
1626 jQuery(function() {
1627 jQuery('.vbo-booking-chat-control').click(function() {
1628 jQuery(this).remove();
1629 jQuery('.vbo-booking-chat-wrap').removeClass('vbo-booking-chat-closed');
1630 jQuery('.vbo-booking-chat-container').fadeIn(400, function() {
1631 // animate to that position
1632 jQuery('html,body').animate({scrollTop: jQuery('.vbo-booking-chat-container').offset().top - 20}, {duration: 400});
1633 if (typeof VCMChat !== 'undefined') {
1634 VCMChat.getInstance().scrollToBottom();
1635 }
1636 });
1637 });
1638 jQuery(window).on('chatsync', function(e) {
1639 // VCMChat event listener to update notifications badge for new messages
1640 var newNotifications = e.detail.notifications;
1641 var currentMessages = parseInt(jQuery('.vbo-booking-chat-control').attr('data-message-count'));
1642 jQuery('.vbo-booking-chat-control').attr('data-message-count', (newNotifications + currentMessages));
1643 });
1644 });
1645 </script>
1646 <?php
1647 }
1648
1649 /**
1650 * If necessary, move the payment form onto the selected position.
1651 *
1652 * @since 1.14 (J) - 1.4.0 (WP)
1653 */
1654 if (is_array($this->payment) && $this->payment['outposition'] != 'bottom') {
1655 // move the payment window, if available
1656 ?>
1657 <script type="text/javascript">
1658
1659 jQuery(function() {
1660
1661 var payment_output = jQuery('.vbvordpaybutton').first(),
1662 payment_notes = jQuery('.vbvordpaynote').first(),
1663 payment_ctimer = jQuery('.vbo-timer-payment').first(),
1664 payment_wrappr = jQuery('.vbo-paycontainer-pos-<?php echo $this->payment['outposition']; ?>').first();
1665
1666 if (payment_output.length && payment_wrappr.length) {
1667 // display final target
1668 payment_wrappr.show();
1669
1670 if (payment_notes.length) {
1671 // prepend notes first
1672 payment_notes.prependTo(payment_wrappr);
1673 }
1674
1675 if (payment_ctimer.length) {
1676 // prepend countdown timer first
1677 payment_ctimer.prependTo(payment_wrappr);
1678 }
1679
1680 // append payment output
1681 payment_output.appendTo(payment_wrappr);
1682 }
1683
1684 });
1685
1686 </script>
1687 <?php
1688 }
1689 //
1690