PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.8.16
VikBooking Hotel Booking Engine & PMS v1.8.16
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 / admin / views / bookingcheckin / tmpl / default.php

default.php in VikBooking Hotel Booking Engine & PMS 1.8.16, at admin/views/bookingcheckin/tmpl/default.php

1,368 lines 53.0 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 $order = $this->row;
14 $rooms = $this->rooms;
15 $customer = $this->customer;
16
17 $dbo = JFactory::getDbo();
18
19 $vbo_app = VikBooking::getVboApplication();
20
21 /**
22 * This view is usually rendered within a modal window, and with WordPress
23 * the modal window is loaded through AJAX by the "editorder" View. For this
24 * reason, with WP we should not load the JS assets for the contextual menu,
25 * or we would reset the default setup of the library. We load the assets in
26 * the parent View "editorder" to avoid issues of any kind.
27 *
28 * @since 1.16.0 (J) - 1.6.0 (WP)
29 */
30 if ((VBOPlatformDetection::isJoomla()) || (VBOPlatformDetection::isWordPress() && !wp_doing_ajax())) {
31 $vbo_app->loadContextMenuAssets();
32 JText::script('VBRENTALORD');
33 JText::script('VBPVIEWORDERSPEOPLE');
34 }
35
36 $currencysymb = VikBooking::getCurrencySymb();
37 $nowdf = VikBooking::getDateFormat(true);
38 if ($nowdf == "%d/%m/%Y") {
39 $df = 'd/m/Y';
40 } elseif ($nowdf == "%m/%d/%Y") {
41 $df = 'm/d/Y';
42 } else {
43 $df = 'Y/m/d';
44 }
45 $datesep = VikBooking::getDateSeparator(true);
46 $pchanged = VikRequest::getInt('changed', '', 'request');
47 $tmpl = VikRequest::getVar('tmpl');
48 $set_parent_status = '';
49 $now_info = getdate();
50 $today_midnight = mktime(0, 0, 0, $now_info['mon'], $now_info['mday'], $now_info['year']);
51 $grace_ts = mktime(0, 0, 0, $now_info['mon'], $now_info['mday'] - 2, $now_info['year']);
52 $colortags = VikBooking::loadBookingsColorTags();
53 $otachannel = '';
54 $otachannel_name = '';
55 $otachannel_bid = '';
56 $otacurrency = '';
57 if (!empty($order['channel'])) {
58 $channelparts = explode('_', $order['channel']);
59 $otachannel = array_key_exists(1, $channelparts) && strlen($channelparts[1]) > 0 ? $channelparts[1] : ucwords($channelparts[0]);
60 $otachannel_name = $otachannel;
61 $otachannel_bid = $order['idorderota'];
62 if (strstr($otachannel, '.') !== false) {
63 $otaccparts = explode('.', $otachannel);
64 $otachannel = $otaccparts[0];
65 }
66 $otacurrency = strlen($order['chcurrency']) > 0 ? $order['chcurrency'] : '';
67 }
68 $sensible_k = array('first_name', 'last_name', 'country', 'gender', 'bdate', 'pbirth');
69 $missing_customer_det = false;
70 foreach ($customer as $ck => $cv) {
71 if ((!isset($customer[$ck]) || empty($customer[$ck])) && in_array($ck, $sensible_k)) {
72 $missing_customer_det = true;
73 }
74 }
75
76 /**
77 * Back-end guests registration now relies on dynamic drivers within Vik Booking.
78 *
79 * @since 1.15.0 (J) - 1.5.0 (WP)
80 */
81
82 // get the list of back-end pax fields according to settings
83 list($pax_fields, $pax_fields_attributes) = VikBooking::getPaxFields();
84
85 // grab also the fields for front-end pre check-in
86 list($pre_pax_fields, $pre_pax_fields_attributes) = VikBooking::getPaxFields(true);
87
88 // once the pax fields have been prepared, get the active driver instance
89 $pax_fields_obj = VBOCheckinPax::getInstance();
90
91 // load any previous checkin information from this customer
92 $previous_checkins = VBOCheckinPax::getCustomerAllPaxData($order['id']);
93
94 ?>
95 <div class="vbo-info-overlay-block">
96 <a class="vbo-info-overlay-close" href="javascript: void(0);"></a>
97 <div class="vbo-info-overlay-content">
98 <h3 id="vbo-overlay-title">
99 <span class="vbo-info-overlay-title-close">
100 <span onclick="vboOpenModal();"><?php VikBookingIcons::e('times-circle'); ?></span>
101 </span>
102 </h3>
103 <div class="vbo-overlay-checkin-body"></div>
104 </div>
105 </div>
106
107 <form action="index.php?option=com_vikbooking" method="post" name="adminForm" id="adminForm">
108 <div class="vbo-bookdet-container">
109 <div class="vbo-bookdet-wrap">
110 <div class="vbo-bookdet-head">
111 <span>ID</span>
112 <?php
113 if (!empty($order['adminnotes'])) {
114 ?>
115 <i class="vboicn-info icn-bigger icn-nomargin icn-float-left icn-clickable" onclick="vboUpdateModal('<?php echo addslashes(JText::translate('VBADMINNOTESTOGGLE')); ?>', '.adminnotes', true);"></i>
116 <?php
117 }
118 ?>
119 </div>
120 <div class="vbo-bookdet-foot">
121 <span><a href="index.php?option=com_vikbooking&task=editorder&cid[]=<?php echo $order['id']; ?>" target="_blank"><?php echo $order['id']; ?></a></span>
122 </div>
123 </div>
124 <?php
125 if (!empty($order['channel'])) {
126 ?>
127 <div class="vbo-bookdet-wrap">
128 <div class="vbo-bookdet-head">
129 <?php echo $otachannel; ?>
130 </div>
131 <div class="vbo-bookdet-foot">
132 <span>ID <?php echo $otachannel_bid; ?></span>
133 </div>
134 </div>
135 <?php
136 }
137 ?>
138 <div class="vbo-bookdet-wrap">
139 <div class="vbo-bookdet-head">
140 <span><?php echo JText::translate('VBEDITORDERONE'); ?></span>
141 </div>
142 <div class="vbo-bookdet-foot">
143 <?php echo date(str_replace("/", $datesep, $df).' H:i', $order['ts']); ?>
144 </div>
145 </div>
146 <?php
147 if (count($customer)) {
148 ?>
149 <div class="vbo-bookdet-wrap">
150 <div class="vbo-bookdet-head">
151 <span><?php echo JText::translate('VBCUSTOMERNOMINATIVE'); ?></span>
152 <?php
153 if ($missing_customer_det) {
154 echo $vbo_app->createPopover(array('title' => JText::translate('VBCUSTOMERMISSIMPDET'), 'content' => JText::translate('VBCUSTOMERMISSIMPDETHELP'), 'icon_class' => VikBookingIcons::i('exclamation-triangle'), 'placement' => 'bottom'));
155 } elseif (!empty($customer['notes'])) {
156 ?>
157 <i class="vboicn-info icn-bigger icn-nomargin icn-float-left icn-clickable" onclick="vboUpdateModal('<?php echo addslashes(JText::translate('VBCUSTOMERNOTES')); ?>', '.customer_notes', true);"></i>
158 <?php
159 }
160 ?>
161 </div>
162 <div class="vbo-bookdet-foot">
163 <?php echo (isset($customer['country_img']) ? $customer['country_img'].' ' : '').'<a href="javascript: void(0);" onclick="vboUpdateModal(\''.addslashes(JText::translate('VBCUSTINFO')).'\', \'.customer_info\', true);">'.ltrim($customer['first_name'].' '.$customer['last_name']).'</a>'; ?>
164 </div>
165 </div>
166 <?php
167 }
168 ?>
169 <div class="vbo-bookdet-wrap">
170 <div class="vbo-bookdet-head">
171 <span><?php echo JText::translate('VBEDITORDERROOMSNUM'); ?></span>
172 </div>
173 <div class="vbo-bookdet-foot">
174 <?php echo $order['roomsnum']; ?>
175 </div>
176 </div>
177 <div class="vbo-bookdet-wrap">
178 <div class="vbo-bookdet-head">
179 <span><?php echo JText::translate('VBEDITORDERFOUR'); ?></span>
180 </div>
181 <div class="vbo-bookdet-foot">
182 <?php echo $order['days']; ?>
183 </div>
184 </div>
185 <div class="vbo-bookdet-wrap">
186 <div class="vbo-bookdet-head">
187 <span><?php echo JText::translate('VBEDITORDERFIVE'); ?></span>
188 </div>
189 <div class="vbo-bookdet-foot">
190 <?php
191 $checkin_info = getdate($order['checkin']);
192 $short_wday = JText::translate('VB'.strtoupper(substr($checkin_info['weekday'], 0, 3)));
193 ?>
194 <?php echo $short_wday.', '.date(str_replace("/", $datesep, $df).' H:i', $order['checkin']); ?>
195 </div>
196 </div>
197 <div class="vbo-bookdet-wrap">
198 <div class="vbo-bookdet-head">
199 <span><?php echo JText::translate('VBEDITORDERSIX'); ?></span>
200 </div>
201 <div class="vbo-bookdet-foot">
202 <?php
203 $checkout_info = getdate($order['checkout']);
204 $short_wday = JText::translate('VB'.strtoupper(substr($checkout_info['weekday'], 0, 3)));
205 ?>
206 <?php echo $short_wday.', '.date(str_replace("/", $datesep, $df).' H:i', $order['checkout']); ?>
207 </div>
208 </div>
209 <div class="vbo-bookdet-wrap vbo-bookdet-wrap-special">
210 <div class="vbo-bookdet-head">
211 <span><?php echo JText::translate('VBOCHECKEDSTATUS'); ?></span>
212 </div>
213 <div class="vbo-bookdet-foot">
214 <?php
215 if ($order['checked'] < 0) {
216 //no show
217 $checked_status = '<span class="label label-error">'.JText::translate('VBOCHECKEDSTATUSNOS').'</span>';
218 $set_parent_status = $pchanged > 0 ? '<span style="font-weight: bold; color: red;">'.strtoupper(JText::translate('VBOCHECKEDSTATUSNOS')).'</span>' : $set_parent_status;
219 } elseif ($order['checked'] == 1) {
220 //checked in
221 $checked_status = '<span class="label label-success">'.JText::translate('VBOCHECKEDSTATUSIN').'</span>';
222 $set_parent_status = $pchanged > 0 ? '<span style="font-weight: bold; color: green;">'.strtoupper(JText::translate('VBOCHECKEDSTATUSIN')).'</span>' : $set_parent_status;
223 } elseif ($order['checked'] == 2) {
224 //checked out
225 $checked_status = '<span class="label label-info">'.JText::translate('VBOCHECKEDSTATUSOUT').'</span>';
226 $set_parent_status = $pchanged > 0 ? '<span style="font-weight: bold; color: green;">'.strtoupper(JText::translate('VBOCHECKEDSTATUSOUT')).'</span>' : $set_parent_status;
227 } else {
228 //none (0)
229 $checked_status = '<span class="label">'.JText::translate('VBOCHECKEDSTATUSZERO').'</span>';
230 $set_parent_status = $pchanged > 0 ? '<span style="font-weight: bold; color: green;">'.strtoupper(JText::translate('VBCONFIRMED')).'</span>' : $set_parent_status;
231 }
232 ?>
233 <?php echo $checked_status; ?>
234 </div>
235 </div>
236 <?php
237 if (is_array($previous_checkins) && count($previous_checkins) && $order['checked'] < 1) {
238 foreach ($previous_checkins as $k => $prev_checkin) {
239 $previous_checkins[$k]['checkin_dt'] = date(str_replace("/", $datesep, $df), $prev_checkin['checkin']);
240 $previous_checkins[$k]['checkout_dt'] = date(str_replace("/", $datesep, $df), $prev_checkin['checkout']);
241 $previous_checkins[$k]['ts_dt'] = date(str_replace("/", $datesep, $df), $prev_checkin['ts']);
242 $book_tot_guests = 0;
243 $prev_checkin['pax_data'] = empty($prev_checkin['pax_data']) || !is_array($prev_checkin['pax_data']) ? [] : $prev_checkin['pax_data'];
244 foreach ($prev_checkin['pax_data'] as $rnum => $room_pax) {
245 foreach ($room_pax as $guest_num => $guest_data) {
246 $book_tot_guests++;
247 }
248 }
249 $previous_checkins[$k]['tot_guests'] = $book_tot_guests;
250 }
251 ?>
252 <div class="vbo-bookdet-wrap">
253 <div class="vbo-bookdet-head">
254 <span><?php echo JText::translate('VBO_PREVIOUS_CHECKINS'); ?></span>
255 </div>
256 <div class="vbo-bookdet-foot">
257 <button type="button" class="btn btn-small btn-primary vbo-context-menu-btn vbo-context-menu-prevchkins">
258 <span class="vbo-context-menu-lbl"><?php echo JText::translate('VBO_SELECT'); ?></span>
259 <span class="vbo-context-menu-ico"><?php VikBookingIcons::e('sort-down'); ?></span>
260 </button>
261 </div>
262 </div>
263
264 <script type="text/javascript">
265 var prev_checkins = <?php echo json_encode($previous_checkins); ?>;
266 var prev_checkins_btns = [];
267
268 function populatePreviousCheckin(pax_data) {
269 if (!pax_data || !pax_data.length) {
270 alert('Invalid previous check-in information');
271 return false;
272 }
273
274 var room_num = 0,
275 guest_num = 1,
276 guests_found = 0;
277
278 pax_data.forEach((room_pax, room_index) => {
279 for (let guest_num in room_pax) {
280 if (!room_pax.hasOwnProperty(guest_num)) {
281 continue;
282 }
283 if (jQuery('.vbo-roomdet-wrapper[data-roomnum="' + room_num + '"]').length && !jQuery('.vbo-roomdet-guest-details[data-guestnum="' + guest_num + '"]').length) {
284 // try to go to the first guest of the next room
285 room_num++;
286 guest_num = 1;
287 }
288 let guest_found = false;
289 for (let prop_name in room_pax[guest_num]) {
290 if (!room_pax[guest_num].hasOwnProperty(prop_name)) {
291 continue;
292 }
293 let field_name = 'guests[' + room_num + '][' + guest_num + '][' + prop_name + ']';
294 if (jQuery('[name="' + field_name + '"]').length) {
295 jQuery('[name="' + field_name + '"]').val(room_pax[guest_num][prop_name]).trigger('change');
296 if (!guest_found) {
297 guests_found++;
298 guest_found = true;
299 }
300 }
301 }
302 guest_num++;
303 if (jQuery('#vbo-roomdet-guests-details-' + room_num).length && !jQuery('#vbo-roomdet-guests-details-' + room_num).is(':visible')) {
304 jQuery('#vbo-roomdet-guests-details-' + room_num).slideDown();
305 }
306 }
307 });
308
309 return guests_found;
310 }
311
312 prev_checkins.forEach((prev_checkin, index) => {
313 prev_checkins_btns.push({
314 icon: '<?php echo VikBookingIcons::i('calendar-check'); ?>',
315 text: Joomla.JText._('VBRENTALORD') + ' #' + prev_checkin['idorder'] + ' - ' + Joomla.JText._('VBPVIEWORDERSPEOPLE') + ': ' + prev_checkin['tot_guests'],
316 separator: (index === prev_checkins.length - 1),
317 action: (root, config) => {
318 var guests_populated = populatePreviousCheckin(prev_checkins[index]['pax_data']);
319 console.log('guests_populated: ' + guests_populated);
320 },
321 });
322 });
323
324 jQuery(function() {
325 jQuery('.vbo-context-menu-prevchkins').vboContextMenu({
326 placement: 'bottom-left',
327 buttons: prev_checkins_btns,
328 });
329 });
330 </script>
331 <?php
332 }
333 ?>
334 </div>
335 <?php
336 //rooms details and total information
337 ?>
338 <div class="vbo-checkin-main-block">
339 <div class="vbo-roomsdet-container">
340 <?php
341 $tars = array();
342 $arrpeople = array();
343 $is_package = (!empty($order['pkg']));
344 $is_cust_cost = false;
345 foreach ($rooms as $ind => $or) {
346 $num = $ind + 1;
347 $arrpeople[$num]['adults'] = $or['adults'];
348 $arrpeople[$num]['children'] = $or['children'];
349 $arrpeople[$num]['children_age'] = $or['childrenage'];
350 $arrpeople[$num]['t_first_name'] = $or['t_first_name'];
351 $arrpeople[$num]['t_last_name'] = $or['t_last_name'];
352 if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
353 //package or custom cost set from the back-end
354 $is_cust_cost = true;
355 continue;
356 }
357 $q = "SELECT * FROM `#__vikbooking_dispcost` WHERE `id`=".(int)$or['idtar'].";";
358 $dbo->setQuery($q);
359 $dbo->execute();
360 $tar = $dbo->loadAssocList();
361 $tars[$num] = $tar;
362 }
363 //compose the calculation for pax_data
364 $pax_data = array();
365 $count_pax_data = 0;
366 if (count($customer) > 0) {
367 $count_pax_data = 1;
368 if (!empty($customer['pax_data'])) {
369 $pax_data = json_decode($customer['pax_data'], true);
370 $pax_data = !is_array($pax_data) ? array() : $pax_data;
371 }
372 }
373 $all_countries = VikBooking::getCountriesArray();
374 //
375 foreach ($rooms as $ind => $or) {
376 $num = $ind + 1;
377 //total guests details available
378 $count_pax_data = $num < 2 ? $count_pax_data : 0;
379 if (isset($pax_data[$ind])) {
380 $count_pax_data = count($pax_data[$ind]);
381 }
382
383 //Room Specific Unit
384 $spec_unit = '';
385 if (!empty($or['params'])) {
386 $room_params = json_decode($or['params'], true);
387 $arr_features = array();
388 if (is_array($room_params) && array_key_exists('features', $room_params) && @count($room_params['features']) > 0) {
389 foreach ($room_params['features'] as $rind => $rfeatures) {
390 foreach ($rfeatures as $fname => $fval) {
391 if (strlen($fval)) {
392 $arr_features[$rind] = '#'.$rind.' - '.JText::translate($fname).': '.$fval;
393 break;
394 }
395 }
396 }
397 }
398 if (isset($arr_features[$or['roomindex']])) {
399 $spec_unit = $arr_features[$or['roomindex']];
400 }
401 }
402
403 // calculate the number of guests to register depending on settings
404 $guests_to_register = $pax_fields_obj->registerChildren() ? ($arrpeople[$num]['adults'] + $arrpeople[$num]['children']) : $arrpeople[$num]['adults'];
405 ?>
406 <div class="vbo-roomdet-wrapper" data-roomnum="<?php echo $ind; ?>">
407 <div class="vbo-roomdet-wrap">
408 <div class="vbo-roomdet-entry">
409 <div class="vbo-roomdet-head">
410 <span><?php echo $or['room_name']; ?></span>
411 </div>
412 <div class="vbo-roomdet-foot">
413 <?php
414 if (!empty($spec_unit)) {
415 ?>
416 <span><?php echo $spec_unit; ?></span>
417 <?php
418 }
419 ?>
420 <div class="vbo-roomdet-guests-toggle-cont">
421 <span tabindex="0" class="vbo-roomdet-guests-toggle <?php echo $count_pax_data >= $guests_to_register ? 'vbo-guestscount-complete' : 'vbo-guestscount-incomplete'; ?>" data-roomind="<?php echo $ind; ?>">
422 <i class="vboicn-user-plus"></i>
423 <span class="vbo-roomdet-guests-toggleword"><?php echo JText::translate('VBOGUESTSDETAILS'); ?> (<span id="vbo-guestscount-<?php echo $ind; ?>"><?php echo $count_pax_data; ?></span>/<?php echo $guests_to_register; ?>)</span>
424 </span>
425 </div>
426 </div>
427 </div>
428 <div class="vbo-roomdet-entry">
429 <div class="vbo-roomdet-head">
430 <span><?php echo JText::translate('VBEDITORDERADULTS'); ?></span>
431 </div>
432 <div class="vbo-roomdet-foot">
433 <span><?php echo $arrpeople[$num]['adults']; ?></span>
434 </div>
435 </div>
436 <?php
437 $age_str = '';
438 if ($arrpeople[$num]['children'] > 0) {
439 if (!empty($arrpeople[$num]['children_age'])) {
440 $json_child = json_decode($arrpeople[$num]['children_age'], true);
441 if (is_array($json_child['age']) && count($json_child['age']) > 0) {
442 $age_str = ' '.JText::sprintf('VBORDERCHILDAGES', implode(', ', $json_child['age']));
443 }
444 }
445 }
446 ?>
447 <div class="vbo-roomdet-entry">
448 <div class="vbo-roomdet-head">
449 <span><?php echo JText::translate('VBEDITORDERCHILDREN'); ?></span>
450 </div>
451 <div class="vbo-roomdet-foot">
452 <span><?php echo $arrpeople[$num]['children'].$age_str; ?></span>
453 </div>
454 </div>
455 <div class="vbo-roomdet-entry">
456 <div class="vbo-roomdet-head">
457 <span><?php echo JText::translate('VBEDITORDERSEVEN'); ?></span>
458 </div>
459 <div class="vbo-roomdet-foot">
460 <?php
461 if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
462 ?>
463 <span>
464 <?php
465 if (!empty($or['pkg_name'])) {
466 //package
467 echo $or['pkg_name'];
468 } else {
469 //custom cost can have an OTA Rate Plan name
470 if (!empty($or['otarplan'])) {
471 echo ucwords($or['otarplan']);
472 } else {
473 echo JText::translate('VBOROOMCUSTRATEPLAN');
474 }
475 }
476 ?>
477 <?php echo VikBooking::formatCurrencyNumber(VikBooking::numberFormat($or['cust_cost']), $currencysymb); ?>
478 </span>
479 <?php
480 } elseif (array_key_exists($num, $tars) && !empty($tars[$num][0]['idprice'])) {
481 $display_rate = !empty($or['room_cost']) ? $or['room_cost'] : $tars[$num][0]['cost'];
482 ?>
483 <span>
484 <?php echo VikBooking::getPriceName($tars[$num][0]['idprice']); ?>
485 <?php
486 if (!empty($or['room_cost'])) {
487 echo VikBooking::formatCurrencyNumber(VikBooking::numberFormat(VikBooking::sayCostPlusIva($display_rate, $tars[$num][0]['idprice'])), $currencysymb);
488 }
489 ?>
490 </span>
491 <?php
492 } elseif (!empty($or['otarplan'])) {
493 ?>
494 <span><?php echo ucwords($or['otarplan']); ?></span>
495 <?php
496 } elseif ($this->row['closure'] < 1) {
497 ?>
498 <span><?php echo JText::translate('VBOROOMNORATE'); ?></span>
499 <?php
500 } else {
501 ?>
502 <span>-----</span>
503 <?php
504 }
505 ?>
506 </div>
507 </div>
508 <div class="vbo-roomdet-entry">
509 <div class="vbo-roomdet-head">
510 <span><?php echo JText::translate('VBEDITORDEREIGHT'); ?></span>
511 </div>
512 <div class="vbo-roomdet-foot">
513 <?php
514 if (!empty($or['optionals'])) {
515 $stepo = explode(";", $or['optionals']);
516 foreach ($stepo as $roptkey => $oo) {
517 if (empty($oo)) {
518 continue;
519 }
520 $hide_price = false;
521 $stept = explode(":", $oo);
522 $actopt = VikBooking::getSingleOption($stept[0]);
523 if (!$actopt) {
524 continue;
525 }
526 $chvar = '';
527 if (!empty($actopt['ageintervals']) && $or['children'] > 0 && strstr($stept[1], '-') != false) {
528 $optagenames = VikBooking::getOptionIntervalsAges($actopt['ageintervals']);
529 $optagepcent = VikBooking::getOptionIntervalsPercentage($actopt['ageintervals']);
530 $optageovrct = VikBooking::getOptionIntervalChildOverrides($actopt, $or['adults'], $or['children']);
531 $child_num = VikBooking::getRoomOptionChildNumber($or['optionals'], $actopt['id'], $roptkey, $or['children']);
532 $optagecosts = VikBooking::getOptionIntervalsCosts(isset($optageovrct['ageintervals_child' . ($child_num + 1)]) ? $optageovrct['ageintervals_child' . ($child_num + 1)] : $actopt['ageintervals']);
533 $agestept = explode('-', $stept[1]);
534 $stept[1] = $agestept[0];
535 $chvar = $agestept[1];
536 if (array_key_exists(($chvar - 1), $optagepcent) && $optagepcent[($chvar - 1)] == 1) {
537 //percentage value of the adults tariff
538 if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
539 $optagecosts[($chvar - 1)] = $or['cust_cost'] * $optagecosts[($chvar - 1)] / 100;
540 } else {
541 $display_rate = !empty($or['room_cost']) ? $or['room_cost'] : $tars[$num][0]['cost'];
542 $hide_price = empty($or['room_cost']) ? true : $hide_price;
543 $optagecosts[($chvar - 1)] = $display_rate * $optagecosts[($chvar - 1)] / 100;
544 }
545 } elseif (array_key_exists(($chvar - 1), $optagepcent) && $optagepcent[($chvar - 1)] == 2) {
546 //VBO 1.10 - percentage value of room base cost
547 if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
548 $optagecosts[($chvar - 1)] = $or['cust_cost'] * $optagecosts[($chvar - 1)] / 100;
549 } else {
550 $display_rate = isset($tars[$num][0]['room_base_cost']) ? $tars[$num][0]['room_base_cost'] : (!empty($or['room_cost']) ? $or['room_cost'] : $tars[$num][0]['cost']);
551 $hide_price = empty($or['room_cost']) ? true : $hide_price;
552 $optagecosts[($chvar - 1)] = $display_rate * $optagecosts[($chvar - 1)] / 100;
553 }
554 }
555 $actopt['chageintv'] = $chvar;
556 $actopt['name'] .= ' ('.$optagenames[($chvar - 1)].')';
557 $realcost = (intval($actopt['perday']) == 1 ? (floatval($optagecosts[($chvar - 1)]) * $order['days'] * $stept[1]) : (floatval($optagecosts[($chvar - 1)]) * $stept[1]));
558 } else {
559 // VBO 1.11 - options percentage cost of the room total fee
560 if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
561 $deftar_basecosts = $or['cust_cost'];
562 } else {
563 $deftar_basecosts = !empty($or['room_cost']) ? $or['room_cost'] : $tars[$num][0]['cost'];
564 }
565 $actopt['cost'] = (int)$actopt['pcentroom'] ? ($deftar_basecosts * $actopt['cost'] / 100) : $actopt['cost'];
566 //
567 $realcost = (intval($actopt['perday']) == 1 ? ($actopt['cost'] * $order['days'] * $stept[1]) : ($actopt['cost'] * $stept[1]));
568 }
569 if ($actopt['maxprice'] > 0 && $realcost > $actopt['maxprice']) {
570 $realcost = $actopt['maxprice'];
571 if (intval($actopt['hmany']) == 1 && intval($stept[1]) > 1) {
572 $realcost = $actopt['maxprice'] * $stept[1];
573 }
574 }
575 $realcost = $actopt['perperson'] == 1 ? ($realcost * $arrpeople[$num]['adults']) : $realcost;
576
577 /**
578 * Trigger event to allow third party plugins to apply a custom calculation for the option/extra fee or tax.
579 *
580 * @since 1.17.7 (J) - 1.7.7 (WP)
581 */
582 $custom_calculation = VBOFactory::getPlatform()->getDispatcher()->filter('onCalculateBookingOptionFeeCost', [$realcost, &$actopt, $order, $or]);
583 if ($custom_calculation) {
584 $realcost = (float) $custom_calculation[0];
585 }
586
587 $tmpopr = VikBooking::sayOptionalsPlusIva($realcost, $actopt['idiva']);
588 ?>
589 <div class="vbo-roomdet-foot-options">
590 <?php echo ($stept[1] > 1 ? $stept[1]." " : "").$actopt['name'].(!$hide_price ? " " . VikBooking::formatCurrencyNumber(VikBooking::numberFormat($tmpopr), $currencysymb) : ''); ?>
591 </div>
592 <?php
593 }
594 }
595 ?>
596 </div>
597 </div>
598 <div class="vbo-roomdet-entry">
599 <div class="vbo-roomdet-head">
600 <span><?php echo JText::translate('VBPEDITBUSYEXTRACOSTS'); ?></span>
601 </div>
602 <div class="vbo-roomdet-foot">
603 <?php
604 if (!empty($or['extracosts'])) {
605 $cur_extra_costs = json_decode($or['extracosts'], true);
606 foreach ($cur_extra_costs as $eck => $ecv) {
607 ?>
608 <div class="vbo-roomdet-foot-extras">
609 <?php echo $ecv['name'] . " " . VikBooking::formatCurrencyNumber(VikBooking::numberFormat(VikBooking::sayOptionalsPlusIva($ecv['cost'], $ecv['idtax'])), $currencysymb); ?>
610 </div>
611 <?php
612 }
613 }
614 ?>
615 </div>
616 </div>
617 </div>
618 <?php
619 if ($arrpeople[$num]['adults'] > 0) {
620 ?>
621 <div class="vbo-roomdet-guests-details" id="vbo-roomdet-guests-details-<?php echo $ind; ?>">
622 <?php
623 /**
624 * Back-end guests registration now relies on dynamic drivers within Vik Booking.
625 *
626 * @since 1.15.0 (J) - 1.5.0 (WP)
627 */
628
629 // loop through all guests that should be registered within this room-party
630 for ($g = 1; $g <= $guests_to_register; $g++) {
631 $current_guest = array();
632 if (count($pax_data) && isset($pax_data[$ind]) && isset($pax_data[$ind][$g])) {
633 $current_guest = $pax_data[$ind][$g];
634 } elseif ($ind < 1 && $g == 1 && count($customer)) {
635 $current_guest = $customer;
636 }
637 ?>
638 <div class="vbo-roomdet-guest-details" data-roomind="<?php echo $ind; ?>" data-guestnum="<?php echo $g; ?>" data-totguests="<?php echo $guests_to_register; ?>">
639 <div class="vbo-roomdet-guest-detail vbo-roomdet-guest-detail-num">
640 <span><?php echo JText::sprintf('VBOGUESTNUM', $g); ?></span>
641 </div>
642 <?php
643 $pax_field_ind = 1;
644 foreach ($pax_fields as $paxk => $paxv) {
645 // get an instance of the VBOCheckinPaxfield object
646 $pax_field_obj = $pax_fields_obj->getField($paxk);
647
648 // detect the current type of guest
649 $guest_type = $g > $arrpeople[$num]['adults'] ? 'child' : 'adult';
650
651 // set object data
652 $pax_field_obj->setGuestType($guest_type)
653 ->setFieldNumber($pax_field_ind)
654 ->setGuestNumber($g)
655 ->setGuestData($current_guest)
656 ->setRoomIndex($ind)
657 ->setBooking($this->row)
658 ->setBookingRooms($this->rooms)
659 ->setRoomGuests($arrpeople[$num]['adults'], $arrpeople[$num]['children'])
660 ->setTotalRooms(count($arrpeople));
661
662 // render input field
663 $pax_field_html = $pax_fields_obj->render($pax_field_obj);
664 if (empty($pax_field_html)) {
665 // nothing to display, increase the counter and continue
666 $pax_field_ind++;
667 continue;
668 }
669
670 // access the implementor object
671 $implementor = $pax_fields_obj->getFieldTypeImplementor($pax_field_obj);
672
673 // check if a particular CSS class has been defined
674 $field_container_class = $implementor->getContainerClassAttr();
675 $field_container_class = !empty($field_container_class) ? " $field_container_class" : '';
676
677 ?>
678 <div class="vbo-roomdet-guest-detail<?php echo $field_container_class; ?>">
679 <div class="vbo-roomdet-guest-detail-lbl">
680 <label for="<?php echo $implementor->getFieldIdAttr(); ?>"><?php echo $paxv; ?></label>
681 </div>
682 <div class="vbo-roomdet-guest-detail-val">
683 <?php echo $pax_field_html; ?>
684 </div>
685 </div>
686 <?php
687 $pax_field_ind++;
688 }
689 // display any other information collected through the pre check-in
690 if (count($pax_data) && isset($pax_data[$ind]) && isset($pax_data[$ind][$g])) {
691 foreach ($pax_data[$ind][$g] as $extrak => $extrav) {
692 // sanitize pax field key
693 $extrak = htmlspecialchars($extrak);
694 if (isset($pax_fields[$extrak]) || (is_scalar($extrav) && !strlen($extrav))) {
695 // this is a default pax field, we skip it
696 continue;
697 }
698 // obtain field label and field type
699 $precheckin_field_lbl = isset($pre_pax_fields[$extrak]) ? $pre_pax_fields[$extrak] : $extrak;
700 $precheckin_field_typ = isset($pre_pax_fields_attributes[$extrak]) && $pre_pax_fields_attributes[$extrak] == 'file' ? 'file' : 'text';
701 // ensure the field should be displayed
702 if (substr($extrak, 0, 1) === '_') {
703 // this is a "protected" pax field to be kept within a hidden input field and no labels
704 ?>
705 <input type="hidden" data-gind="<?php echo $g; ?>" class="vbo-paxfield" name="guests[<?php echo $ind; ?>][<?php echo $g; ?>][<?php echo $extrak; ?>]" value="<?php echo htmlspecialchars($extrav); ?>" />
706 <?php
707 // do not display anyting else
708 continue;
709 }
710 ?>
711 <div class="vbo-roomdet-guest-detail vbo-roomdet-guest-detail-precheckin">
712 <div class="vbo-roomdet-guest-detail-lbl">
713 <span><?php echo $precheckin_field_lbl; ?></span>
714 </div>
715 <div class="vbo-roomdet-guest-detail-val">
716 <?php
717 if ($precheckin_field_typ == 'file') {
718 // documents uploaded by the customer during pre-checkin
719 $guest_files = explode('|', $extrav);
720 foreach ($guest_files as $gfk => $guest_file) {
721 if (empty($guest_file) || strpos($guest_file, 'http') !== 0) {
722 continue;
723 }
724 $furl_segments = explode('/', $guest_file);
725 $guest_fname = $furl_segments[(count($furl_segments) - 1)];
726 $read_fname = substr($guest_fname, (strpos($guest_fname, '_') + 1));
727 ?>
728 <div class="vbo-paxfield-file-uploaded">
729 <a href="<?php echo JHtml::fetch('esc_attr', $guest_file); ?>" target="_blank">
730 <?php VikBookingIcons::e('image'); ?>
731 <span><?php echo htmlspecialchars($read_fname); ?></span>
732 </a>
733 </div>
734 <?php
735 }
736 ?>
737 <input type="hidden" data-gind="<?php echo $g; ?>" name="guests[<?php echo $ind; ?>][<?php echo $g; ?>][<?php echo $extrak; ?>]" value="<?php echo $extrav; ?>" />
738 <?php
739 } else {
740 ?>
741 <input type="text" data-gind="<?php echo $g; ?>" class="vbo-paxfield" name="guests[<?php echo $ind; ?>][<?php echo $g; ?>][<?php echo $extrak; ?>]" value="<?php echo htmlspecialchars($extrav); ?>" />
742 <?php
743 }
744 ?>
745 </div>
746 </div>
747 <?php
748 }
749 }
750 ?>
751 </div>
752 <?php
753 }
754 ?>
755 </div>
756 </div>
757 <?php
758 }
759 }
760 ?>
761 </div>
762
763 <div class="vbo-checkin-payment-container">
764 <div class="vbo-checkin-payment-detail">
765 <?php
766 $bcolortag = VikBooking::applyBookingColorTag($order, $colortags);
767 $usectag = '';
768 if (count($bcolortag) > 0) {
769 $bcolortag['name'] = JText::translate($bcolortag['name']);
770 $usectag = '<span class="vbo-colortag-circle hasTooltip" style="background-color: '.$bcolortag['color'].';" title="'.htmlspecialchars($bcolortag['name']).'"></span> ';
771 }
772 ?>
773 <span class="vbo-checkin-payment-detail-lbl"><?php echo $usectag; ?><strong><?php echo JText::translate('VBEDITORDERNINE'); ?></strong></span>
774 <span class="vbo-checkin-payment-detail-v"><?php echo VikBooking::formatCurrencyNumber(VikBooking::numberFormat($order['total']), (strlen($otacurrency) > 0 ? '('.$otacurrency.') '.$currencysymb : $currencysymb)); ?></span>
775 </div>
776 <?php
777 if (!empty($order['totpaid']) && $order['totpaid'] > 0) {
778 $diff_to_pay = $order['total'] - $order['totpaid'];
779 ?>
780 <div class="vbo-checkin-payment-detail">
781 <span class="vbo-checkin-payment-detail-lbl"><?php echo JText::translate('VBAMOUNTPAID'); ?></span>
782 <span class="vbo-checkin-payment-detail-v"><?php echo VikBooking::formatCurrencyNumber(VikBooking::numberFormat($order['totpaid']), $currencysymb); ?></span>
783 </div>
784 <?php
785 if ($diff_to_pay > 0) {
786 ?>
787 <div class="vbo-checkin-payment-detail">
788 <span class="vbo-checkin-payment-detail-lbl"><?php echo JText::translate('VBTOTALREMAINING'); ?></span>
789 <span class="vbo-checkin-payment-detail-v"><?php echo VikBooking::formatCurrencyNumber(VikBooking::numberFormat($diff_to_pay), $currencysymb, ['%s', '<span id="vbo-checkin-remaining">%s</span>']); ?></span>
790 </div>
791 <div class="vbo-checkin-payment-detail">
792 <span class="vbo-checkin-payment-detail-lbl"><?php echo JText::translate('VBONEWAMOUNTPAID'); ?></span>
793 <span class="vbo-checkin-payment-detail-v"><?php echo $currencysymb; ?> <input name="newtotpaid" id="newtotpaid" value="" min="0" type="number" step="any" style="margin: 0;"></span>
794 </div>
795 <?php
796 }
797 } else {
798 // print the new amount paid anyway to let it update
799 ?>
800 <div class="vbo-checkin-payment-detail">
801 <span class="vbo-checkin-payment-detail-lbl"><?php echo JText::translate('VBONEWAMOUNTPAID'); ?></span>
802 <span class="vbo-checkin-payment-detail-v"><?php echo $currencysymb; ?> <input name="newtotpaid" id="newtotpaid" value="" min="0" type="number" step="any" style="margin: 0;"></span>
803 </div>
804 <?php
805 }
806 $payment = VikBooking::getPayment($order['idpayment']);
807 if (is_array($payment)) {
808 ?>
809 <div class="vbo-checkin-payment-detail">
810 <span class="vbo-checkin-payment-detail-lbl"><?php echo JText::translate('VBPAYMENTMETHOD'); ?></span>
811 <span class="vbo-checkin-payment-detail-v"><?php echo $payment['name']; ?></span>
812 </div>
813 <?php
814 }
815 if (!empty($order['paymentlog'])) {
816 ?>
817 <div class="vbo-checkin-payment-detail">
818 <span class="vbo-checkin-payment-detail-lbl vbo-checkin-payment-detail-click" onclick="vboUpdateModal('<?php echo addslashes(JText::translate('VBPAYMENTLOGTOGGLE')); ?>', '.paymentlog', true);">
819 <i class="vboicn-credit-card"></i> <?php echo JText::translate('VBPAYMENTLOGTOGGLE'); ?>
820 </span>
821 </div>
822 <?php
823 }
824 ?>
825 </div>
826 </div>
827
828 <div class="vbo-checkin-notes-wrap">
829 <div class="vbo-checkin-notes-inner">
830 <div class="vbo-checkin-notes-trig">
831 <span onclick="vboToggleCheckinNotes();"><i class="<?php echo count($customer) && !empty($customer['comments']) ? 'vboicn-bubbles2' : 'vboicn-bubble2'; ?>"></i> <?php echo JText::translate('VBOTOGGLECHECKINNOTES'); ?></span>
832 </div>
833 <div class="vbo-checkin-notes-cont">
834 <textarea name="comments"><?php echo count($customer) && isset($customer['comments']) ? htmlspecialchars($customer['comments']) : ''; ?></textarea>
835 </div>
836 </div>
837 </div>
838
839 <div class="vbo-checkin-update-wrap">
840 <div class="vbo-checkin-update-inner">
841 <div>
842 <button type="button" class="btn btn-primary" onclick="jQuery('#adminForm').submit();"><i class="vboicn-checkmark"></i> <?php echo JText::translate('VBOCHECKINUPDATEBTN'); ?></button>
843 </div>
844 </div>
845 </div>
846
847 <div class="vbo-checkin-commands-wrap">
848 <div class="vbo-checkin-commands-inner">
849 <?php
850 if ($today_midnight < $order['checkout'] || $grace_ts < $order['checkout']) {
851 $allowed_btns = array();
852 if ($order['checked'] <= 0) {
853 //check-in btn only for no-status or no-show
854 $allowed_btns[] = 1;
855 }
856 if ($order['checked'] < 0 && !empty($order['channel']) && strpos($order['channel'], 'booking.com') !== false && VikBooking::vcmBcomReportingSupported($order)) {
857 //report no show to Booking.com btn only for no-status
858 $allowed_btns[] = -11;
859 }
860 if ($order['checked'] == 0) {
861 //no-show button only if no-status
862 $allowed_btns[] = -1;
863 }
864 if ($order['checked'] == 1 && (count($customer) && empty($customer['checkindoc']))) {
865 //generate check-in doc button only for checked-in and no check-in doc
866 $allowed_btns[] = 11;
867 } elseif ($order['checked'] > 0 && (count($customer) && !empty($customer['checkindoc']))) {
868 //download check-in doc button only for checked-in||out and check-in doc
869 $allowed_btns[] = 12;
870 //add also the possibility of re-creating the document
871 $allowed_btns[] = 11;
872 }
873 if ($order['checked'] == 1 && $today_midnight > $order['checkin']) {
874 //check-out button only for checked-in and after the check-in day
875 $allowed_btns[] = 2;
876 }
877 if ($order['checked'] != 0) {
878 //cancel button only if not no-status
879 $allowed_btns[] = 0;
880 }
881 //print buttons
882 foreach ($allowed_btns as $chstatus) {
883 switch ($chstatus) {
884 case -1:
885 ?>
886 <div class="vbo-checkin-commands-btn">
887 <button type="button" onclick="vboSetCheckinAction(-1);" class="btn btn-large btn-danger"><i class="vboicn-blocked"></i> <?php echo JText::translate('VBOSETCHECKEDSTATUSNOS'); ?></button>
888 </div>
889 <?php
890 break;
891 case 0:
892 ?>
893 <div class="vbo-checkin-commands-btn">
894 <button type="button" onclick="vboSetCheckinAction(0);" class="btn btn-large btn-secondary"><i class="vboicn-cancel-circle"></i> <?php echo JText::translate('VBOSETCHECKEDSTATUSZERO'); ?></button>
895 </div>
896 <?php
897 break;
898 case 1:
899 ?>
900 <div class="vbo-checkin-commands-btn">
901 <button type="button" onclick="vboSetCheckinAction(1);" class="btn btn-large btn-success"><i class="vboicn-checkmark"></i> <?php echo JText::translate('VBOSETCHECKEDSTATUSIN'); ?></button>
902 </div>
903 <?php
904 break;
905 case 2:
906 ?>
907 <div class="vbo-checkin-commands-btn">
908 <button type="button" onclick="vboSetCheckinAction(2);" class="btn btn-large btn-success"><i class="vboicn-exit"></i> <?php echo JText::translate('VBOSETCHECKEDSTATUSOUT'); ?></button>
909 </div>
910 <?php
911 break;
912 case 11:
913 ?>
914 <div class="vbo-checkin-commands-btn">
915 <a href="index.php?option=com_vikbooking&task=gencheckindoc&cid[]=<?php echo $order['id'].($tmpl == 'component' ? '&tmpl=component' : ''); ?>" class="btn btn-large btn-success"><i class="vboicn-profile"></i> <?php echo JText::translate('VBOGENCHECKINDOC'); ?></a>
916 </div>
917 <?php
918 break;
919 case 12:
920 ?>
921 <div class="vbo-checkin-commands-btn">
922 <button type="button" onclick="window.open('<?php echo VBO_SITE_URI.'helpers/checkins/generated/'.$customer['checkindoc']; ?>', '_blank');" class="btn btn-large btn-success"><i class="vboicn-download"></i> <?php echo JText::translate('VBODWNLCHECKINDOC'); ?></button>
923 </div>
924 <?php
925 break;
926 case -11:
927 /**
928 * Build the contextual menu buttons to report the no-show to the OTA through AJAX requests.
929 *
930 * @since 1.16.8 (J) - 1.6.8 (WP)
931 *
932 * @requires VCM >= 1.8.24
933 */
934 ?>
935 <div class="vbo-checkin-commands-btn">
936 <button type="button" class="btn btn-large btn-danger vbo-context-menu-btn vbo-context-menu-otanoshow">
937 <span class="vbo-context-menu-lbl"><?php VikBookingIcons::e('ban'); ?> <?php echo JText::translate('VBOBCOMREPORTNOSHOW'); ?></span>
938 <span class="vbo-context-menu-ico"><?php VikBookingIcons::e('sort-down'); ?></span>
939 </button>
940 </div>
941
942 <script type="text/javascript">
943 jQuery(function() {
944
945 // callback constant will receive this.waived_fees (do not use an arrow function)
946 const notify_noshow = function() {
947 if (confirm('<?php echo addslashes(JText::translate('VBOBCOMREPORTNOSHOWCONF')); ?>')) {
948 // show inner modal
949 VBOCore.displayModal({
950 title: '.....',
951 dismiss_event: 'vbo-bookingcheckin-ajax-dismiss',
952 loading_event: 'vbo-bookingcheckin-ajax-loading',
953 loading_body: '<?php VikBookingIcons::e('circle-notch', 'fa-spin fa-fw'); ?>',
954 });
955
956 // start loading
957 VBOCore.emitEvent('vbo-bookingcheckin-ajax-loading');
958
959 // perform the request
960 VBOCore.doAjax(
961 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikchannelmanager&task=breporting.no_show'); ?>",
962 {
963 otaid: '<?php echo $order['idorderota']; ?>',
964 waived_fees: this.waived_fees,
965 },
966 (success) => {
967 // remove inner modal
968 VBOCore.emitEvent('vbo-bookingcheckin-ajax-dismiss');
969
970 // hide main modal
971 try {
972 jQuery('#jmodal-vbo-checkin-booking').modal('hide');
973 } catch(e) {
974 // do nothing
975 }
976
977 // reload (parent/current) window
978 (window.parent || window).location.reload();
979 },
980 (error) => {
981 // remove inner modal
982 VBOCore.emitEvent('vbo-bookingcheckin-ajax-dismiss');
983
984 // log and display the error
985 console.error(error);
986 alert(error.responseText);
987 }
988 );
989 }
990 };
991
992 jQuery('.vbo-context-menu-otanoshow').vboContextMenu({
993 placement: 'bottom-right',
994 buttons: [
995 {
996 icon: '<?php echo VikBookingIcons::i('ban'); ?>',
997 text: '<?php echo addslashes(JText::translate('VBO_DONT_WAIVE_FEES')); ?>',
998 class: 'vbo-context-menu-entry-warning',
999 separator: true,
1000 waived_fees: 0,
1001 action: notify_noshow,
1002 },
1003 {
1004 icon: '<?php echo VikBookingIcons::i('ban'); ?>',
1005 text: '<?php echo addslashes(JText::translate('VBO_DO_WAIVE_FEES')); ?>',
1006 class: 'vbo-context-menu-entry-danger',
1007 separator: false,
1008 waived_fees: 1,
1009 action: notify_noshow,
1010 },
1011 ],
1012 });
1013 });
1014 </script>
1015 <?php
1016 break;
1017 default:
1018 break;
1019 }
1020 }
1021 } else {
1022 ?>
1023 <p class="warn"><?php echo JText::translate('VBOCHECKINTIMEOVER'); ?></p>
1024 <?php
1025 //if the document exists, print the download button even if the check-out date is in the past
1026 if ($order['checked'] != 0 && (count($customer) && !empty($customer['checkindoc']))) {
1027 //download check-in doc button only for checked-in||out and check-in doc
1028 ?>
1029 <div class="vbo-checkin-commands-btn">
1030 <button type="button" onclick="window.open('<?php echo VBO_SITE_URI.'helpers/checkins/generated/'.$customer['checkindoc']; ?>', '_blank');" class="btn btn-large btn-success"><i class="vboicn-download"></i> <?php echo JText::translate('VBODWNLCHECKINDOC'); ?></button>
1031 </div>
1032 <?php
1033 }
1034 }
1035 ?>
1036 </div>
1037 </div>
1038 <input type="hidden" name="cid[]" value="<?php echo $order['id']; ?>">
1039 <input type="hidden" name="checkin_action" id="vbo-checkin-action" value="<?php echo $order['checked']; ?>">
1040 <input type="hidden" name="task" value="updatebookingcheckin" />
1041 <input type="hidden" name="option" value="com_vikbooking" />
1042 <?php
1043 if ($tmpl == 'component') {
1044 ?>
1045 <input type="hidden" name="tmpl" value="component" />
1046 <?php
1047 }
1048 ?>
1049 </form>
1050 <?php
1051 //
1052 ?>
1053 <script type="text/javascript">
1054 var vbo_overlay_data = {};
1055 <?php
1056 if (!empty($order['adminnotes'])) {
1057 $order['adminnotes'] = VikBooking::strTrimLiteral(nl2br(htmlspecialchars($order['adminnotes'])));
1058 ?>
1059 vbo_overlay_data['adminnotes'] = '<pre><?php echo addslashes($order['adminnotes']); ?></pre>';
1060 <?php
1061 }
1062 if (!empty($order['paymentlog'])) {
1063 $plain_log = htmlspecialchars($order['paymentlog']);
1064 $order['paymentlog'] = VikBooking::strTrimLiteral(nl2br(htmlspecialchars($order['paymentlog'])));
1065 ?>
1066 vbo_overlay_data['paymentlog'] = '<pre><?php echo addslashes($order['paymentlog']); ?></pre>';
1067 <?php
1068 //PCI Data Retrieval
1069 if (!empty($order['idorderota']) && !empty($order['channel'])) {
1070 $channel_source = $order['channel'];
1071 if (strpos($order['channel'], '_') !== false) {
1072 $channelparts = explode('_', $order['channel']);
1073 $channel_source = $channelparts[0];
1074 }
1075 //Limit set to Check-out date at 29:59:59
1076 $checkout_info = getdate($order['checkout']);
1077 $checkout_midnight = mktime(23, 59, 59, $checkout_info['mon'], $checkout_info['mday'], $checkout_info['year']);
1078 if (time() < $checkout_midnight) {
1079 if ((stripos($plain_log, 'card number') !== false && strpos($plain_log, '****') !== false) || !strcasecmp($channel_source, 'Booking.com')) {
1080 /*
1081 * Log contains credit card details.
1082 * Build the URI for the administrator section of VCM according to the platform.
1083 */
1084 $exec_pcid_uri = VBOFactory::getPlatform()->getUri()->admin('index.php?option=com_vikchannelmanager&task=execpcid&channel_source=' . $channel_source . '&otaid=' . $order['idorderota'] . '&tmpl=component', false);
1085 ?>
1086 var pci_vcm_frame = '<iframe src="<?php echo $exec_pcid_uri; ?>"></iframe>';
1087 vbo_overlay_data['paymentlog'] = '<div class="vcm-notif-pcidrq-container">'+
1088 '<button type="button" class="btn vbo-config-btn vcm-pcid-launch" onclick="vboUpdateModal(\'<?php echo addslashes(JText::translate('VBPAYMENTLOGTOGGLE')); ?>\', pci_vcm_frame, false);">'+
1089 '<?php VikBookingIcons::e('credit-card'); ?>'+
1090 '<?php echo addslashes(JText::translate('GETFULLCARDDETAILS')); ?>'+
1091 '</button>'+
1092 '</div>'+
1093 vbo_overlay_data['paymentlog'];
1094 <?php
1095 }
1096 }
1097 }
1098 //
1099 }
1100 if (count($customer) && !empty($customer['notes'])) {
1101 $customer['notes'] = VikBooking::strTrimLiteral(nl2br(htmlspecialchars($customer['notes'])));
1102 ?>
1103 vbo_overlay_data['customer_notes'] = '<pre><?php echo addslashes($customer['notes']); ?></pre>';
1104 <?php
1105 }
1106 if (count($customer)) {
1107 $displayable_fields = array(
1108 'first_name' => JText::translate('VBCUSTOMERFIRSTNAME'),
1109 'last_name' => JText::translate('VBCUSTOMERLASTNAME'),
1110 'company' => JText::translate('VBCUSTOMERCOMPANY'),
1111 'vat' => JText::translate('VBCUSTOMERCOMPANYVAT'),
1112 'email' => JText::translate('VBCUSTOMEREMAIL'),
1113 'phone' => JText::translate('VBCUSTOMERPHONE'),
1114 'address' => JText::translate('VBCUSTOMERADDRESS'),
1115 'city' => JText::translate('VBCUSTOMERCITY'),
1116 'zip' => JText::translate('VBCUSTOMERZIP'),
1117 'country' => JText::translate('VBCUSTOMERCOUNTRY'),
1118 'gender' => JText::translate('VBCUSTOMERGENDER'),
1119 'bdate' => JText::translate('VBCUSTOMERBDATE'),
1120 'pbirth' => JText::translate('VBCUSTOMERPBIRTH'),
1121 'doctype' => JText::translate('VBCUSTOMERDOCTYPE'),
1122 'docnum' => JText::translate('VBCUSTOMERDOCNUM')
1123 );
1124 /**
1125 * We use a link rather than a button to support the
1126 * modal navigation through AJAX on both J and WP.
1127 */
1128 ?>
1129 vbo_overlay_data['customer_info'] = '<a class="btn btn-primary pull-right" href="index.php?option=com_vikbooking&task=editcustomer&cid[]=<?php echo $customer['id'].'&checkin=1&bid='.$order['id'].($tmpl == 'component' ? '&tmpl=component' : ''); ?>"><i class="vboicn-profile"></i> <?php echo addslashes(JText::translate('VBMAINCUSTOMEREDIT')); ?></a>'+
1130 '<div class="vbo-checkin-custdet-cont">'+
1131 <?php
1132 foreach ($displayable_fields as $k => $v) {
1133 $customer_val = isset($customer[$k]) && !empty($customer[$k]) ? addslashes(VikBooking::strTrimLiteral(nl2br(htmlspecialchars($customer[$k])))) : '---';
1134 ?>
1135 '<div class="vbo-checkin-custdet-entry">'+
1136 '<span class="vbo-checkin-custdet-key<?php echo (!isset($customer[$k]) || empty($customer[$k])) && in_array($k, $sensible_k) ? ' vbo-checkin-custdet-key-warn' : ''; ?>"><?php echo addslashes(JText::translate($v)); ?></span>'+
1137 '<span class="vbo-checkin-custdet-value"><?php echo $customer_val; ?></span>'+
1138 '</div>'+
1139 <?php
1140 }
1141 ?>
1142 '</div>';
1143 <?php
1144 }
1145 if (!empty($set_parent_status)) {
1146 /**
1147 * This function supports the admin widgets arriving today and departing today.
1148 */
1149 ?>
1150 if (jQuery('[data-status="<?php echo $order['id']; ?>"]', window.parent.document).length) {
1151 jQuery('[data-status="<?php echo $order['id']; ?>"]', window.parent.document).html('<?php echo str_replace("'", "", $set_parent_status); ?>');
1152 }
1153 <?php
1154 }
1155 ?>
1156 </script>
1157 <script type="text/javascript">
1158 /* Global Variables and Functions */
1159 var vbo_overlay_on = false;
1160 var booking_total = <?php echo (float)$order['total']; ?>;
1161 var tot_rooms = <?php echo (int)$order['roomsnum']; ?>;
1162 var current_checked = <?php echo (int)$order['checked']; ?>;
1163
1164 function vboOpenModal() {
1165 <?php
1166 if (VBOPlatformDetection::isWordPress()) {
1167 ?>
1168 /**
1169 * @wponly - we are inside the same parent page as the modal is loaded via Ajax.
1170 * We need to select the values from the modal container.
1171 */
1172 jQuery('.modal-body').find(".vbo-info-overlay-block").fadeToggle(400, function() {
1173 if (jQuery('.modal-body').find(".vbo-info-overlay-block").is(":visible")) {
1174 vbo_overlay_on = true;
1175 } else {
1176 vbo_overlay_on = false;
1177 jQuery('.modal-body').find('.vbo-overlay-checkin-body').html('');
1178 }
1179 });
1180 <?php
1181 } else {
1182 ?>
1183 jQuery(".vbo-info-overlay-block").fadeToggle(400, function() {
1184 if (jQuery(".vbo-info-overlay-block").is(":visible")) {
1185 vbo_overlay_on = true;
1186 } else {
1187 vbo_overlay_on = false;
1188 jQuery('.vbo-overlay-checkin-body').html('');
1189 }
1190 });
1191 <?php
1192 }
1193 ?>
1194 }
1195
1196 function vboUpdateModal(title, body, call_toggle) {
1197 <?php
1198 if (VBOPlatformDetection::isWordPress()) {
1199 ?>
1200 /**
1201 * @wponly - we are inside the same parent page as the modal is loaded via Ajax.
1202 * We need to select the values from the modal container.
1203 */
1204 var keep_closing_btn = jQuery('.modal-body').find('#vbo-overlay-title').find('.vbo-info-overlay-title-close').html();
1205 jQuery('.modal-body').find('#vbo-overlay-title').html(title + '<span class="vbo-info-overlay-title-close">' + keep_closing_btn + '</span>');
1206 if (body.substr(0, 1) == '.') {
1207 //look for this value inside the global array
1208 body = body.substr(1, (body.length - 1));
1209 if (vbo_overlay_data.hasOwnProperty(body)) {
1210 body = vbo_overlay_data[body];
1211 }
1212 }
1213 jQuery('.modal-body').find('.vbo-overlay-checkin-body').html(body);
1214 if (call_toggle) {
1215 vboOpenModal();
1216 }
1217 /**
1218 * @wponly - the customer_info 'body' has a link to another page, which must be manually
1219 * registered for preventing the browser to follow it and make the Ajax request instead.
1220 */
1221 var parent_modal_id = jQuery('.modal-body').find('.vbo-overlay-checkin-body').closest('.modal').attr('id');
1222 ajaxPreventFormSubmit(parent_modal_id);
1223 <?php
1224 } else {
1225 ?>
1226 var keep_closing_btn = jQuery('#vbo-overlay-title').find('.vbo-info-overlay-title-close').html();
1227 jQuery('#vbo-overlay-title').html(title + '<span class="vbo-info-overlay-title-close">' + keep_closing_btn + '</span>');
1228 if (body.substr(0, 1) == '.') {
1229 //look for this value inside the global array
1230 body = body.substr(1, (body.length - 1));
1231 if (vbo_overlay_data.hasOwnProperty(body)) {
1232 body = vbo_overlay_data[body];
1233 }
1234 }
1235 jQuery('.vbo-overlay-checkin-body').html(body);
1236 if (call_toggle) {
1237 vboOpenModal();
1238 }
1239 <?php
1240 }
1241 ?>
1242 }
1243
1244 function vboToggleCheckinNotes() {
1245 jQuery('.vbo-checkin-notes-cont').toggle();
1246 }
1247
1248 function vboSetCheckinAction(action) {
1249 jQuery('#vbo-checkin-action').val(action);
1250 if (action > 0) {
1251 //check if guests details were filled in for check-in/out actions
1252 var guests_filled = true;
1253 for (var i = 0; i < tot_rooms; i++) {
1254 var elem = jQuery(".vbo-roomdet-guests-toggle[data-roomind='"+i+"']");
1255 if (elem.length && elem.hasClass('vbo-guestscount-incomplete')) {
1256 guests_filled = false;
1257 break;
1258 }
1259 }
1260 if (!guests_filled) {
1261 if (confirm('<?php echo addslashes(JText::translate('VBOCHECKINACTCONFGUESTS')) ?>')) {
1262 jQuery('#adminForm').submit();
1263 }
1264 return true;
1265 }
1266 }
1267 jQuery('#adminForm').submit();
1268 }
1269
1270 if (typeof jQuery.fn.tooltip === 'function') {
1271 jQuery(".hasTooltip").tooltip();
1272 } else {
1273 jQuery.fn.tooltip = function(){};
1274 }
1275
1276 jQuery(function() {
1277 /* Guests Details events - Start */
1278 var focused = null;
1279 jQuery('.vbo-roomdet-guests-toggle').focus(function(e) {
1280 // focus event will be fired before the click event
1281 focused = null;
1282 e.stopPropagation();
1283 e.preventDefault();
1284 var roomind = jQuery(this).attr('data-roomind');
1285 var elem = jQuery('#vbo-roomdet-guests-details-'+roomind);
1286 if (elem.length && elem.is(':hidden')) {
1287 focused = '#vbo-roomdet-guests-details-'+roomind;
1288 elem.slideDown();
1289 }
1290 });
1291 jQuery('.vbo-roomdet-guests-toggle').click(function(e) {
1292 // click event will be fired after the focus event
1293 var roomind = jQuery(this).attr('data-roomind');
1294 var elem = jQuery('#vbo-roomdet-guests-details-'+roomind);
1295 if (!elem.length || focused == '#vbo-roomdet-guests-details-'+roomind) {
1296 // focus event has already displayed the content
1297 focused = null;
1298 return;
1299 }
1300 elem.slideToggle();
1301 });
1302 jQuery('.vbo-paxfield').keyup(function() {
1303 var cur_gind = jQuery(this).attr('data-gind');
1304 var roomind = jQuery(this).closest('.vbo-roomdet-guest-details').attr('data-roomind');
1305 var tot_room_guests = parseInt(jQuery(this).closest('.vbo-roomdet-guest-details').attr('data-totguests'));
1306 if (!cur_gind.length || isNaN(tot_room_guests) || !jQuery(this).hasClass('vbo-paxfield-'+roomind)) {
1307 return true;
1308 }
1309 var cur_val = jQuery(this).val();
1310 var tot_full_guests = 0;
1311 for (var i = 1; i <= tot_room_guests; i++) {
1312 var fullfilled = true;
1313 jQuery(".vbo-paxfield-"+roomind+"[data-gind='"+i+"']").each(function(k, v) {
1314 if (!jQuery(this).val().length) {
1315 fullfilled = false;
1316 }
1317 });
1318 if (fullfilled) {
1319 tot_full_guests++;
1320 }
1321 }
1322 if (tot_full_guests >= tot_room_guests) {
1323 var add_class = 'vbo-guestscount-complete';
1324 var rm_class = 'vbo-guestscount-incomplete';
1325 var ico_add_class = 'vboicn-user-check';
1326 var ico_rm_class = 'vboicn-user-plus';
1327 } else {
1328 var add_class = 'vbo-guestscount-incomplete';
1329 var rm_class = 'vbo-guestscount-complete';
1330 var ico_add_class = 'vboicn-user-plus';
1331 var ico_rm_class = 'vboicn-user-check';
1332 }
1333 jQuery('#vbo-guestscount-'+roomind).text(tot_full_guests).closest('.vbo-roomdet-guests-toggle').addClass(add_class).removeClass(rm_class).find('i').addClass(ico_add_class).removeClass(ico_rm_class);
1334 });
1335 /* Guests Details events - End */
1336 /* Overlay for Customer Notes, Booking Notes, Payment Logs - Start */
1337 jQuery(document).mouseup(function(e) {
1338 if (!vbo_overlay_on) {
1339 return;
1340 }
1341 var vbo_overlay_cont = jQuery(".vbo-info-overlay-content");
1342 if (!vbo_overlay_cont.is(e.target) && vbo_overlay_cont.has(e.target).length === 0) {
1343 jQuery(".vbo-info-overlay-block").fadeOut();
1344 vbo_overlay_on = false;
1345 }
1346 });
1347 jQuery(document).keyup(function(e) {
1348 if (e.keyCode == 27 && vbo_overlay_on) {
1349 jQuery(".vbo-info-overlay-block").fadeOut();
1350 vbo_overlay_on = false;
1351 }
1352 });
1353 /* Overlay for Customer Notes, Booking Notes, Payment Logs - End */
1354 /* Update amount paid and remaining balance */
1355 jQuery('#newtotpaid').change(function() {
1356 if (!jQuery('#vbo-checkin-remaining').length) {
1357 return true;
1358 }
1359 var cur_val = parseFloat(jQuery(this).val());
1360 if (!(cur_val > 0)) {
1361 return true;
1362 }
1363 var new_val = booking_total - cur_val;
1364 jQuery('#vbo-checkin-remaining').text(new_val.toFixed(2));
1365 });
1366 });
1367 </script>
1368