PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.9
VikBooking Hotel Booking Engine & PMS v1.6.9
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 / editorder / tmpl / default.php

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

3,231 lines 138.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 $row = $this->row;
14 $rooms = $this->rooms;
15 $busy = $this->busy;
16 $customer = $this->customer;
17 $payments = $this->payments;
18
19 $history_obj = VikBooking::getBookingHistoryInstance($row['id']);
20
21 // availability helper
22 $av_helper = VikBooking::getAvailabilityInstance();
23
24 // load datepicker for all CMS compatibility
25 JHtml::fetch('stylesheet', VBO_SITE_URI.'resources/jquery-ui.min.css');
26 JHtml::fetch('jquery.framework', true, true);
27 JHtml::fetch('script', VBO_SITE_URI.'resources/jquery-ui.min.js');
28
29 // js lang def
30 JText::script('VBO_CONV_RES_OTA_CURRENCY_APPLY');
31 JText::script('VBDELCONFIRM');
32 JText::script('VBSENDCANCORDEMAIL');
33 JText::script('VBO_SET_STANDBY');
34 JText::script('VBO_CONF_RM_OVERBOOKING_FLAG');
35
36 $dbo = JFactory::getDbo();
37
38 $vbo_app = VikBooking::getVboApplication();
39 $vbo_app->loadVisualEditorAssets();
40
41 /**
42 * This View can render within a modal the "bookingcheckin" View, and with WP
43 * this is loaded via AJAX. In order to not interfere or reset the contextual menu,
44 * we load the assets from the parent View. Context menu may also be used in this View.
45 *
46 * @since 1.16.0 (J) - 1.6.0 (WP)
47 */
48 $vbo_app->loadContextMenuAssets();
49 if (VBOPlatformDetection::isWordPress()) {
50 JText::script('VBRENTALORD');
51 JText::script('VBPVIEWORDERSPEOPLE');
52 }
53
54 $canDo = JFactory::getUser();
55 $vbo_auth_bookings = $canDo->authorise('core.vbo.bookings', 'com_vikbooking');
56
57 $currencyname = VikBooking::getCurrencyName();
58 $currencysymb = VikBooking::getCurrencySymb();
59 $after_tax = VikBooking::ivaInclusa();
60 $nowdf = VikBooking::getDateFormat(true);
61 if ($nowdf == "%d/%m/%Y") {
62 $df = 'd/m/Y';
63 } elseif ($nowdf == "%m/%d/%Y") {
64 $df = 'm/d/Y';
65 } else {
66 $df = 'Y/m/d';
67 }
68 $datesep = VikBooking::getDateSeparator(true);
69 $vbo_modals_html = array();
70 $payment = VikBooking::getPayment($row['idpayment']);
71 $pactive_tab = VikRequest::getString('vbo_active_tab', 'vbo-tab-details', 'request');
72 $printreceipt = VikRequest::getInt('print', 0, 'request');
73 $printreceipt = ($printreceipt > 0);
74 if ($printreceipt) {
75 //we set a different page title when printing the receipt for the "PDF Printer" to give the file a good name.
76 JFactory::getDocument()->setTitle(VikBooking::getFrontTitle()." - ".JText::translate('VBOFISCRECEIPT')." #".$row['id']);
77 }
78 $gotouri = 'index.php?option=com_vikbooking&task=editorder&cid[]='.$row['id'];
79
80 if ($row['status'] == "confirmed") {
81 $use_js_bid = $row['id'];
82 JFactory::getDocument()->addScriptDeclaration(
83 <<<JS
84 window["vbo_current_bid"] = $use_js_bid;
85 JS
86 );
87 }
88
89 $tars = array();
90 $arrpeople = array();
91 $is_package = !empty($row['pkg']) ? true : false;
92 $is_cust_cost = false;
93 foreach ($rooms as $ind => $or) {
94 $num = $ind + 1;
95 $arrpeople[$num]['adults'] = $or['adults'];
96 $arrpeople[$num]['children'] = $or['children'];
97 $arrpeople[$num]['children_age'] = $or['childrenage'];
98 $arrpeople[$num]['t_first_name'] = $or['t_first_name'];
99 $arrpeople[$num]['t_last_name'] = $or['t_last_name'];
100 $arrpeople[$num]['pets'] = $or['pets'];
101 if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
102 //package or custom cost set from the back-end
103 $is_cust_cost = true;
104 continue;
105 }
106 $q = "SELECT * FROM `#__vikbooking_dispcost` WHERE `id`=".(int)$or['idtar'].";";
107 $dbo->setQuery($q);
108 $tar = $dbo->loadAssocList();
109 $tar = VikBooking::applySeasonsRoom($tar, $row['checkin'], $row['checkout']);
110
111 // apply OBP rules
112 $tar = VBORoomHelper::getInstance()->applyOBPRules($tar, $or, $or['adults']);
113
114 $tars[$num] = $tar;
115 }
116 $pcheckin = $row['checkin'];
117 $pcheckout = $row['checkout'];
118 $secdiff = $pcheckout - $pcheckin;
119 $daysdiff = $secdiff / 86400;
120 if (is_int($daysdiff)) {
121 if ($daysdiff < 1) {
122 $daysdiff = 1;
123 }
124 } else {
125 if ($daysdiff < 1) {
126 $daysdiff = 1;
127 } else {
128 $sum = floor($daysdiff) * 86400;
129 $newdiff = $secdiff - $sum;
130 $maxhmore = VikBooking::getHoursMoreRb() * 3600;
131 if ($maxhmore >= $newdiff) {
132 $daysdiff = floor($daysdiff);
133 } else {
134 $daysdiff = ceil($daysdiff);
135 }
136 }
137 }
138 $otachannel = '';
139 $otachannel_name = '';
140 $otachannel_bid = '';
141 $otacurrency = '';
142 if (!empty($row['channel'])) {
143 $channelparts = explode('_', $row['channel']);
144 $otachannel = array_key_exists(1, $channelparts) && strlen($channelparts[1]) > 0 ? $channelparts[1] : ucwords($channelparts[0]);
145 $otachannel_name = $otachannel;
146 $otachannel_bid = $otachannel.(!empty($row['idorderota']) ? ' - Booking ID: '.$row['idorderota'] : '');
147 if (strstr($otachannel, '.') !== false) {
148 $otaccparts = explode('.', $otachannel);
149 $otachannel = $otaccparts[0];
150 }
151 $otacurrency = strlen($row['chcurrency']) > 0 ? $row['chcurrency'] : '';
152 }
153
154 $status_type = '';
155 if (!empty($row['type'])) {
156 $status_type = JText::translate('VBO_BTYPE_' . strtoupper($row['type']));
157 if (!strcasecmp($row['type'], 'overbooking')) {
158 $status_type = '<span class="label label-error vbo-label-nested vbo-label-overbooking">' . $status_type . '</span>';
159 }
160 $status_type .= ' / ';
161 }
162 $extra_status = $row['refund'] > 0 ? ' / ' . JText::translate('VBO_STATUS_REFUNDED') : '';
163 if ($row['status'] == "confirmed") {
164 $saystaus = '<span class="label label-success">' . $status_type . JText::translate('VBCONFIRMED') . $extra_status . '</span>';
165 } elseif ($row['status'] == "standby") {
166 $saystaus = '<span class="label label-warning">' . $status_type . JText::translate('VBSTANDBY') . $extra_status . '</span>';
167 } else {
168 $saystaus = '<span class="label label-error">' . $status_type . JText::translate('VBCANCELLED') . $extra_status . '</span>';
169 }
170
171 // extend booking details main panel
172 $bookingPanelForms = $this->onDisplayView();
173
174 // extend booking details sidebar
175 $bookingSidebarForms = $this->onDisplayView('Sidebar');
176
177 // extend administration main panel
178 $adminFormsSetup = new stdClass;
179 $adminFormsSetup->icons = [];
180 $adminPanelForms = $this->onDisplayView('Administration', $adminFormsSetup);
181
182 // extend administration sidebar
183 $adminSidebarForms = $this->onDisplayView('AdministrationSidebar');
184
185 //Prepare modal (used for the Registration and for reconstructing the credit card details through the channel manager)
186 echo $vbo_app->getJmodalScript();
187 //end Prepare modal
188 ?>
189 <script type="text/javascript">
190 function changePayment() {
191 var newpayment = document.getElementById('newpayment').value;
192 if (newpayment != '') {
193 var paymentname = document.getElementById('newpayment').options[document.getElementById('newpayment').selectedIndex].text;
194 if (confirm('<?php echo addslashes(JText::translate('VBCHANGEPAYCONFIRM')); ?>' + paymentname + '?')) {
195 document.adminForm.submit();
196 } else {
197 document.getElementById('newpayment').selectedIndex = 0;
198 }
199 }
200 }
201 function vbToggleLog(elem) {
202 vbToggleDynamicPanel(elem, '#vbpaymentlogdiv');
203 }
204 function vbToggleNotes(elem) {
205 vbToggleDynamicPanel(elem, '#vbadminnotesdiv');
206 }
207 function vbToggleHistory(elem) {
208 vbToggleDynamicPanel(elem, '#vbhistorydiv');
209 }
210 function vbToggleInvNotes(elem) {
211 vbToggleDynamicPanel(elem, '#vbinvnotesdiv');
212 }
213 function vbToggleMessaging(elem) {
214 vbToggleDynamicPanel(elem, '#vbmessagingdiv');
215 if (typeof VCMChat !== 'undefined') {
216 VCMChat.getInstance().scrollToBottom();
217 }
218 }
219 function vbToggleDynamicPanel(elem, target) {
220 if (jQuery(target).is(':visible')) {
221 return;
222 }
223
224 jQuery(".vbo-bookingdet-noteslogs-btn-active").removeClass("vbo-bookingdet-noteslogs-btn-active");
225
226 jQuery('.vbo-extra-panel').hide();
227 jQuery(target).show();
228
229 jQuery(elem).parent(".vbo-bookingdet-noteslogs-btn").addClass("vbo-bookingdet-noteslogs-btn-active");
230
231 if (typeof sessionStorage !== 'undefined') {
232 sessionStorage.setItem('vboEditOrderTab<?php echo $row['id']; ?>', jQuery(elem).parent().data('id'));
233 }
234 }
235 function toggleDiscount(elem) {
236 var discsp = document.getElementById('vbdiscenter').style.display;
237 if (discsp == 'block') {
238 document.getElementById('vbdiscenter').style.display = 'none';
239 jQuery(elem).find('i').attr('class', '<?php echo VikBookingIcons::i('chevron-down'); ?>');
240 } else {
241 document.getElementById('vbdiscenter').style.display = 'block';
242 jQuery(elem).find('i').attr('class', '<?php echo VikBookingIcons::i('chevron-up'); ?>');
243 }
244 }
245 </script>
246
247 <div class="vbo-bookingdet-topcontainer">
248 <form name="adminForm" id="adminForm" action="<?php echo VBOPlatformDetection::isWordPress() ? 'admin.php' : 'index.php'; ?>?option=com_vikbooking&amp;task=editorder&amp;cid[]=<?php echo $row['id']; ?>" method="post">
249 <?php
250 if ($printreceipt) {
251 //print the company details
252 $companylogo = VikBooking::getSiteLogo();
253 $next_receipt = VikBooking::getNextReceiptNumber($row['id']);
254 ?>
255 <div class="vbo-receipt-company-block-outer">
256 <div class="vbo-receipt-company-block">
257 <?php
258 if (!empty($companylogo)) {
259 ?>
260 <div class="vbo-receipt-company-logo"><img src="<?php echo VBO_ADMIN_URI.'resources/'.$companylogo; ?>" /></div>
261 <?php
262 }
263 ?>
264 <div class="vbo-receipt-company-info"><?php echo VikBooking::getInvoiceCompanyInfo(); ?></div>
265 </div>
266 <div class="vbo-receipt-numdate-block">
267 <div class="vbo-receipt-numdate-inner">
268 <div class="vbo-receipt-numdate-title">
269 <span><?php echo JText::translate('VBOFISCRECEIPT'); ?></span>
270 <span style="float: right; cursor: pointer; color: #ff0000;" onclick="vboMakePrintOnly();"><?php VikBookingIcons::e('times-circle'); ?></span>
271 </div>
272 <div class="vbo-receipt-numdate-num">
273 <span class="vbo-receipt-numdate-num-lbl"><?php echo JText::translate('VBOFISCRECEIPTNUM'); ?></span>
274 <span class="vbo-receipt-numdate-num-val">
275 <span class="vbo-showin-print" id="vbo-receipt-num"><?php echo $next_receipt; ?></span>
276 <input class="vbo-hidein-print" id="vbo-receipt-num-inp" type="number" min="0" value="<?php echo $next_receipt; ?>" onchange="document.getElementById('vbo-receipt-num').innerText = this.value;" />
277 </span>
278 </div>
279 <div class="vbo-receipt-numdate-date">
280 <span class="vbo-receipt-numdate-date-lbl"><?php echo JText::translate('VBOFISCRECEIPTDATE'); ?></span>
281 <span class="vbo-receipt-numdate-date-val"><?php echo date(str_replace("/", $datesep, $df)); ?></span>
282 </div>
283 </div>
284 </div>
285 <div class="vbo-receipt-print-confirm vbo-hidein-print">
286 <div class="vbo-receipt-print-btn">
287 <span onclick="vboLaunchPrintReceipt();">
288 <?php VikBookingIcons::e('print'); ?>
289 <span id="vbo-receipt-print-btn-name"><?php echo JText::translate('VBOPRINTRECEIPT'); ?></span>
290 </span>
291 </div>
292 </div>
293 </div>
294 <?php
295 }
296 ?>
297
298 <div class="vbo-bookdet-container">
299 <div class="vbo-bookdet-wrap">
300 <div class="vbo-bookdet-head">
301 <span>ID</span>
302 </div>
303 <div class="vbo-bookdet-foot">
304 <span><?php echo $row['id']; ?></span>
305 </div>
306 </div>
307 <div class="vbo-bookdet-wrap">
308 <div class="vbo-bookdet-head">
309 <span><?php echo JText::translate('VBEDITORDERONE'); ?></span>
310 </div>
311 <div class="vbo-bookdet-foot">
312 <span><?php echo date(str_replace("/", $datesep, $df).' H:i', $row['ts']); ?></span>
313 </div>
314 </div>
315 <?php
316 if (!$printreceipt && count($customer)) {
317 ?>
318 <div class="vbo-bookdet-wrap">
319 <div class="vbo-bookdet-head">
320 <span><?php echo JText::translate('VBCUSTOMERNOMINATIVE'); ?></span>
321 </div>
322 <div class="vbo-bookdet-foot">
323 <div class="vbo-customer-info-box">
324 <div class="vbo-customer-info-box-name">
325 <?php echo (isset($customer['country_img']) ? $customer['country_img'] . ' ' : ''); ?>
326
327 <?php if ($canDo->authorise('core.edit', 'com_vikbooking') && $canDo->authorise('core.vbo.management', 'com_vikbooking')): ?>
328 <a href="index.php?option=com_vikbooking&task=editcustomer&cid[]=<?php echo $customer['id']; ?>&goto=<?php echo base64_encode($gotouri); ?>"><?php echo ltrim($customer['first_name'] . ' ' . $customer['last_name']); ?></a>
329 <?php else: ?>
330 <?php echo ltrim($customer['first_name'] . ' ' . $customer['last_name']); ?>
331 <?php endif; ?>
332 </div>
333 <?php
334 if (!empty($customer['pic'])) {
335 $avatar_caption = ltrim($customer['first_name'] . ' ' . $customer['last_name']);
336 ?>
337 <div class="vbo-customer-info-box-avatar vbo-customer-avatar-small">
338 <span>
339 <img src="<?php echo strpos($customer['pic'], 'http') === 0 ? $customer['pic'] : VBO_SITE_URI . 'resources/uploads/' . $customer['pic']; ?>" data-caption="<?php echo htmlspecialchars($avatar_caption); ?>" />
340 </span>
341 </div>
342 <?php
343 }
344 ?>
345 </div>
346 </div>
347 </div>
348 <?php
349 }
350 if (!$printreceipt) {
351 ?>
352 <div class="vbo-bookdet-wrap">
353 <div class="vbo-bookdet-head">
354 <span><?php echo JText::translate('VBEDITORDERROOMSNUM'); ?></span>
355 </div>
356 <div class="vbo-bookdet-foot">
357 <?php echo $row['roomsnum']; ?>
358 </div>
359 </div>
360 <?php
361 }
362 ?>
363 <div class="vbo-bookdet-wrap">
364 <div class="vbo-bookdet-head">
365 <span><?php echo JText::translate('VBEDITORDERFOUR'); ?></span>
366 </div>
367 <div class="vbo-bookdet-foot">
368 <span><?php echo $row['days']; ?></span>
369 <?php
370 if ($row['split_stay']) {
371 ?>
372 <span class="hasTooltip" title="<?php echo JHtml::fetch('esc_attr', JText::translate('VBO_SPLIT_STAY')); ?>"><?php VikBookingIcons::e('random'); ?></span>
373 <?php
374 }
375 ?>
376 </div>
377 </div>
378 <div class="vbo-bookdet-wrap">
379 <div class="vbo-bookdet-head">
380 <span><?php echo JText::translate('VBEDITORDERFIVE'); ?></span>
381 </div>
382 <div class="vbo-bookdet-foot">
383 <?php
384 $checkin_info = getdate($row['checkin']);
385 $short_wday = JText::translate('VB'.strtoupper(substr($checkin_info['weekday'], 0, 3)));
386 ?>
387 <?php echo $short_wday.', '.date(str_replace("/", $datesep, $df).' H:i', $row['checkin']); ?>
388 </div>
389 </div>
390 <div class="vbo-bookdet-wrap">
391 <div class="vbo-bookdet-head">
392 <span><?php echo JText::translate('VBEDITORDERSIX'); ?></span>
393 </div>
394 <div class="vbo-bookdet-foot">
395 <?php
396 $checkout_info = getdate($row['checkout']);
397 $short_wday = JText::translate('VB'.strtoupper(substr($checkout_info['weekday'], 0, 3)));
398 ?>
399 <?php echo $short_wday.', '.date(str_replace("/", $datesep, $df).' H:i', $row['checkout']); ?>
400 </div>
401 </div>
402 <?php
403 if (!$printreceipt && $vbo_auth_bookings && $row['closure'] != 1 && $row['status'] == 'confirmed') {
404 // we don't need to check in the IF above "&& $row['checked'] != 0" because the registration is useful for all bookings.
405 $checked_btn = 'btn-primary';
406 switch ($row['checked']) {
407 case -1:
408 $checked_status = JText::translate('VBOCHECKEDSTATUSNOS');
409 $checked_btn = 'btn-danger';
410 break;
411 case 1:
412 $checked_status = JText::translate('VBOCHECKEDSTATUSIN');
413 $checked_btn = 'btn-success';
414 break;
415 case 2:
416 $checked_status = JText::translate('VBOCHECKEDSTATUSOUT');
417 $checked_btn = 'btn-warning';
418 break;
419 default:
420 $checked_status = JText::translate('VBOCHECKEDSTATUSZERO');
421 if (count($customer) && isset($customer['pax_data']) && !empty($customer['pax_data'])) {
422 // pre check-in performed via front-end
423 $checked_status = JText::translate('VBOCHECKEDSTATUSPRECHECKIN');
424 }
425 break;
426 }
427 ?>
428 <div class="vbo-bookdet-wrap pro-feature">
429 <div class="vbo-bookdet-head">
430 <span><?php echo JText::translate('VBOCHECKEDSTATUS'); ?></span>
431 </div>
432 <div class="vbo-bookdet-foot">
433 <button type="button" class="btn btn-small <?php echo $checked_btn; ?>" onclick="vboOpenJModal('vbo-checkin-booking', 'index.php?option=com_vikbooking&task=bookingcheckin&cid[]=<?php echo $row['id']; ?>&tmpl=component');">
434 <?php echo $checked_status; ?>
435 </button>
436 </div>
437 </div>
438 <?php
439 //Prepare modal (Registration)
440 array_push($vbo_modals_html, $vbo_app->getJmodalHtml('vbo-checkin-booking', JText::translate('VBOMANAGECHECKSINOUT')));
441 //end Prepare modal
442 }
443
444 /**
445 * Check whether the booking can be refunded.
446 *
447 * @since 1.14 (J) - 1.4.0 (WP)
448 */
449
450 // refundable up to 7 days after check-out day
451 $max_refund_ts = mktime(23, 59, 59, $checkout_info['mon'], ($checkout_info['mday'] + 7), $checkout_info['year']);
452 // current payment driver must be set
453 $tn_driver = is_array($payment) ? $payment['file'] : null;
454 // transaction data validation callback
455 $tn_data_callback = function($data) use ($tn_driver) {
456 return (is_object($data) && isset($data->driver) && basename($data->driver, '.php') == basename($tn_driver, '.php'));
457 };
458 $prev_tn_data = $history_obj->getEventsWithData(array('P0', 'PN'), $tn_data_callback);
459 $refundable = ($row['status'] != 'standby' && $max_refund_ts >= time() && is_array($prev_tn_data) && count($prev_tn_data));
460 if ($refundable) {
461 // prepare modal (refundtn) with a custom function to trigger the opening
462 array_push($vbo_modals_html, $vbo_app->getJmodalHtml('vbo-refund-tn', JText::translate('VBO_ISSUE_REFUND')));
463 echo $vbo_app->getJmodalScript('Refund', 'vboDetectRefundChanges();');
464 // count the number of refunds made
465 $refunds = $history_obj->getEventsWithData('RF', null, false);
466 $refunds = !is_array($refunds) ? array() : $refunds;
467 ?>
468 <script type="text/javascript">
469 var vbo_refund_performed = false;
470 function vboDetectRefundChanges() {
471 if (vbo_refund_performed === true) {
472 location.reload();
473 }
474 }
475 </script>
476
477 <div class="vbo-bookdet-wrap">
478 <div class="vbo-bookdet-head">
479 <span><?php echo JText::translate('VBO_ISSUE_REFUND'); ?></span>
480 </div>
481 <div class="vbo-bookdet-foot">
482 <button type="button" class="btn btn-small btn-danger vbo-dorefund-btn"<?php echo count($refunds) ? ' data-totrefunds="' . count($refunds) . '"' : ''; ?> onclick="vboOpenJModalRefund('vbo-refund-tn', 'index.php?option=com_vikbooking&task=refundtn&cid[]=<?php echo $row['id']; ?>&tmpl=component');">
483 <?php echo JText::translate('VBO_REFUND'); ?>
484 </button>
485 </div>
486 </div>
487 <?php
488 }
489 //
490
491 if (!$printreceipt && !empty($row['channel'])) {
492 $ota_logo_img = VikBooking::getVcmChannelsLogo($row['channel']);
493 if ($ota_logo_img === false) {
494 $ota_logo_img = $otachannel_name;
495 } else {
496 $ota_logo_img = '<img src="'.$ota_logo_img.'" class="vbo-channelimg-medium"/>';
497 }
498 ?>
499 <div class="vbo-bookdet-wrap">
500 <div class="vbo-bookdet-head">
501 <span><?php echo JText::translate('VBPVIEWORDERCHANNEL'); ?></span>
502 </div>
503 <div class="vbo-bookdet-foot">
504 <span><?php echo $ota_logo_img; ?></span>
505 </div>
506 </div>
507 <?php
508 } elseif (!$printreceipt && class_exists('VCMOtaBooking')) {
509 /**
510 * Vik Channel Manager booking assignable channels.
511 *
512 * @since 1.16.3 (J) - 1.6.3 (WP)
513 */
514 $assignable_channels = VCMOtaBooking::getInstance($row, true)->getChannelsAssignable();
515 if ($assignable_channels) {
516 JText::script('VBO_ASSIGN_BOOKING_TO_OTA_CONFIRM');
517 JFactory::getDocument()->addScriptDeclaration(
518 <<<JS
519 function vboConfirmAssignChannel(ch_key, ch_name) {
520 if (!ch_key || !ch_name) {
521 return true;
522 }
523 if (confirm(Joomla.JText._('VBO_ASSIGN_BOOKING_TO_OTA_CONFIRM').replace('%s', ch_name))) {
524 document.adminForm.submit();
525 return true;
526 } else {
527 return false;
528 }
529 }
530 JS
531 );
532 ?>
533 <div class="vbo-bookdet-wrap">
534 <div class="vbo-bookdet-head">
535 <span><?php echo JText::translate('VBPVIEWORDERCHANNEL'); ?></span>
536 </div>
537 <div class="vbo-bookdet-foot">
538 <select name="vcm_assign_channel" class="vbo-select-small" onchange="return vboConfirmAssignChannel(this.value, this.options[this.selectedIndex].text);">
539 <option value=""><?php echo JText::translate('VBORDFROMSITE'); ?></option>
540 <?php
541 foreach ($assignable_channels as $assign_ch_key => $assign_ch_name) {
542 ?>
543 <option value="<?php echo JHtml::fetch('esc_attr', $assign_ch_key); ?>"><?php echo $assign_ch_name; ?></option>
544 <?php
545 }
546 ?>
547 </select>
548 </div>
549 </div>
550 <?php
551 }
552 }
553 if (!$printreceipt) {
554 ?>
555 <div class="vbo-bookdet-wrap">
556 <div class="vbo-bookdet-head">
557 <span><?php echo JText::translate('VBSTATUS'); ?></span>
558 </div>
559 <div class="vbo-bookdet-foot">
560 <span><?php echo $saystaus; ?></span>
561 </div>
562 </div>
563 <?php
564 if (is_array($this->vcm_pre_approval)) {
565 ?>
566 <div class="vbo-bookdet-wrap">
567 <div class="vbo-bookdet-head">
568 <span><?php echo $this->vcm_pre_approval[1]; ?></span>
569 </div>
570 <div class="vbo-bookdet-foot">
571 <span>
572 <?php
573 if (empty($this->vcm_pre_approval[2]) || !empty($this->vcm_pre_approval[3])) {
574 // no pre-approvals before, or withdrawn before
575 ?>
576 <a href="index.php?option=com_vikchannelmanager&task=sendSpecialOffer&vbo_oid=<?php echo $row['id']; ?>&spo_type=preapproval&spo_action=send&ota_thread_id=<?php echo $this->vcm_pre_approval[0]; ?>" class="btn btn-small btn-primary vcm-btn-channel-<?php echo strtolower($this->vcm_pre_approval[1]); ?>"><?php VikBookingIcons::e('thumbs-up'); ?> <?php echo JText::translate('VBO_PREAPPROVE_INQUIRY'); ?></a>
577 <?php
578 } else {
579 // pre-approved before, pass the ID
580 ?>
581 <a href="index.php?option=com_vikchannelmanager&task=sendSpecialOffer&vbo_oid=<?php echo $row['id']; ?>&spo_type=preapproval&spo_action=withdraw&ota_thread_id=<?php echo $this->vcm_pre_approval[0]; ?>&spo_id=<?php echo $this->vcm_pre_approval[2]; ?>" class="btn btn-small btn-danger"><?php VikBookingIcons::e('thumbs-down'); ?> <?php echo JText::translate('VBO_WITHDRAW_PREAPPROVAL'); ?></a>
582 <?php
583 }
584 ?>
585 </span>
586 </div>
587 </div>
588 <?php
589 }
590 if (!empty($row['channel']) && stripos($row['channel'], 'booking.com') !== false && $row['checkin'] <= time() && strtotime('+ 7 days', $row['checkout']) >= time()) {
591 /**
592 * Guest misconduct reporting API for Booking.com.
593 * Only after reservation check-in date and no later than 7 days after check-out date.
594 *
595 * @since 1.13.5 - VCM 1.7.2
596 */
597 $misconduct_reported = $history_obj->hasEvent('GM');
598 ?>
599 <div class="vbo-bookdet-wrap">
600 <div class="vbo-bookdet-head">
601 <span><?php echo JText::translate('VBOGUESTMISCONDUCT'); ?></span>
602 </div>
603 <div class="vbo-bookdet-foot">
604 <?php
605 if ($misconduct_reported === false) {
606 // allow to report the guest misconduct
607 ?>
608 <button type="button" class="btn btn-small btn-danger" onclick="vboRenderGuestMisconduct();"><?php VikBookingIcons::e('user-slash'); ?> <?php echo JText::translate('VBOREPORTMISCONDUCT'); ?></button>
609 <?php
610 } else {
611 // guest misconduct already reported
612 ?>
613 <button type="button" class="btn btn-small btn-warning" onclick="vboShowGuestMisconductReported();"><?php VikBookingIcons::e('user-slash'); ?> <?php echo $misconduct_reported; ?></button>
614 <?php
615 }
616 ?>
617 <a id="vbo-gm-reloadlink" style="display: none;" href="index.php?option=com_vikbooking&task=editorder&cid[]=<?php echo $row['id']; ?>"></a>
618 </div>
619
620 <div class="vbo-modal-overlay-block vbo-modal-overlay-block-guestmisconduct">
621 <a class="vbo-modal-overlay-close" href="javascript: void(0);"></a>
622 <div class="vbo-modal-overlay-content vbo-modal-overlay-content-guestmisconduct">
623 <div class="vbo-modal-overlay-content-head vbo-modal-overlay-content-head-guestmisconduct">
624 <h3><?php VikBookingIcons::e('exclamation-circle'); ?> <?php echo JText::sprintf('VBOREPGUESTMISCONDUCTTO', 'Booking.com'); ?> <span class="vbo-modal-overlay-close-times" onclick="hideVboDialogGuestMisconduct();">&times;</span></h3>
625 </div>
626 <div class="vbo-modal-overlay-content-body">
627 <div class="vbo-modal-guestmisconduct-addnew" data-bid="<?php echo $row['id']; ?>" data-otabid="<?php echo $row['idorderota']; ?>">
628 <div class="vbo-modal-guestmisconduct-report-elems"></div>
629 <div class="vbo-modal-guestmisconduct-addnew-save">
630 <button type="button" id="vbo-guest-misconduct-submit-btn" class="btn btn-success" onclick="vboSubmitGuestMisconduct();" style="display: none;"><?php echo JText::translate('VBCHANNELMANAGERSENDRQ'); ?></button>
631 <button type="button" class="btn btn-secondary" onclick="hideVboDialogGuestMisconduct();"><?php echo JText::translate('VBOCLOSE'); ?></button>
632 </div>
633 </div>
634 </div>
635 </div>
636 </div>
637
638 <script type="text/javascript">
639 var vbodialogguestmisconduct_on = false;
640 var vbo_guest_misconduct_fields = new Array;
641
642 function vboShowGuestMisconductReported() {
643 // this is like simulating the navigation to the booking history tab
644 jQuery(".vbo-bookingdet-tab[data-vbotab='vbo-tab-admin']").trigger('click');
645 vbToggleHistory(document.getElementById('vbo-trig-bookhistory'));
646 }
647
648 function vboRenderGuestMisconduct() {
649 // empty content
650 jQuery('.vbo-modal-guestmisconduct-report-elems').html('<?php echo $this->escape(JText::translate('VIKLOADING') . '...'); ?>');
651 vbo_guest_misconduct_fields = new Array;
652
653 // display modal
654 jQuery('.vbo-modal-overlay-block-guestmisconduct').fadeIn();
655 vbodialogguestmisconduct_on = true;
656
657 // make AJAX request to VCM to always reload the form fields
658 VBOCore.doAjax(
659 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikchannelmanager&task=get_bcom_misconduct_categories'); ?>",
660 {
661 tmpl: "component"
662 },
663 (res) => {
664 // parse the JSON response that contains the categories object with all fields for the reporting
665 try {
666 var misconduct_fields_rs = JSON.parse(res);
667
668 // make sure the request was successful
669 if (!misconduct_fields_rs.status) {
670 alert(misconduct_fields_rs.error);
671 hideVboDialogGuestMisconduct();
672 return false;
673 }
674
675 // render form from response obtained
676 var misconduct_html = '';
677 var misconduct_fields = misconduct_fields_rs.data;
678 if (!misconduct_fields.hasOwnProperty('categories') || !misconduct_fields.hasOwnProperty('fields')) {
679 alert('Unexptected response. Vik Channel Manager needs to be installed, configured and updated to the latest version.');
680 hideVboDialogGuestMisconduct();
681 return false;
682 }
683
684 // main category of misconduct
685 misconduct_html += '<div class="vbo-modal-form-addnew-elem vbo-modal-guestmisconduct-addnew-elem">' + "\n";
686 misconduct_html += '<label for="vbo-gm-category">' + misconduct_fields['labels']['category'] + '</label>';
687 misconduct_html += '<select id="vbo-gm-category" data-gmname="category_id" onchange="vboGuestMisconductChangeCategory(this.value);">' + "\n";
688 for (var category in misconduct_fields['categories']) {
689 if (!misconduct_fields['categories'].hasOwnProperty(category)) {
690 continue;
691 }
692 misconduct_html += '<option value="' + misconduct_fields['categories'][category]['id'] + '">' + misconduct_fields['categories'][category]['title'] + '</option>' + "\n";
693 }
694 misconduct_html += '</select>' + "\n";
695 misconduct_html += '</div>' + "\n";
696 // push category field in fields list for later submit
697 vbo_guest_misconduct_fields.push('vbo-gm-category');
698
699 // sub-categories or additional fields of misconduct categories
700 for (var category in misconduct_fields['categories']) {
701 if (!misconduct_fields['categories'].hasOwnProperty(category)) {
702 continue;
703 }
704 if (!misconduct_fields['categories'][category].hasOwnProperty('subcategories') && !misconduct_fields['categories'][category].hasOwnProperty('additional_fields')) {
705 // at least one of these two properties must be set
706 continue;
707 }
708 if (misconduct_fields['categories'][category].hasOwnProperty('subcategories') && misconduct_fields['categories'][category]['subcategories'].length) {
709 // sub-categories in drop down
710 var subcat_field_id = 'vbo-gm-subcategory' + misconduct_fields['categories'][category]['id'];
711 misconduct_html += '<div class="vbo-modal-form-addnew-elem vbo-modal-guestmisconduct-addnew-elem vbo-modal-guestmisconduct-addnew-cond" data-gmcid="' + misconduct_fields['categories'][category]['id'] + '" style="display: none;">' + "\n";
712 misconduct_html += '<label for="' + subcat_field_id + '">' + misconduct_fields['labels']['subcategory'] + '</label>';
713 misconduct_html += '<select id="' + subcat_field_id + '" data-gmname="subcategory_id">' + "\n";
714 for (var subcategory in misconduct_fields['categories'][category]['subcategories']) {
715 if (!misconduct_fields['categories'][category]['subcategories'].hasOwnProperty(subcategory)) {
716 continue;
717 }
718 misconduct_html += '<option value="' + misconduct_fields['categories'][category]['subcategories'][subcategory]['id'] + '">' + misconduct_fields['categories'][category]['subcategories'][subcategory]['title'] + '</option>' + "\n";
719 }
720 misconduct_html += '</select>' + "\n";
721 misconduct_html += '</div>' + "\n";
722 // push sub-category field in fields list for later submit
723 if (vbo_guest_misconduct_fields.indexOf(subcat_field_id) < 0) {
724 vbo_guest_misconduct_fields.push(subcat_field_id);
725 }
726 } else if (misconduct_fields['categories'][category].hasOwnProperty('additional_fields') && misconduct_fields['categories'][category]['additional_fields'].length) {
727 // additional fields
728 for (var extra_field in misconduct_fields['categories'][category]['additional_fields']) {
729 if (!misconduct_fields['categories'][category]['additional_fields'].hasOwnProperty(extra_field)) {
730 continue;
731 }
732 var field_id = 'vbo-gm-extrafield-' + misconduct_fields['categories'][category]['additional_fields'][extra_field]['name'];
733 var field_name = misconduct_fields['categories'][category]['additional_fields'][extra_field]['name'];
734 misconduct_html += '<div class="vbo-modal-form-addnew-elem vbo-modal-guestmisconduct-addnew-elem vbo-modal-guestmisconduct-addnew-cond" data-gmcid="' + misconduct_fields['categories'][category]['id'] + '" style="display: none;">' + "\n";
735 misconduct_html += '<label for="' + field_id + '">' + misconduct_fields['categories'][category]['additional_fields'][extra_field]['label'] + '</label>';
736 if (misconduct_fields['categories'][category]['additional_fields'][extra_field]['type'] == 'number') {
737 misconduct_html += '<input data-gmname="' + field_name + '" type="number" id="' + field_id + '" value="" step="any" min="0" />';
738 } else if (misconduct_fields['categories'][category]['additional_fields'][extra_field]['type'] == 'text') {
739 misconduct_html += '<input data-gmname="' + field_name + '" type="text" id="' + field_id + '" value="" />';
740 } else if (misconduct_fields['categories'][category]['additional_fields'][extra_field]['type'] == 'text') {
741 misconduct_html += '<input data-gmname="' + field_name + '" type="text" id="' + field_id + '" value="" />';
742 } else if (misconduct_fields['categories'][category]['additional_fields'][extra_field]['type'] == 'textarea') {
743 misconduct_html += '<textarea data-gmname="' + field_name + '" id="' + field_id + '" rows="5" cols="50" maxlength="240"></textarea>';
744 } else if (misconduct_fields['categories'][category]['additional_fields'][extra_field]['type'] == 'select') {
745 misconduct_html += '<select data-gmname="' + field_name + '" id="' + field_id + '">';
746 for (var choicekey in misconduct_fields['categories'][category]['additional_fields'][extra_field]['choices']) {
747 // this is either an array when keys are numeric from 0, or an object when keys start from like 1, but with choicekey we take the proper key in the object
748 if (!misconduct_fields['categories'][category]['additional_fields'][extra_field]['choices'].hasOwnProperty(choicekey)) {
749 continue;
750 }
751 misconduct_html += '<option value="' + choicekey + '">' + misconduct_fields['categories'][category]['additional_fields'][extra_field]['choices'][choicekey] + '</option>';
752 }
753 misconduct_html += '</select>';
754 }
755 misconduct_html += '</div>' + "\n";
756 // push additional field in fields list for later submit
757 vbo_guest_misconduct_fields.push(field_id);
758 }
759 }
760 }
761
762 // mandatory fields for all categories of guest misconduct reporting
763 for (var mandfield in misconduct_fields['fields']) {
764 if (!misconduct_fields['fields'].hasOwnProperty(mandfield)) {
765 continue;
766 }
767 var field_id = 'vbo-gm-mandfield-' + misconduct_fields['fields'][mandfield]['name'];
768 var field_name = misconduct_fields['fields'][mandfield]['name'];
769 misconduct_html += '<div class="vbo-modal-form-addnew-elem vbo-modal-guestmisconduct-addnew-elem">' + "\n";
770 misconduct_html += '<label for="' + field_id + '">' + misconduct_fields['fields'][mandfield]['label'] + '</label>';
771 if (misconduct_fields['fields'][mandfield]['type'] == 'number') {
772 misconduct_html += '<input data-gmname="' + field_name + '" type="number" id="' + field_id + '" value="" step="any" min="0" />';
773 } else if (misconduct_fields['fields'][mandfield]['type'] == 'text') {
774 misconduct_html += '<input data-gmname="' + field_name + '" type="text" id="' + field_id + '" value="" />';
775 } else if (misconduct_fields['fields'][mandfield]['type'] == 'text') {
776 misconduct_html += '<input data-gmname="' + field_name + '" type="text" id="' + field_id + '" value="" />';
777 } else if (misconduct_fields['fields'][mandfield]['type'] == 'textarea') {
778 misconduct_html += '<textarea data-gmname="' + field_name + '" id="' + field_id + '" rows="5" cols="50" maxlength="240"></textarea>';
779 } else if (misconduct_fields['fields'][mandfield]['type'] == 'select') {
780 misconduct_html += '<select data-gmname="' + field_name + '" id="' + field_id + '">';
781 for (var choicekey in misconduct_fields['fields'][mandfield]['choices']) {
782 if (!misconduct_fields['fields'][mandfield]['choices'].hasOwnProperty(choicekey)) {
783 continue;
784 }
785 misconduct_html += '<option value="' + choicekey + '">' + misconduct_fields['fields'][mandfield]['choices'][choicekey] + '</option>';
786 }
787 misconduct_html += '</select>';
788 }
789 misconduct_html += '</div>' + "\n";
790 // push mandatory field in fields list for later submit
791 vbo_guest_misconduct_fields.push(field_id);
792 }
793
794 // display HTML content and submit button
795 jQuery('.vbo-modal-guestmisconduct-report-elems').html(misconduct_html);
796 jQuery('#vbo-guest-misconduct-submit-btn').show();
797 // trigger change of main category drop down
798 jQuery('#vbo-gm-category').trigger('change');
799 } catch (e) {
800 console.log(res);
801 alert('Invalid response. Vik Channel Manager needs to be installed, configured and updated to the latest version.');
802 hideVboDialogGuestMisconduct();
803 return false;
804 }
805 },
806 (err) => {
807 hideVboDialogGuestMisconduct();
808 alert('Request failed. Vik Channel Manager needs to be installed, configured and updated to the latest version.');
809 }
810 );
811 }
812
813 function vboSubmitGuestMisconduct() {
814 if (!vbo_guest_misconduct_fields.length) {
815 alert('Empty data to submit. Vik Channel Manager needs to be installed, configured and updated to the latest version.');
816 return false;
817 }
818
819 // prevent double submissions
820 vboGuestMisconductDisableSubmit();
821 //
822
823 var submit_fields = {
824 tmpl: "component",
825 bid: jQuery('.vbo-modal-guestmisconduct-addnew').attr('data-bid'),
826 otabid: jQuery('.vbo-modal-guestmisconduct-addnew').attr('data-otabid'),
827 bcom_keys: new Array
828 };
829 for (var elemid in vbo_guest_misconduct_fields) {
830 if (!vbo_guest_misconduct_fields.hasOwnProperty(elemid)) {
831 continue;
832 }
833 if (!jQuery('#' + vbo_guest_misconduct_fields[elemid]).length || !jQuery('#' + vbo_guest_misconduct_fields[elemid]).closest('.vbo-modal-guestmisconduct-addnew-elem').length) {
834 // form element not found, or parent container not found
835 continue;
836 }
837 if (jQuery('#' + vbo_guest_misconduct_fields[elemid]).closest('.vbo-modal-guestmisconduct-addnew-elem').is(':visible')) {
838 // we include this value in the AJAX request
839 var field_name = jQuery('#' + vbo_guest_misconduct_fields[elemid]).attr('data-gmname');
840 var submit_key = 'bcom_' + field_name;
841 submit_fields[submit_key] = jQuery('#' + vbo_guest_misconduct_fields[elemid]).val();
842 submit_fields['bcom_keys'].push(submit_key);
843 }
844 }
845
846 // make the AJAX request to VCM
847 var jqxhr = jQuery.ajax({
848 type: "POST",
849 url: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikchannelmanager&task=submit_bcom_guestmisconduct'); ?>",
850 data: submit_fields
851 }).done(function(res) {
852 try {
853 var misconduct_rs = JSON.parse(res);
854 console.log(submit_fields, misconduct_rs);
855
856 // make sure the request was successful
857 if (!misconduct_rs.status) {
858 alert(misconduct_rs.error);
859 vboGuestMisconductEnableSubmit();
860 return false;
861 }
862
863 // make another AJAX request (now on VBO) to update the booking history
864 var event_descr = jQuery('#vbo-gm-mandfield-details_text').length ? jQuery('#vbo-gm-mandfield-details_text').val() : '';
865 jQuery.ajax({
866 type: "POST",
867 url: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=store_booking_history_event'); ?>",
868 data: {
869 tmpl: "component",
870 bid: jQuery('.vbo-modal-guestmisconduct-addnew').attr('data-bid'),
871 event: 'GM',
872 descr: event_descr
873 }
874 }).done(function(res) {
875 // just reload the page in case of success
876 document.location.href = jQuery('#vbo-gm-reloadlink').attr('href');
877 }).fail(function() {
878 // we reload the page even in case of failure
879 document.location.href = jQuery('#vbo-gm-reloadlink').attr('href');
880 });
881 } catch (e) {
882 console.log(res);
883 alert('Invalid update response. Vik Channel Manager needs to be installed, configured and updated to the latest version.');
884 vboGuestMisconductEnableSubmit();
885 hideVboDialogGuestMisconduct();
886 return false;
887 }
888 }).fail(function() {
889 alert('Update Request failed. Vik Channel Manager needs to be installed, configured and updated to the latest version.');
890 vboGuestMisconductEnableSubmit();
891 return false;
892 });
893 }
894
895 function hideVboDialogGuestMisconduct() {
896 if (vbodialogguestmisconduct_on === true) {
897 jQuery(".vbo-modal-overlay-block-guestmisconduct").fadeOut(400, function () {
898 jQuery(".vbo-modal-overlay-content-guestmisconduct").show();
899 });
900 // turn flag off
901 vbodialogguestmisconduct_on = false;
902 }
903 }
904
905 function vboGuestMisconductChangeCategory(gmcid) {
906 jQuery('.vbo-modal-guestmisconduct-addnew-cond').each(function() {
907 if (jQuery(this).attr('data-gmcid') == gmcid) {
908 jQuery(this).show();
909 } else {
910 jQuery(this).hide();
911 }
912 });
913 }
914
915 function vboGuestMisconductDisableSubmit() {
916 jQuery('#vbo-guest-misconduct-submit-btn').prepend('<i class="<?php echo VikBookingIcons::i('refresh', 'fa-spin fa-fw'); ?>"></i> ').prop('disabled', true);
917 }
918
919 function vboGuestMisconductEnableSubmit() {
920 jQuery('#vbo-guest-misconduct-submit-btn').prop('disabled', false).find('i').remove();
921 }
922 </script>
923
924 </div>
925 <?php
926 }
927 if ($this->vcm_host_to_guest_review) {
928 ?>
929 <div class="vbo-bookdet-wrap">
930 <div class="vbo-bookdet-head">
931 <span><?php echo JText::translate('VBO_REVIEW_YOUR_GUEST'); ?></span>
932 </div>
933 <div class="vbo-bookdet-foot">
934 <button type="button" class="btn btn-small btn-primary vcm-btn-channel-airbnbapi" onclick="vboOpenJModal('vbo-vcm-host-to-guest-review', 'index.php?option=com_vikchannelmanager&task=hostguestreview&cid[]=<?php echo $row['id']; ?>&tmpl=component');">
935 <?php VikBookingIcons::e('smile'); ?>
936 <?php echo JText::translate('VBO_WRITE_REVIEW'); ?>
937 </button>
938 </div>
939 </div>
940 <?php
941 // prepare modal (host-to-guest review)
942 array_push($vbo_modals_html, $vbo_app->getJmodalHtml('vbo-vcm-host-to-guest-review', JText::translate('VBO_REVIEW_YOUR_GUEST')));
943
944 // check if a notification was clicked
945 if (VikRequest::getString('notif_action', '', 'request') == 'airbnb_host_guest_review') {
946 JFactory::getDocument()->addScriptDeclaration(
947 <<<JS
948 jQuery(function() {
949 setTimeout(() => {
950 jQuery('.vcm-btn-channel-airbnbapi').trigger('click');
951 }, 500);
952 });
953 JS
954 );
955 }
956 }
957 }
958 ?>
959 </div>
960
961 <?php
962 if (!$printreceipt && $this->allows_conversion !== false) {
963 ?>
964 <div class="vbo-bookdet-container vbo-bookdet-conv-currency">
965 <div class="vbo-bookdet-conv-currency-inner">
966 <div class="vbo-bookdet-conv-currency-info">
967 <span><?php echo JText::sprintf('VBO_CONV_RES_OTA_CURRENCY', $this->conv_from_currency, $this->conv_to_currency); ?></span>
968 <span><?php echo JText::sprintf('VBO_CONV_RES_OTA_CURRENCY_EXC', ($this->conv_from_currency . ' ' . VikBooking::numberFormat($row['total'])), ($this->conv_to_currency . ' ' . VikBooking::numberFormat($this->allows_conversion))); ?></span>
969 </div>
970 <div class="vbo-bookdet-conv-currency-apply">
971 <a class="btn vbo-config-btn" onclick="return confirm(Joomla.JText._('VBO_CONV_RES_OTA_CURRENCY_APPLY') + '?');" href="index.php?option=com_vikbooking&task=editorder&cid[]=<?php echo $row['id']; ?>&do_ota_curr_conv=1"><?php VikBookingIcons::e('exchange-alt'); ?> <?php echo JText::translate('VBO_CONV_RES_OTA_CURRENCY_APPLY'); ?></a>
972 </div>
973 </div>
974 </div>
975 <?php
976 }
977
978 if (!$printreceipt && $row['status'] == "standby" && empty($row['idorderota']) && !strcasecmp((string)$row['type'], 'Inquiry')) {
979 // website pending reservation inquiry
980 $ir_data_callback = function($data) {
981 return (is_object($data) && !empty($data->av_type));
982 };
983 $prev_ir_data = $history_obj->getEventsWithData('IR', $ir_data_callback, true);
984 if (is_array($prev_ir_data) && count($prev_ir_data)) {
985 // display a message about the availability type at the time of creation of the inquiry reservation
986
987 // parse original stay dates into DateTime objects
988 $orig_checkin_dt_obj = new JDate($prev_ir_data[0]->checkin_date);
989 $orig_checkout_dt_obj = new JDate($prev_ir_data[0]->checkout_date);
990 ?>
991 <div class="vbo-bookdet-container vbo-bookdet-inquiry-alert">
992 <div class="vbo-bookdet-inquiry-alert-dismiss">
993 <button type="button" class="btn btn-warning" onclick="jQuery('.vbo-bookdet-inquiry-alert').remove();"><?php VikBookingIcons::e('times-circle'); ?> <?php echo JText::translate('VBOBTNKEEPREMIND'); ?></button>
994 </div>
995 <div class="vbo-bookdet-inquiry-alert-message">
996 <div class="vbo-bookdet-inquiry-alert-top">
997 <span><?php echo JText::translate('VBO_WEB_INQUIRY_ALERT'); ?></span>
998 </div>
999 <div class="vbo-bookdet-inquiry-alert-avtype">
1000 <span class="vbo-bookdet-inquiry-alert-mess-avtype"><?php
1001 // explain what was the availability at the time of inquiry
1002 if ($prev_ir_data[0]->av_type === 1) {
1003 echo JText::translate('VBO_WEB_INQUIRY_AVTYPE_1');
1004 } elseif ($prev_ir_data[0]->av_type === 2) {
1005 echo JText::translate('VBO_WEB_INQUIRY_AVTYPE_2');
1006 } elseif ($prev_ir_data[0]->av_type === 3) {
1007 echo JText::translate('VBO_WEB_INQUIRY_AVTYPE_3');
1008 } else {
1009 echo JText::translate('VBO_WEB_INQUIRY_AVTYPE_4');
1010 }
1011 ?></span>
1012 <span class="vbo-bookdet-inquiry-alert-mess-origrq">
1013 <strong><?php echo JText::translate('VBO_WEB_INQUIRY_ORIGRQ') . ':'; ?></strong>
1014 <span class="badge"><?php echo JText::translate('VBPICKUPAT') . ': ' . $orig_checkin_dt_obj->format('D, d M Y', true); ?></span>
1015 <span class="badge"><?php echo JText::translate('VBRELEASEAT') . ': ' . $orig_checkout_dt_obj->format('D, d M Y', true); ?></span>
1016 <span class="badge"><?php echo JText::translate('VBEDITORDERADULTS') . ': ' . $prev_ir_data[0]->adults; ?></span>
1017 <?php
1018 if (!empty($prev_ir_data[0]->children)) {
1019 ?>
1020 <span class="badge"><?php echo JText::translate('VBEDITORDERCHILDREN') . ': ' . $prev_ir_data[0]->children; ?></span>
1021 <?php
1022 }
1023 ?>
1024 </span>
1025 </div>
1026 <div class="vbo-bookdet-inquiry-alert-bottom">
1027 <span><?php echo JText::translate('VBO_WEB_INQUIRY_SUGG'); ?></span>
1028 </div>
1029 </div>
1030 </div>
1031 <?php
1032 }
1033 }
1034 ?>
1035
1036 <div class="vbo-bookingdet-innertop">
1037 <div class="vbo-bookingdet-commands">
1038 <?php
1039 if ($busy || $row['status'] == "standby") {
1040 ?>
1041 <div class="vbo-bookingdet-command">
1042 <button onclick="document.location.href='index.php?option=com_vikbooking&task=editbusy&cid[]=<?php echo $row['id']; ?>';" class="btn vbo-config-btn" type="button"><i class="icon-pencil"></i> <?php echo JText::translate('VBMODRES'); ?></button>
1043 </div>
1044 <?php
1045 }
1046 if ((array_key_exists(1, $tars) && count($tars[1]) > 0) || ($is_package || $is_cust_cost)) {
1047
1048 if (VBOPlatformDetection::isWordPress()) {
1049 /**
1050 * @wponly display warning message if no valid Shortcodes found
1051 */
1052 $model = JModel::getInstance('vikbooking', 'shortcodes');
1053 $itemid = $model->best('booking');
1054 if (!$itemid) {
1055 VikError::raiseWarning('', 'No Shortcodes found, or no Shortcodes being used in Pages/Posts.');
1056 }
1057 }
1058
1059 ?>
1060 <div class="vbo-bookingdet-command">
1061 <button onclick="window.open('<?php echo VikBooking::externalroute('index.php?option=com_vikbooking&view=booking&sid='.(!empty($row['sid']) ? $row['sid'] : $row['idorderota']).'&ts='.$row['ts'], false); ?>', '_blank');" type="button" class="btn vbo-config-btn"><?php VikBookingIcons::e('external-link'); ?> <?php echo JText::translate('VBVIEWORDFRONT'); ?></button>
1062 </div>
1063 <?php
1064 }
1065 if (($row['status'] == "confirmed" || ($row['status'] == "standby" && !empty($row['custmail']))) && ((array_key_exists(1, $tars) && count($tars[1]) > 0) || ($is_package || $is_cust_cost))) {
1066 ?>
1067 <div class="vbo-bookingdet-command">
1068 <button class="btn vbo-config-btn" type="button" onclick="document.location.href='index.php?option=com_vikbooking&task=resendordemail&cid[]=<?php echo $row['id']; ?>';"><?php VikBookingIcons::e('envelope'); ?> <?php echo JText::translate('VBRESENDORDEMAIL'); ?></button>
1069 </div>
1070 <?php
1071 }
1072 if (is_array($this->vcm_special_offer)) {
1073 if (empty($this->vcm_special_offer[3]) || !empty($this->vcm_special_offer[4])) {
1074 // no special offer sent before, or withdrawn
1075 ?>
1076 <div class="vbo-bookingdet-command">
1077 <button type="button" class="btn btn-primary vcm-btn-channel-<?php echo strtolower($this->vcm_special_offer[2]); ?>" onclick="vboOpenJModal('vbo-vcm-special-offer', 'index.php?option=com_vikchannelmanager&task=specialoffer&bid=<?php echo $row['id']; ?>&listing_id=<?php echo $this->vcm_special_offer[0]; ?>&ota_thread_id=<?php echo $this->vcm_special_offer[1]; ?>&tmpl=component');"><?php VikBookingIcons::e('certificate'); ?> <?php echo JText::sprintf('VBO_VCM_SPECIAL_OFFER', $this->vcm_special_offer[2]); ?></button>
1078 </div>
1079 <?php
1080 // prepare modal (VCM prepare special offer)
1081 array_push($vbo_modals_html, $vbo_app->getJmodalHtml('vbo-vcm-special-offer', JText::sprintf('VBO_VCM_SPECIAL_OFFER', $this->vcm_special_offer[2])));
1082 // end prepare modal
1083 } else {
1084 // special offer sent before, link to withdraw it
1085 ?>
1086 <div class="vbo-bookingdet-command">
1087 <a href="index.php?option=com_vikchannelmanager&task=sendSpecialOffer&vbo_oid=<?php echo $row['id']; ?>&spo_type=special_offer&spo_action=withdraw&ota_thread_id=<?php echo $this->vcm_special_offer[1]; ?>&spo_id=<?php echo $this->vcm_special_offer[3]; ?>" class="btn btn-danger"><?php VikBookingIcons::e('ban'); ?> <?php echo JText::translate('VBO_WITHDRAW_SPOFFER'); ?></a>
1088 </div>
1089 <?php
1090 }
1091 }
1092 if ($row['status'] == "standby" || ($row['status'] == "cancelled" && $row['checkout'] >= time())) {
1093 ?>
1094 <div class="vbo-bookingdet-command">
1095 <button class="btn btn-success" type="button" onclick="if (confirm('<?php echo htmlspecialchars(JText::translate('VBSETORDCONFIRMED')); ?> ?')) {document.location.href='index.php?option=com_vikbooking&task=setordconfirmed&cid[]=<?php echo $row['id'] . ($row['status'] == "cancelled" ? '&skip_notification=1' : ''); ?>';}"><?php VikBookingIcons::e('check'); ?> <?php echo JText::translate('VBSETORDCONFIRMED'); ?></button>
1096 </div>
1097 <?php
1098 }
1099 if ($row['status'] == "cancelled" && !$row['closure']) {
1100 ?>
1101 <div class="vbo-bookingdet-command">
1102 <button type="button" class="btn btn-warning vbo-context-menu-btn vbo-context-menu-actionscanc">
1103 <span class="vbo-context-menu-lbl"><?php echo JText::translate('VBCRONACTIONS'); ?> &#8230;</span>
1104 <span class="vbo-context-menu-ico"><?php VikBookingIcons::e('sort-down'); ?></span>
1105 </button>
1106 </div>
1107
1108 <script type="text/javascript">
1109 jQuery(function() {
1110 jQuery('.vbo-context-menu-actionscanc').vboContextMenu({
1111 placement: 'bottom-right',
1112 buttons: [
1113 <?php
1114 if (!empty($row['custmail'])) :
1115 ?>
1116 {
1117 icon: '<?php echo VikBookingIcons::i('envelope'); ?>',
1118 text: Joomla.JText._('VBSENDCANCORDEMAIL'),
1119 class: 'vbo-context-menu-entry-danger',
1120 separator: true,
1121 action: (root, config) => {
1122 document.location.href = 'index.php?option=com_vikbooking&task=sendcancordemail&cid[]=<?php echo $row['id']; ?>';
1123 },
1124 },
1125 <?php
1126 endif;
1127 ?>
1128 {
1129 icon: '<?php echo VikBookingIcons::i('hourglass-half'); ?>',
1130 text: Joomla.JText._('VBO_SET_STANDBY'),
1131 class: 'vbo-context-menu-entry-warning',
1132 separator: false,
1133 action: (root, config) => {
1134 document.location.href = '<?php echo VBOFactory::getPlatform()->getUri()->addCSRF('index.php?option=com_vikbooking&task=bookings.set_to_pending&bid=' . $row['id']); ?>';
1135 },
1136 },
1137 ],
1138 });
1139 });
1140 </script>
1141 <?php
1142 }
1143 if ($row['status'] == 'confirmed' && $row['closure'] < 1) {
1144 ?>
1145 <div class="vbo-bookingdet-command pro-feature">
1146 <button type="button" class="btn vbo-config-btn" onclick="document.getElementById('invnotes-hid').value=document.getElementById('invnotes').value;document.getElementById('vbo-gen-invoice').submit();"><?php VikBookingIcons::e('file-text-o'); ?> <?php echo JText::translate('VBOGENBOOKINGINVOICE'); ?></button>
1147 </div>
1148 <?php
1149 }
1150 if ($row['status'] == 'confirmed' && $row['closure'] < 1) {
1151 ?>
1152 <div class="vbo-bookingdet-command pro-feature">
1153 <button type="button" class="btn vbo-config-btn" onclick="window.open('index.php?option=com_vikbooking&task=editorder&cid[]=<?php echo $row['id']; ?>&print=1&tmpl=component', '_blank');"><?php VikBookingIcons::e('print'); ?> <?php echo JText::translate('VBOPRINTRECEIPT'); ?></button>
1154 </div>
1155 <?php
1156 }
1157 if ($row['status'] != 'confirmed' || $row['closure'] > 0 || $this->vcm_cancel_active_res) {
1158 if ($this->vcm_decline_actions) {
1159 // this booking requires some decline actions before being removed
1160 ?>
1161 <div class="vbo-bookingdet-command">
1162 <button type="button" class="btn btn-danger" onclick="vboOpenJModal('vbo-vcm-decline-booking', 'index.php?option=com_vikchannelmanager&task=declinebooking&cid[]=<?php echo $row['id']; ?>&tmpl=component');"><?php VikBookingIcons::e('trash'); ?> <?php echo JText::translate('VBMAINEBUSYDEL'); ?></button>
1163 </div>
1164 <?php
1165 // prepare modal (VCM decline booking)
1166 array_push($vbo_modals_html, $vbo_app->getJmodalHtml('vbo-vcm-decline-booking', JText::translate('VBMAINEBUSYDEL')));
1167 // end prepare modal
1168 } elseif ($this->vcm_cancel_active_res) {
1169 // the active OTA booking can be cancelled
1170 ?>
1171 <div class="vbo-bookingdet-command">
1172 <button type="button" class="btn btn-danger" onclick="vboOpenJModal('vbo-vcm-cancel-reservation', 'index.php?option=com_vikchannelmanager&task=cancelreservation&vbo_oid=<?php echo $row['id']; ?>&tmpl=component');"><?php VikBookingIcons::e('trash'); ?> <?php echo JText::translate('VBMAINEBUSYDEL'); ?></button>
1173 </div>
1174 <?php
1175 // prepare modal (VCM cancel reservation)
1176 array_push($vbo_modals_html, $vbo_app->getJmodalHtml('vbo-vcm-cancel-reservation', JText::translate('VBMAINEBUSYDEL')));
1177 // end prepare modal
1178 } else {
1179 // regular remove button with confirmation
1180 ?>
1181 <div class="vbo-bookingdet-command">
1182 <button type="button" class="btn btn-danger" onclick="if (confirm(Joomla.JText._('VBDELCONFIRM'))){document.location.href='index.php?option=com_vikbooking&task=removeorders&cid[]=<?php echo $row['id']; ?>&goto=<?php echo $row['id']; ?>';}"><?php VikBookingIcons::e('trash'); ?> <?php echo $row['status'] == 'cancelled' ? JText::translate('VBO_PURGERM_RESERVATION') : JText::translate('VBMAINEBUSYDEL'); ?></button>
1183 </div>
1184 <?php
1185 }
1186 }
1187 ?>
1188
1189 <!-- Define role to detect the supported hook -->
1190 <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorder","key":"buttons","type":"field"} -->
1191
1192 <?php
1193 if (isset($bookingPanelForms['buttons']))
1194 {
1195 echo $bookingPanelForms['buttons'];
1196 }
1197 ?>
1198 </div>
1199
1200 <div class="vbo-bookingdet-tabs">
1201 <div class="vbo-bookingdet-tab vbo-bookingdet-tab-active" data-vbotab="vbo-tab-details"><?php echo JText::translate('VBOBOOKDETTABDETAILS'); ?></div>
1202 <div class="vbo-bookingdet-tab" data-vbotab="vbo-tab-admin"><?php echo JText::translate('VBOBOOKDETTABADMIN'); ?></div>
1203 </div>
1204 </div>
1205
1206 <div class="vbo-bookingdet-tab-cont" id="vbo-tab-details" style="display: block;">
1207 <div class="vbo-bookingdet-innercontainer">
1208 <div class="vbo-bookingdet-customer">
1209 <div class="vbo-bookingdet-detcont<?php echo $row['closure'] > 0 ? ' vbo-bookingdet-closure' : ''; ?>">
1210 <?php
1211 $custdata_parts = explode("\n", $row['custdata']);
1212 if (count($custdata_parts) > 2 && strpos($custdata_parts[0], ':') !== false && strpos($custdata_parts[1], ':') !== false) {
1213 //attempt to format labels and values
1214 foreach ($custdata_parts as $custdet) {
1215 if (strlen($custdet) < 1) {
1216 continue;
1217 }
1218 $custdet_parts = explode(':', $custdet);
1219 $custd_lbl = '';
1220 $custd_val = '';
1221 if (count($custdet_parts) < 2) {
1222 $custd_val = $custdet;
1223 } else {
1224 $custd_lbl = $custdet_parts[0];
1225 if ($custd_lbl == 'http' || $custd_lbl == 'https') {
1226 // shift values
1227 $custdet_parts[2] = $custdet_parts[1];
1228 $custdet_parts[1] = $custdet_parts[0];
1229 $custd_lbl = '';
1230 }
1231 unset($custdet_parts[0]);
1232 if ((!strcasecmp(trim($custdet_parts[1]), 'http') || !strcasecmp(trim($custdet_parts[1]), 'https')) && !empty($custdet_parts[2]) && strpos($custdet_parts[2], '//') !== false) {
1233 // this is a URI
1234 $custd_val = '<a href="' . trim(implode(':', $custdet_parts)) . '" target="_blank"><i class="' . VikBookingIcons::i('external-link') . '"></i></a>';
1235 } else {
1236 $custd_val = trim(implode(':', $custdet_parts));
1237 }
1238 }
1239 ?>
1240 <div class="vbo-bookingdet-userdetail">
1241 <?php
1242 if (strlen($custd_lbl)) {
1243 ?>
1244 <span class="vbo-bookingdet-userdetail-lbl"><?php echo VikBooking::tnCustomerRawDataLabel($custd_lbl); ?></span>
1245 <?php
1246 }
1247 if (strlen($custd_val)) {
1248 ?>
1249 <span class="vbo-bookingdet-userdetail-val"><?php echo $custd_val; ?></span>
1250 <?php
1251 }
1252 ?>
1253 </div>
1254 <?php
1255 }
1256 } else {
1257 if ($row['closure'] > 0) {
1258 ?>
1259 <div class="vbo-bookingdet-userdetail">
1260 <span class="vbo-bookingdet-userdetail-val"><?php echo nl2br($row['custdata']); ?></span>
1261 </div>
1262 <?php
1263 } else {
1264 echo nl2br($row['custdata']);
1265 ?>
1266 <div class="vbo-bookingdet-userdetail">
1267 <span class="vbo-bookingdet-userdetail-val">&nbsp;</span>
1268 </div>
1269 <?php
1270 }
1271 }
1272 if (!empty($row['ujid'])) {
1273 $orig_user = JFactory::getUser($row['ujid']);
1274 $author_name = is_object($orig_user) && property_exists($orig_user, 'name') && !empty($orig_user->name) ? $orig_user->name : '';
1275 ?>
1276 <div class="vbo-bookingdet-userdetail">
1277 <span class="vbo-bookingdet-userdetail-val"><?php echo JText::sprintf('VBOBOOKINGCREATEDBY', $row['ujid'].(!empty($author_name) ? ' ('.$author_name.')' : '')); ?></span>
1278 </div>
1279 <?php
1280 }
1281 ?>
1282
1283 <!-- Define role to detect the supported hook -->
1284 <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderSidebar","key":"userdetails","type":"field"} -->
1285
1286 <?php
1287 if (isset($bookingSidebarForms['userdetails']))
1288 {
1289 echo $bookingSidebarForms['userdetails'];
1290 }
1291 ?>
1292
1293 </div>
1294
1295 <?php
1296 // build list of invoice details (path/uri & label/button), one by default
1297 $invoice_details = [
1298 [
1299 'path' => implode(DIRECTORY_SEPARATOR, [VBO_SITE_PATH, 'helpers', 'invoices', 'generated', "{$row['id']}_{$row['sid']}.pdf"]),
1300 'uri' => VBO_SITE_URI . 'helpers/invoices/generated/' . "{$row['id']}_{$row['sid']}.pdf",
1301 'label' => JText::translate('VBOCOLORTAGRULEINVONE'),
1302 'btn' => JText::translate('VBOINVDOWNLOAD'),
1303 ]
1304 ];
1305
1306 /**
1307 * Merge the additional invoices generated by the e-invoicing drivers for this booking.
1308 *
1309 * @since 1.16.7 (J) - 1.6.7 (WP)
1310 */
1311 $invoice_details = array_merge($invoice_details, VBOEinvoicingFactory::getInstance()->getBookingExtraInvoices($row['id']));
1312
1313 /**
1314 * Trigger event to allow third-party plugins to define additional invoices or paths/urls.
1315 *
1316 * @since 1.16.7 (J) - 1.6.7 (WP)
1317 */
1318 VBOFactory::getPlatform()->getDispatcher()->trigger('onBeforeListInvoices', [$row, &$invoice_details]);
1319
1320 // check if an invoice exists
1321 $invoiced = false;
1322 foreach ((array) $invoice_details as $invoice_detail) {
1323 $invoiced = $invoiced || is_file($invoice_detail['path']);
1324 }
1325
1326 // extra booking details
1327 if (!$printreceipt && ((!empty($row['channel']) && !empty($row['idorderota'])) || strlen((string)$row['confirmnumber']) || $invoiced)) {
1328 ?>
1329 <div class="vbo-bookingdet-detcont vbo-bookingdet-detcont-labels-wrap vbo-hidein-print">
1330 <?php
1331 if (!empty($row['channel']) && !empty($row['idorderota'])) {
1332 ?>
1333 <div class="vbo-bookingdet-detcont-label vbo-bookingdet-detcont-label-idorderota">
1334 <span class="label label-info">
1335 <span><?php echo $otachannel_name . ' ID'; ?></span>
1336 <span class="badge"><?php echo !strcasecmp((string)$row['type'], 'Inquiry') && $row['status'] == 'standby' ? '-----' : $row['idorderota']; ?></span>
1337 </span>
1338 </div>
1339 <?php
1340 }
1341 if (strlen((string)$row['confirmnumber'])) {
1342 ?>
1343 <div class="vbo-bookingdet-detcont-label vbo-bookingdet-detcont-label-confirmnumber">
1344 <span class="label label-success">
1345 <span><?php echo JText::translate('VBCONFIRMNUMB'); ?></span>
1346 <span class="badge"><?php echo $row['confirmnumber']; ?></span>
1347 </span>
1348 </div>
1349 <?php
1350 }
1351 if ($invoiced) {
1352 foreach ($invoice_details as $invoice_detail) {
1353 ?>
1354 <div class="vbo-bookingdet-detcont-label vbo-bookingdet-detcont-label-invoice">
1355 <span class="label label-success">
1356 <span><?php echo $invoice_detail['label'] ?? JText::translate('VBOCOLORTAGRULEINVONE'); ?></span>
1357 <span class="badge"><a href="<?php echo $invoice_detail['uri'] . (strpos($invoice_detail['uri'], '?') === false ? '?' . rand() . '=1' : ''); ?>" target="_blank"><?php VikBookingIcons::e('download'); ?> <?php echo $invoice_detail['btn'] ?? JText::translate('VBOINVDOWNLOAD'); ?></a></span>
1358 </span>
1359 </div>
1360 <?php
1361 }
1362 }
1363 if ($this->vcm_review) {
1364 ?>
1365 <div class="vbo-bookingdet-detcont-label vbo-bookingdet-detcont-label-review">
1366 <span class="label label-warning">
1367 <a href="index.php?option=com_vikchannelmanager&task=reviews&revid=<?php echo $this->vcm_review['id']; ?>" target="_blank" style="color: #fff;"><i class="vboicn-star-full"></i> <?php echo JText::translate('VBOSEEGUESTREVIEW'); ?></a>
1368 </span>
1369 </div>
1370 <?php
1371 // check if a notification was clicked
1372 if (VikRequest::getString('notif_action', '', 'request') == 'see_guest_review') {
1373 $vcm_review_link = VBOFactory::getPlatform()->getUri()->admin('index.php?option=com_vikchannelmanager&task=reviews&revid=' . $this->vcm_review['id'], false);
1374 JFactory::getDocument()->addScriptDeclaration(
1375 <<<JS
1376 jQuery(function() {
1377 setTimeout(() => {
1378 document.location.href = '$vcm_review_link';
1379 }, 200);
1380 });
1381 JS
1382 );
1383 }
1384 }
1385 ?>
1386
1387 <!-- Define role to detect the supported hook -->
1388 <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderSidebar","key":"invoice","type":"field"} -->
1389
1390 <?php
1391 if (isset($bookingSidebarForms['invoice']))
1392 {
1393 echo $bookingSidebarForms['invoice'];
1394 }
1395 ?>
1396
1397 </div>
1398 <?php
1399 }
1400 if (!$printreceipt && $row['closure'] < 1) {
1401 ?>
1402 <div class="vbo-bookingdet-detcont vbo-hidein-print">
1403 <div class="vbo-bookingdet-lblcont">
1404 <label for="custmail"><?php echo JText::translate('VBCUSTEMAIL'); ?></label>
1405 </div>
1406 <div class="vbo-bookingdet-inpwrap">
1407 <div class="vbo-bookingdet-inpcont">
1408 <input type="text" name="custmail" id="custmail" value="<?php echo $this->escape($row['custmail']); ?>" size="25" onkeyup="vboKeyupEmail(event);"/>
1409 </div>
1410 <div class="vbo-bookingdet-btncont vbo-bookingdet-save-email" style="display: none;">
1411 <button type="button" class="btn btn-success" onclick="document.adminForm.submit();"><?php VikBookingIcons::e('save'); ?> <?php echo JText::translate('VBSAVE'); ?></button>
1412 </div>
1413 <?php if (!empty($row['custmail'])) : ?>
1414 <div class="vbo-bookingdet-btncont">
1415 <button type="button" class="btn vbo-config-btn" onclick="vboToggleSendEmail();" style="vertical-align: top;"><?php VikBookingIcons::e('envelope'); ?> <?php echo JText::translate('VBSENDEMAILACTION'); ?></button>
1416 </div>
1417 <?php endif; ?>
1418 </div>
1419
1420 <!-- Define role to detect the supported hook -->
1421 <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderSidebar","key":"email","type":"field"} -->
1422
1423 <?php
1424 if (isset($bookingSidebarForms['email']))
1425 {
1426 echo $bookingSidebarForms['email'];
1427 }
1428 ?>
1429
1430 </div>
1431 <div class="vbo-bookingdet-detcont vbo-hidein-print">
1432 <div class="vbo-bookingdet-lblcont">
1433 <label for="custphone"><?php echo JText::translate('VBCUSTOMERPHONE'); ?></label>
1434 </div>
1435 <div class="vbo-bookingdet-inpwrap">
1436 <div class="vbo-bookingdet-inpcont">
1437 <?php echo $vbo_app->printPhoneInputField(array('name' => 'custphone', 'id' => 'custphone', 'value' => $this->escape($row['phone'])), array('nationalMode' => false, 'fullNumberOnBlur' => true)); ?>
1438 </div>
1439 <?php if (!empty($row['phone'])) : ?>
1440 <div class="vbo-bookingdet-btncont">
1441 <button type="button" class="btn vbo-config-btn" onclick="vboToggleSendSMS();" style="vertical-align: top;"><?php VikBookingIcons::e('comment-dots'); ?> <?php echo JText::translate('VBSENDSMSACTION'); ?></button>
1442 </div>
1443 <?php endif; ?>
1444 </div>
1445
1446 <!-- Define role to detect the supported hook -->
1447 <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderSidebar","key":"phone","type":"field"} -->
1448
1449 <?php
1450 if (isset($bookingSidebarForms['phone']))
1451 {
1452 echo $bookingSidebarForms['phone'];
1453 }
1454 ?>
1455
1456 </div>
1457
1458 <!-- Define role to detect the supported hook -->
1459 <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderSidebar","type":"fieldset"} -->
1460
1461 <?php
1462 foreach ($bookingSidebarForms as $legend => $form)
1463 {
1464 if (in_array($legend, ['userdetails', 'invoice', 'email', 'phone']))
1465 {
1466 // skip default forms
1467 continue;
1468 }
1469 ?>
1470 <div class="vbo-bookingdet-detcont vbo-hidein-print">
1471 <h3><?php echo JText::translate($legend); ?></h3>
1472
1473 <?php echo $form; ?>
1474 </div>
1475 <?php
1476 }
1477 ?>
1478
1479 <?php
1480 }
1481 ?>
1482 </div>
1483
1484 <?php
1485 $all_id_prices = array();
1486 $used_indexes_map = array();
1487 ?>
1488 <div class="vbo-bookingdet-summary">
1489 <div class="table-responsive">
1490 <table class="table">
1491 <?php
1492 // room stay dates in case of split stay (or modified room nights)
1493 $room_stay_dates = [];
1494 $room_stay_records = [];
1495 if ($row['split_stay']) {
1496 if ($row['status'] == 'confirmed') {
1497 $room_stay_dates = $av_helper->loadSplitStayBusyRecords($row['id']);
1498 } else {
1499 $room_stay_dates = VBOFactory::getConfig()->getArray('split_stay_' . $row['id'], []);
1500 }
1501 } elseif (!$row['split_stay'] && $row['roomsnum'] > 1 && $row['days'] > 1 && $row['status'] == 'confirmed') {
1502 // load the occupied stay dates for each room in case they were modified
1503 $room_stay_records = $av_helper->loadSplitStayBusyRecords($row['id']);
1504 }
1505
1506 // parse all rooms booked
1507 foreach ($rooms as $ind => $or) {
1508 $num = $ind + 1;
1509 $room_icon = $row['split_stay'] && $ind > 0 ? 'random' : 'bed';
1510 $room_stay_nights = $row['days'];
1511 ?>
1512 <tr class="vbo-bookingdet-summary-room">
1513 <td class="vbo-bookingdet-summary-room-firstcell">
1514 <div class="vbo-bookingdet-summary-room-wrap">
1515 <div class="vbo-bookingdet-summary-roomnum"><?php VikBookingIcons::e($room_icon); ?> <?php echo JText::translate('VBEDITORDERTHREE').' '.$num; ?></div>
1516 <?php
1517 //Room Specific Unit
1518 if (!$row['closure'] && $row['status'] == "confirmed" && !empty($or['params'])) {
1519 $room_params = json_decode($or['params'], true);
1520 $arr_features = array();
1521 $unavailable_indexes = VikBooking::getRoomUnitNumsUnavailable($row, $or['idroom']);
1522 if (is_array($room_params) && array_key_exists('features', $room_params) && !empty($room_params['features'])) {
1523 foreach ($room_params['features'] as $rind => $rfeatures) {
1524 if (in_array($rind, $unavailable_indexes) || (isset($used_indexes_map[$or['idroom']]) && in_array($rind, $used_indexes_map[$or['idroom']]))) {
1525 continue;
1526 }
1527 foreach ($rfeatures as $fname => $fval) {
1528 if (strlen($fval)) {
1529 $arr_features[$rind] = '#'.$rind.' - '.JText::translate($fname).': '.$fval;
1530 break;
1531 }
1532 }
1533 }
1534 }
1535 if (count($arr_features)) {
1536 // $or['id'] equals to the ID of each matching record in _ordersrooms
1537 ?>
1538 <div class="vbo-bookingdet-summary-roomnum-chunit">
1539 <?php echo !$printreceipt ? $vbo_app->getNiceSelect($arr_features, $or['roomindex'], 'roomindex['.$or['id'].']', JText::translate('VBOFEATASSIGNUNIT'), JText::translate('VBOFEATASSIGNUNITEMPTY'), '', 'document.adminForm.submit();', $or['id']) : (!empty($or['roomindex']) && isset($arr_features[$or['roomindex']]) ? $arr_features[$or['roomindex']] : ''); ?>
1540 </div>
1541 <?php
1542 if (!empty($or['idroom']) && !empty($or['roomindex'])) {
1543 if (!array_key_exists($or['idroom'], $used_indexes_map)) {
1544 $used_indexes_map[$or['idroom']] = array();
1545 }
1546 $used_indexes_map[$or['idroom']][] = $or['roomindex'];
1547 }
1548 }
1549 }
1550 //
1551 ?>
1552 </div>
1553 <div class="vbo-bookingdet-summary-roomguests">
1554 <?php VikBookingIcons::e('male'); ?>
1555 <div class="vbo-bookingdet-summary-roomadults">
1556 <span><?php echo JText::translate('VBEDITORDERADULTS'); ?>:</span> <?php echo $arrpeople[$num]['adults']; ?>
1557 </div>
1558 <?php
1559 if ($arrpeople[$num]['children'] > 0) {
1560 $age_str = '';
1561 if (!empty($arrpeople[$num]['children_age'])) {
1562 $json_child = json_decode($arrpeople[$num]['children_age'], true);
1563 if (is_array($json_child) && isset($json_child['age']) && is_array($json_child['age']) && count($json_child['age'])) {
1564 $age_str = ' '.JText::sprintf('VBORDERCHILDAGES', implode(', ', $json_child['age']));
1565 }
1566 }
1567 ?>
1568 <div class="vbo-bookingdet-summary-roomchildren">
1569 <span><?php echo JText::translate('VBEDITORDERCHILDREN'); ?>:</span> <?php echo $arrpeople[$num]['children'].$age_str; ?>
1570 </div>
1571 <?php
1572 }
1573 if ($arrpeople[$num]['pets'] > 0) {
1574 ?>
1575 <div class="vbo-bookingdet-summary-roompets">
1576 <span><?php VikBookingIcons::e('dog'); ?> <?php echo JText::translate('VBO_PETS'); ?>:</span> <?php echo $arrpeople[$num]['pets']; ?>
1577 </div>
1578 <?php
1579 }
1580 ?>
1581 </div>
1582 <?php
1583 if (!empty($arrpeople[$num]['t_first_name'])) {
1584 ?>
1585 <div class="vbo-bookingdet-summary-guestname">
1586 <span><?php echo $arrpeople[$num]['t_first_name'].' '.$arrpeople[$num]['t_last_name']; ?></span>
1587 </div>
1588 <?php
1589 }
1590 ?>
1591 </td>
1592 <td>
1593 <div class="vbo-bookingdet-summary-roomname"><?php echo $or['name']; ?></div>
1594 <div class="vbo-bookingdet-summary-roomrate">
1595 <?php
1596 $active_rplan_id = 0;
1597 if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
1598 if (!empty($or['pkg_name'])) {
1599 //package
1600 echo $or['pkg_name'];
1601 } else {
1602 //custom cost can have an OTA Rate Plan name
1603 if (!empty($or['otarplan'])) {
1604 echo ucwords($or['otarplan']);
1605 } else {
1606 echo JText::translate('VBOROOMCUSTRATEPLAN');
1607 }
1608 }
1609 } elseif (!empty($tars[$num]) && !empty($tars[$num][0]['idprice'])) {
1610 $active_rplan_id = $tars[$num][0]['idprice'];
1611 $all_id_prices[] = $tars[$num][0]['idprice'];
1612 echo VikBooking::getPriceName($tars[$num][0]['idprice']);
1613 if (!empty($tars[$num][0]['attrdata'])) {
1614 ?>
1615 <div>
1616 <?php echo VikBooking::getPriceAttr($tars[$num][0]['idprice']).": ".$tars[$num][0]['attrdata']; ?>
1617 </div>
1618 <?php
1619 }
1620 } elseif (!empty($or['otarplan'])) {
1621 echo ucwords($or['otarplan']);
1622 } elseif ($row['closure'] < 1) {
1623 echo JText::translate('VBOROOMNORATE');
1624 }
1625 ?>
1626 </div>
1627 <?php
1628 // meals included in the room rate
1629 if (!empty($or['meals'])) {
1630 // display included meals defined at room-reservation record
1631 $included_meals = VBOMealplanManager::getInstance()->roomRateIncludedMeals($or);
1632 } else {
1633 // fetch default included meals in the selected rate plan
1634 $included_meals = $active_rplan_id ? VBOMealplanManager::getInstance()->ratePlanIncludedMeals($active_rplan_id) : [];
1635 }
1636 if (!$included_meals && empty($or['meals']) && !empty($row['idorderota']) && !empty($row['channel']) && !empty($row['custdata'])) {
1637 // attempt to fetch the included meal plans from the raw customer data or OTA reservation and room
1638 $included_meals = VBOMealplanManager::getInstance()->otaDataIncludedMeals($row, $or);
1639 }
1640 if ($included_meals) {
1641 ?>
1642 <div class="vbo-bookingdet-summary-roomrate vbo-bookingdet-summary-roommeals vbo-wider-badges-wrap">
1643 <?php
1644 foreach ($included_meals as $included_meal) {
1645 ?>
1646 <span class="badge badge-info"><?php echo $included_meal; ?></span>
1647 <?php
1648 }
1649 ?>
1650 </div>
1651 <?php
1652 }
1653
1654 if ($row['split_stay'] && count($room_stay_dates) && isset($room_stay_dates[$ind]) && $room_stay_dates[$ind]['idroom'] == $or['idroom']) {
1655 // print split stay information for this room
1656 $room_stay_checkin = !empty($room_stay_dates[$ind]['checkin_ts']) ? $room_stay_dates[$ind]['checkin_ts'] : $room_stay_dates[$ind]['checkin'];
1657 $room_stay_checkout = !empty($room_stay_dates[$ind]['checkout_ts']) ? $room_stay_dates[$ind]['checkout_ts'] : $room_stay_dates[$ind]['checkout'];
1658 $room_stay_nights = $av_helper->countNightsOfStay($room_stay_checkin, $room_stay_checkout);
1659 ?>
1660 <div class="vbo-cal-splitstay-details vbo-bookdet-splitstay-details">
1661 <div class="vbo-cal-splitstay-dates">
1662 <span class="vbo-cal-splitstay-room-nights"><?php VikBookingIcons::e('moon'); ?> <?php echo $room_stay_nights . ' ' . ($room_stay_nights > 1 ? JText::translate('VBDAYS') : JText::translate('VBDAY')); ?></span>
1663 <span class="vbo-cal-splitstay-dates-in" title="<?php echo date('H:i', $room_stay_checkin); ?>"><?php VikBookingIcons::e('plane-arrival'); ?> <?php echo date(str_replace("/", $datesep, $df), $room_stay_checkin); ?></span>
1664 <span class="vbo-cal-splitstay-dates-out" title="<?php echo date('H:i', $room_stay_checkout); ?>"><?php VikBookingIcons::e('plane-departure'); ?> <?php echo date(str_replace("/", $datesep, $df), $room_stay_checkout); ?></span>
1665 </div>
1666 </div>
1667 <?php
1668 } elseif (!$row['split_stay'] && count($room_stay_records) && isset($room_stay_records[$ind]) && $room_stay_records[$ind]['idroom'] == $or['idroom']) {
1669 // print modified stay dates information for this room
1670 $room_stay_checkin = $room_stay_records[$ind]['checkin'];
1671 $room_stay_checkout = $room_stay_records[$ind]['checkout'];
1672 $room_stay_nights = $av_helper->countNightsOfStay($room_stay_checkin, $room_stay_checkout);
1673 if ($room_stay_checkin != $row['checkin'] || $room_stay_checkout != $row['checkout']) {
1674 ?>
1675 <div class="vbo-cal-splitstay-details vbo-bookdet-splitstay-details vbo-bookdet-roomdatesmod-details">
1676 <div class="vbo-cal-splitstay-dates">
1677 <span class="vbo-cal-splitstay-room-nights"><?php VikBookingIcons::e('moon'); ?> <?php echo $room_stay_nights . ' ' . ($room_stay_nights > 1 ? JText::translate('VBDAYS') : JText::translate('VBDAY')); ?></span>
1678 <span class="vbo-cal-splitstay-dates-in" title="<?php echo date('H:i', $room_stay_checkin); ?>"><?php VikBookingIcons::e('plane-arrival'); ?> <?php echo date(str_replace("/", $datesep, $df), $room_stay_checkin); ?></span>
1679 <span class="vbo-cal-splitstay-dates-out" title="<?php echo date('H:i', $room_stay_checkout); ?>"><?php VikBookingIcons::e('plane-departure'); ?> <?php echo date(str_replace("/", $datesep, $df), $room_stay_checkout); ?></span>
1680 </div>
1681 </div>
1682 <?php
1683 }
1684 }
1685 ?>
1686 </td>
1687 <td>
1688 <div class="vbo-bookingdet-summary-price">
1689 <?php
1690 if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
1691 echo $currencyname.' '.VikBooking::numberFormat($or['cust_cost']);
1692 } elseif (!empty($tars[$num]) && !empty($tars[$num][0]['idprice'])) {
1693 $display_rate = !empty($or['room_cost']) ? $or['room_cost'] : $tars[$num][0]['cost'];
1694 echo $currencyname.' '.VikBooking::numberFormat(($after_tax ? VikBooking::sayCostPlusIva($display_rate, $tars[$num][0]['idprice']) : $display_rate));
1695 }
1696 ?>
1697 </div>
1698 </td>
1699 </tr>
1700 <?php
1701 //Options
1702 if (!empty($or['optionals'])) {
1703 $stepo = explode(";", $or['optionals']);
1704 $counter = 0;
1705 foreach ($stepo as $roptkey => $oo) {
1706 if (empty($oo)) {
1707 continue;
1708 }
1709 $stept = explode(":", $oo);
1710 $q = "SELECT * FROM `#__vikbooking_optionals` WHERE `id`=".(int)$stept[0].";";
1711 $dbo->setQuery($q);
1712 $actopt = $dbo->loadAssocList();
1713 if (!$actopt) {
1714 continue;
1715 }
1716 $counter++;
1717 $chvar = '';
1718 if (!empty($actopt[0]['ageintervals']) && $or['children'] > 0 && strstr($stept[1], '-') != false) {
1719 $optagenames = VikBooking::getOptionIntervalsAges($actopt[0]['ageintervals']);
1720 $optagepcent = VikBooking::getOptionIntervalsPercentage($actopt[0]['ageintervals']);
1721 $optageovrct = VikBooking::getOptionIntervalChildOverrides($actopt[0], $or['adults'], $or['children']);
1722 $child_num = VikBooking::getRoomOptionChildNumber($or['optionals'], $actopt[0]['id'], $roptkey, $or['children']);
1723 $optagecosts = VikBooking::getOptionIntervalsCosts(isset($optageovrct['ageintervals_child' . ($child_num + 1)]) ? $optageovrct['ageintervals_child' . ($child_num + 1)] : $actopt[0]['ageintervals']);
1724 $agestept = explode('-', $stept[1]);
1725 $stept[1] = $agestept[0];
1726 $chvar = $agestept[1];
1727 if (array_key_exists(($chvar - 1), $optagepcent) && $optagepcent[($chvar - 1)] == 1) {
1728 //percentage value of the adults tariff
1729 if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
1730 $optagecosts[($chvar - 1)] = $or['cust_cost'] * $optagecosts[($chvar - 1)] / 100;
1731 } else {
1732 $display_rate = !empty($or['room_cost']) ? $or['room_cost'] : $tars[$num][0]['cost'];
1733 $optagecosts[($chvar - 1)] = $display_rate * $optagecosts[($chvar - 1)] / 100;
1734 }
1735 } elseif (array_key_exists(($chvar - 1), $optagepcent) && $optagepcent[($chvar - 1)] == 2) {
1736 //VBO 1.10 - percentage value of room base cost
1737 if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
1738 $optagecosts[($chvar - 1)] = $or['cust_cost'] * $optagecosts[($chvar - 1)] / 100;
1739 } else {
1740 $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']);
1741 $optagecosts[($chvar - 1)] = $display_rate * $optagecosts[($chvar - 1)] / 100;
1742 }
1743 }
1744 if (!isset($optagenames[($chvar - 1)])) {
1745 $optagenames[($chvar - 1)] = '';
1746 }
1747 if (!isset($optagecosts[($chvar - 1)])) {
1748 $optagecosts[($chvar - 1)] = 0;
1749 }
1750 $actopt[0]['chageintv'] = $chvar;
1751 $actopt[0]['name'] .= ' ('.$optagenames[($chvar - 1)].')';
1752 $realcost = (intval($actopt[0]['perday']) == 1 ? (floatval($optagecosts[($chvar - 1)]) * $room_stay_nights * $stept[1]) : (floatval($optagecosts[($chvar - 1)]) * $stept[1]));
1753 } else {
1754 // VBO 1.11 - options percentage cost of the room total fee
1755 if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
1756 $deftar_basecosts = $or['cust_cost'];
1757 } else {
1758 $use_def_tar = isset($tars[$num]) && isset($tars[$num][0]) ? $tars[$num][0]['cost'] : 0;
1759 $deftar_basecosts = !empty($or['room_cost']) ? $or['room_cost'] : $use_def_tar;
1760 }
1761 $actopt[0]['cost'] = (int)$actopt[0]['pcentroom'] ? ($deftar_basecosts * $actopt[0]['cost'] / 100) : $actopt[0]['cost'];
1762 //
1763 $realcost = (intval($actopt[0]['perday']) == 1 ? ($actopt[0]['cost'] * $room_stay_nights * $stept[1]) : ($actopt[0]['cost'] * $stept[1]));
1764 }
1765 if ($actopt[0]['maxprice'] > 0 && $realcost > $actopt[0]['maxprice']) {
1766 $realcost = $actopt[0]['maxprice'];
1767 if (intval($actopt[0]['hmany']) == 1 && intval($stept[1]) > 1) {
1768 $realcost = $actopt[0]['maxprice'] * $stept[1];
1769 }
1770 }
1771 $realcost = $actopt[0]['perperson'] == 1 ? ($realcost * $arrpeople[$num]['adults']) : $realcost;
1772 $tmpopr = VikBooking::sayOptionalsPlusIva($realcost, $actopt[0]['idiva']);
1773 ?>
1774 <tr class="vbo-bookingdet-summary-options">
1775 <td class="vbo-bookingdet-summary-options-title"><?php echo $counter == 1 ? JText::translate('VBEDITORDEREIGHT') : '&nbsp;'; ?></td>
1776 <td>
1777 <span class="vbo-bookingdet-summary-lbl"><?php echo ($stept[1] > 1 ? $stept[1]." " : "").$actopt[0]['name']; ?></span>
1778 </td>
1779 <td>
1780 <span class="vbo-bookingdet-summary-cost"><?php echo $currencyname." ".VikBooking::numberFormat(($after_tax ? $tmpopr : $realcost)); ?></span>
1781 </td>
1782 </tr>
1783 <?php
1784 }
1785 }
1786 //Custom extra costs
1787 if (!empty($or['extracosts'])) {
1788 $counter = 0;
1789 $cur_extra_costs = json_decode($or['extracosts'], true);
1790 foreach ($cur_extra_costs as $eck => $ecv) {
1791 $counter++;
1792 $ecv['idtax'] = isset($ecv['idtax']) ? $ecv['idtax'] : 0;
1793 ?>
1794 <tr class="vbo-bookingdet-summary-custcosts">
1795 <td class="vbo-bookingdet-summary-custcosts-title"><?php echo $counter == 1 ? JText::translate('VBPEDITBUSYEXTRACOSTS') : '&nbsp;'; ?></td>
1796 <td>
1797 <?php
1798 if (!empty($ecv['type'])) {
1799 ?>
1800 <span class="vbo-tooltip vbo-tooltip-top" data-tooltiptext="<?php echo JHtml::fetch('esc_attr', JText::translate('VBPSHOWSEASONSTHREE') . ': ' . $ecv['type']); ?>">
1801 <span class="vbo-bookingdet-summary-lbl"><?php echo $ecv['name']; ?></span>
1802 </span>
1803 <?php
1804 } else {
1805 ?>
1806 <span class="vbo-bookingdet-summary-lbl"><?php echo $ecv['name']; ?></span>
1807 <?php
1808 }
1809 ?>
1810 </td>
1811 <td>
1812 <span class="vbo-bookingdet-summary-cost"><?php echo $currencyname." ".VikBooking::numberFormat(($after_tax ? VikBooking::sayOptionalsPlusIva($ecv['cost'], $ecv['idtax']) : $ecv['cost'])); ?></span>
1813 </td>
1814 </tr>
1815 <?php
1816 }
1817 }
1818 }
1819 //vikbooking 1.1 coupon
1820 if (strlen((string)$row['coupon']) > 0) {
1821 $expcoupon = explode(";", $row['coupon']);
1822 ?>
1823 <tr class="vbo-bookingdet-summary-coupon">
1824 <td><?php echo JText::translate('VBCOUPON'); ?></td>
1825 <td>
1826 <span class="vbo-bookingdet-summary-lbl"><?php echo $expcoupon[2]; ?></span>
1827 </td>
1828 <td>
1829 <span class="vbo-bookingdet-summary-cost">- <?php echo $currencyname; ?> <?php echo VikBooking::numberFormat($expcoupon[1]); ?></span>
1830 </td>
1831 </tr>
1832 <?php
1833 }
1834 if ($row['refund'] > 0) {
1835 ?>
1836 <tr class="vbo-bookingdet-summary-totpaid vbo-bookingdet-summary-totrefunded">
1837 <td>
1838 <strong><?php echo JText::translate('VBOBOOKHISTORYTRF'); ?></strong>
1839 </td>
1840 <td>
1841 <span class="vbo-amount-refunded-lbl"><?php echo JText::translate('VBO_AMOUNT_REFUNDED'); ?></span>
1842 </td>
1843 <td>
1844 <div id="vbo-amountrefunded-cont">
1845 <span id="vbo-amountrefunded-current"><?php echo $currencyname.' '.VikBooking::numberFormat($row['refund']); ?></span>
1846 <span id="vbo-amountrefunded-edit" style="margin-left: 5px; cursor: pointer;"><?php VikBookingIcons::e('edit'); ?></span>
1847 </div>
1848 <div id="vbo-amountrefunded-modcont" style="display: none;">
1849 <span id="vbo-amountrefunded-cancedit" style="margin-right: 5px; cursor: pointer;"><?php VikBookingIcons::e('times'); ?></span>
1850 <span id="vbo-amountrefunded-new"><input type="number" step="any" name="newamountrefunded" value="" min="0" style="margin: 0;" placeholder="<?php echo $row['refund']; ?>" disabled /></span>
1851 <span id="vbo-amountrefunded-save"><button type="submit" class="btn btn-success"><?php echo JText::translate('VBAPPLYDISCOUNTSAVE'); ?></button></span>
1852 </div>
1853 </td>
1854 </tr>
1855 <?php
1856 }
1857 //Reservation Total
1858 //Taxes Breakdown (only if tot_taxes is greater than 0)
1859 $tax_breakdown = array();
1860 $base_aliq = 0;
1861 if (count($all_id_prices) > 0 && $row['tot_taxes'] > 0) {
1862 //only last type of price assuming that the tax breakdown is equivalent in case of different rates
1863 $q = "SELECT `p`.`id`,`p`.`name`,`p`.`idiva`,`t`.`aliq`,`t`.`breakdown` FROM `#__vikbooking_prices` AS `p` LEFT JOIN `#__vikbooking_iva` `t` ON `p`.`idiva`=`t`.`id` WHERE `p`.`id`=".intval(array_pop($all_id_prices))." LIMIT 1;";
1864 $dbo->setQuery($q);
1865 $breakdown_info = $dbo->loadAssoc();
1866 if ($breakdown_info) {
1867 if (!empty($breakdown_info['breakdown']) && !empty($breakdown_info['aliq'])) {
1868 $tax_breakdown = json_decode($breakdown_info['breakdown'], true);
1869 $tax_breakdown = is_array($tax_breakdown) && count($tax_breakdown) > 0 ? $tax_breakdown : array();
1870 $base_aliq = $breakdown_info['aliq'];
1871 }
1872 }
1873 }
1874 //
1875 if ($printreceipt && $row['tot_taxes'] > 0) {
1876 // only when printing the receipt we display an additional row for the total amount of tax
1877 ?>
1878 <tr class="vbo-bookingdet-summary-total vbo-bookingdet-summary-totaltax">
1879 <td>
1880
1881 </td>
1882 <td>
1883 <span class="vbo-bookingdet-summary-lbl"><?php echo JText::translate('VBTOTALVAT'); ?></span>
1884 </td>
1885 <td>
1886 <span class="vbo-bookingdet-summary-cost"><?php echo $currencyname; ?> <?php echo VikBooking::numberFormat($row['tot_taxes']); ?></span>
1887 </td>
1888 </tr>
1889 <?php
1890 }
1891 ?>
1892 <tr class="vbo-bookingdet-summary-total">
1893 <td>
1894 <?php
1895 if (!$printreceipt) {
1896 ?>
1897 <span class="vbapplydiscsp" onclick="toggleDiscount(this);">
1898 <i class="<?php echo VikBookingIcons::i('chevron-down'); ?>" title="<?php echo htmlspecialchars(JText::translate('VBAPPLYDISCOUNT')); ?>"></i>
1899 </span>
1900 <?php
1901 }
1902 ?>
1903 </td>
1904 <td>
1905 <span class="vbo-bookingdet-summary-lbl"><?php echo JText::translate('VBEDITORDERNINE'); ?></span>
1906
1907 <div class="vbdiscenter" id="vbdiscenter" style="display: none;">
1908 <div class="vbdiscenter-entry">
1909 <span class="vbdiscenter-label"><?php echo JText::translate('VBTOTALVAT'); ?>:</span><span class="vbdiscenter-value"><?php echo $currencyname; ?> <input type="number" step="any" name="tot_taxes" value="<?php echo $row['tot_taxes']; ?>" size="4"/></span>
1910 </div>
1911 <?php
1912 if (count($tax_breakdown)) {
1913 foreach ($tax_breakdown as $tbkk => $tbkv) {
1914 $tax_break_cost = $row['tot_taxes'] * floatval($tbkv['aliq']) / $base_aliq;
1915 ?>
1916 <div class="vbdiscenter-entry vbdiscenter-entry-breakdown">
1917 <span class="vbdiscenter-label"><?php echo $tbkv['name']; ?>:</span><span class="vbdiscenter-value"><?php echo $currencyname; ?> <?php echo VikBooking::numberFormat($tax_break_cost); ?></span>
1918 </div>
1919 <?php
1920 }
1921 }
1922 ?>
1923 <div class="vbdiscenter-entry">
1924 <span class="vbdiscenter-label"><?php echo JText::translate('VBTOTALCITYTAX'); ?>:</span><span class="vbdiscenter-value"><?php echo $currencyname; ?> <input type="number" step="any" name="tot_city_taxes" value="<?php echo $row['tot_city_taxes']; ?>" size="4"/></span>
1925 </div>
1926 <div class="vbdiscenter-entry">
1927 <span class="vbdiscenter-label"><?php echo JText::translate('VBTOTALFEES'); ?>:</span><span class="vbdiscenter-value"><?php echo $currencyname; ?> <input type="number" step="any" name="tot_fees" value="<?php echo $row['tot_fees']; ?>" size="4"/></span>
1928 </div>
1929 <div class="vbdiscenter-entry">
1930 <span class="vbdiscenter-label hasTooltip"<?php echo !empty($otachannel_name) ? ' title="'.$otachannel_name.'"' : ''; ?>><?php echo JText::translate('VBTOTALCOMMISSIONS'); ?>:</span><span class="vbdiscenter-value"><?php echo $currencyname; ?> <input type="number" step="any" name="cmms" value="<?php echo $row['cmms']; ?>" size="4"/></span>
1931 </div>
1932 <div class="vbdiscenter-entry">
1933 <span class="vbdiscenter-label"><?php echo JText::translate('VBAPPLYDISCOUNT'); ?>:</span><span class="vbdiscenter-value"><?php echo $currencyname; ?> <input type="number" step="any" name="admindisc" value="<?php echo isset($expcoupon) ? (float)$expcoupon[1] : ''; ?>" size="4"/></span>
1934 </div>
1935 <div class="vbdiscenter-entrycentered">
1936 <button type="submit" class="btn btn-success"><?php echo JText::translate('VBAPPLYDISCOUNTSAVE'); ?></button>
1937 </div>
1938 </div>
1939 </td>
1940 <td>
1941 <span class="vbo-bookingdet-summary-cost"><?php echo (strlen($otacurrency) > 0 ? '('.$otacurrency.') '.$currencyname : $currencyname); ?> <?php echo VikBooking::numberFormat($row['total']); ?></span>
1942 </td>
1943 </tr>
1944 <?php
1945 if ($row['total'] > 0 && !$row['closure']) {
1946 $has_paid = ($row['totpaid'] > 0);
1947 $diff_to_pay = $has_paid ? ($row['total'] - $row['totpaid']) : 0;
1948 if ($has_paid || $row['status'] != 'standby') {
1949 ?>
1950 <tr class="vbo-bookingdet-summary-totpaid">
1951 <td>&nbsp;</td>
1952 <td><?php echo JText::translate('VBAMOUNTPAID'); ?></td>
1953 <td>
1954 <div id="vbo-amountpaid-cont">
1955 <span id="vbo-amountpaid-current"><?php echo $has_paid ? ($currencyname . ' ' . VikBooking::numberFormat($row['totpaid'])) : ''; ?></span>
1956 <span id="vbo-amountpaid-edit" style="margin-left: 5px; cursor: pointer;"><?php VikBookingIcons::e('edit'); ?></span>
1957 </div>
1958 <div id="vbo-amountpaid-modcont" style="display: none;">
1959 <span id="vbo-amountpaid-cancedit" style="margin-right: 5px; cursor: pointer;"><?php VikBookingIcons::e('times'); ?></span>
1960 <span id="vbo-amountpaid-new"><input type="number" step="any" name="newamountpaid" value="" min="0" style="margin: 0;" placeholder="<?php echo $has_paid ? $row['totpaid'] : ''; ?>" disabled /></span>
1961 <?php
1962 if ($payments) {
1963 ?>
1964 <span id="vbo-amountpaid-paymeth" style="margin: 0 5px; max-width: 160px;">
1965 <select name="newamountpaymeth" style="margin: 0;">
1966 <option value=""><?php echo JText::translate('VBPAYMENTMETHOD'); ?></option>
1967 <?php
1968 foreach ($payments as $pay) {
1969 ?>
1970 <option value="<?php echo JHtml::fetch('esc_attr', $pay['id'] . '_' . $pay['name']); ?>"><?php echo $pay['name']; ?></option>
1971 <?php
1972 }
1973 ?>
1974 </select>
1975 </span>
1976 <?php
1977 }
1978 ?>
1979 <span id="vbo-amountpaid-save"><button type="submit" class="btn btn-success"><?php echo JText::translate('VBAPPLYDISCOUNTSAVE'); ?></button></span>
1980 </div>
1981 </td>
1982 </tr>
1983 <?php
1984 }
1985 if ($diff_to_pay > 1 && $row['status'] != 'cancelled') {
1986 ?>
1987 <tr class="vbo-bookingdet-summary-totpaid vbo-bookingdet-summary-totremaining">
1988 <td>&nbsp;</td>
1989 <td>
1990 <div><?php echo JText::translate('VBTOTALREMAINING'); ?></div>
1991 <?php
1992 // enable second payment
1993 if (!$printreceipt && $row['status'] == 'confirmed' && !($row['paymcount'] > 0) && VikBooking::multiplePayments() && is_array($payment) && !empty($payment['id'])) {
1994 ?>
1995 <div style="margin-top: 5px;">
1996 <a href="index.php?option=com_vikbooking&amp;task=editorder&amp;makepay=1&amp;cid[]=<?php echo $row['id']; ?>" class="vbo-makepayable-link"><?php VikBookingIcons::e('credit-card'); ?> <?php echo JText::translate('VBMAKEORDERPAYABLE'); ?></a>
1997 </div>
1998 <?php
1999 }
2000 ?>
2001 </td>
2002 <td><?php echo $currencyname . ' ' . VikBooking::numberFormat($diff_to_pay); ?></td>
2003 </tr>
2004 <?php
2005 }
2006 }
2007 if (!$printreceipt && $row['status'] == 'confirmed' && VikBooking::multiplePayments() && is_array($payment) && !empty($payment['id']) && $row['checkout'] > time()) {
2008 /**
2009 * The amount payable can be modified by the admin.
2010 *
2011 * @since 1.14 (J) - 1.4.0 (WP)
2012 */
2013 ?>
2014 <tr class="vbo-bookingdet-summary-totpaid vbo-bookingdet-summary-totpayable">
2015 <td>&nbsp;</td>
2016 <td>
2017 <span class="vbo-amount-payable-lbl<?php echo $row['payable'] > 0 ? ' vbo-amount-payable-lbl-requested' : ''; ?>"><?php echo $row['payable'] > 0 ? JText::translate('VBO_AMOUNT_PAYABLE') : JText::translate('VBO_AMOUNT_PAYABLE_RQ'); ?></span>
2018 </td>
2019 <td>
2020 <div id="vbo-amountpayable-cont">
2021 <?php
2022 if ($row['payable'] > 0) {
2023 ?>
2024 <span id="vbo-amountpayable-current"><?php echo $currencyname . ' ' . VikBooking::numberFormat($row['payable']); ?></span>
2025 <?php
2026 }
2027 ?>
2028 <span id="vbo-amountpayable-edit" style="margin-left: 5px; cursor: pointer;"><?php VikBookingIcons::e('edit'); ?></span>
2029 </div>
2030 <div id="vbo-amountpayable-modcont" style="display: none;">
2031 <span id="vbo-amountpayable-cancedit" style="margin-right: 5px; cursor: pointer;"><?php VikBookingIcons::e('times'); ?></span>
2032 <span id="vbo-amountpayable-new"><input type="number" step="any" name="newamountpayable" value="" min="0" style="margin: 0;" placeholder="<?php echo $row['payable']; ?>" disabled /></span>
2033 <span id="vbo-amountpayable-save"><button type="submit" class="btn btn-success"><?php echo JText::translate('VBAPPLYDISCOUNTSAVE'); ?></button></span>
2034 </div>
2035 </td>
2036 </tr>
2037 <?php
2038 }
2039
2040 /**
2041 * Cancellation fee for cancelled bookings after the deadline.
2042 *
2043 * @since 1.16.0 (J) - 1.6.0 (WP)
2044 */
2045 if ($row['status'] == 'cancelled' && !$row['closure'] && $row['total'] > 0) {
2046 ?>
2047 <tr class="vbo-bookingdet-summary-cancfee">
2048 <td>&nbsp;</td>
2049 <td><?php echo JText::translate('VBO_CANC_FEE'); ?></td>
2050 <td>
2051 <div id="vbo-cancfee-cont">
2052 <span id="vbo-cancfee-current"><?php echo $currencyname.' '.VikBooking::numberFormat($row['canc_fee']); ?></span>
2053 <span id="vbo-cancfee-edit" style="margin-left: 5px; cursor: pointer;"><?php VikBookingIcons::e('edit'); ?></span>
2054 </div>
2055 <div id="vbo-cancfee-modcont" style="display: none;">
2056 <span id="vbo-cancfee-cancedit" style="margin-right: 5px; cursor: pointer;"><?php VikBookingIcons::e('times'); ?></span>
2057 <span id="vbo-cancfee-new"><input type="number" step="any" name="newcancfee" value="" min="0" style="margin: 0;" placeholder="<?php echo $row['canc_fee']; ?>" disabled /></span>
2058 <span id="vbo-cancfee-save"><button type="submit" class="btn btn-success"><?php echo JText::translate('VBAPPLYDISCOUNTSAVE'); ?></button></span>
2059 </div>
2060 </td>
2061 </tr>
2062 <?php
2063 }
2064 ?>
2065 </table>
2066 </div>
2067
2068 <!-- Define role to detect the supported hook -->
2069 <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorder","type":"fieldset"} -->
2070
2071 <?php
2072 foreach ($bookingPanelForms as $legend => $form)
2073 {
2074 if (in_array($legend, ['buttons']))
2075 {
2076 // skip default forms
2077 continue;
2078 }
2079 ?>
2080 <div class="table-responsive">
2081 <h3><?php echo JText::translate($legend); ?></h3>
2082
2083 <?php echo $form; ?>
2084 </div>
2085 <?php
2086 }
2087 ?>
2088
2089 </div>
2090 </div>
2091 <?php
2092 if ($printreceipt) {
2093 $receipt_notes = VikBooking::getReceiptNotes();
2094 ?>
2095 <div class="vbo-receipt-notes-container">
2096 <div class="vbo-receipt-notes-inner">
2097 <div class="vbo-receipt-notes-val vbo-showin-print" id="vbo-receipt-notes-val"><?php echo $receipt_notes; ?></div>
2098 <div class="vbo-receipt-notes-tarea vbo-hidein-print">
2099 <textarea id="vbo-receipt-notes" placeholder="<?php echo JText::translate('VBORECEIPTNOTESDEF'); ?>"><?php echo htmlspecialchars($receipt_notes); ?></textarea>
2100 </div>
2101 </div>
2102 </div>
2103 <?php
2104 }
2105 ?>
2106 </div>
2107
2108 <div class="vbo-bookingdet-tab-cont" id="vbo-tab-admin" style="display: none;">
2109 <div class="vbo-bookingdet-innercontainer">
2110 <div class="vbo-bookingdet-admindata">
2111 <?php
2112 if (!$row['closure']) {
2113 ?>
2114 <div class="vbo-bookingdet-admin-entry">
2115 <label for="vbo-searchcust"><?php echo JText::translate(count($customer) ? 'VBOASSIGNNEWCUST' : 'VBFILLCUSTFIELDS'); ?></label>
2116 <span style="display: block;"><?php echo JText::translate('VBOSEARCHEXISTCUST'); ?></span>
2117 <span class="vbo-eorder-assigncust" style="margin-bottom: 1px;">
2118 <input type="text" id="vbo-searchcust" autocomplete="off" value="" placeholder="<?php echo JText::translate('VBOSEARCHCUSTBY'); ?>" size="30" style="margin-bottom: 0;" />
2119 </span>
2120 <span id="vbo-searchcust-loading">
2121 <?php VikBookingIcons::e('hourglass-half'); ?>
2122 </span>
2123 <input type="hidden" name="newcustid" id="newcustid" value="" />
2124 <div id="vbo-searchcust-res" style="position: absolute; background-color: #fff;"></div>
2125 <span class="vbo-eorder-assignnewcust" style="display: block; margin-top: 10px;">
2126 <a class="vbo-assign-customer" href="index.php?option=com_vikbooking&task=newcustomer&bid=<?php echo $row['id']; ?>&goto=<?php echo base64_encode($gotouri.'#tab-admin'); ?>">
2127 <?php VikBookingIcons::e('user-circle'); ?>
2128 <span><?php echo JText::translate('VBOCREATENEWCUST'); ?></span>
2129 </a>
2130 </span>
2131
2132 <?php
2133 if (isset($adminSidebarForms['customer']))
2134 {
2135 echo $adminSidebarForms['customer'];
2136 }
2137 ?>
2138
2139 </div>
2140 <?php
2141 }
2142 ?>
2143 <div class="vbo-bookingdet-admin-entry">
2144 <label for="newpayment"><?php echo JText::translate('VBPAYMENTMETHOD'); ?></label>
2145 <?php
2146 if (is_array($payment)) {
2147 ?>
2148 <span><?php echo $payment['name']; ?></span>
2149 <?php
2150 }
2151 $chpayment = '';
2152 if ($payments) {
2153 $chpayment = '<div><select name="newpayment" id="newpayment" onchange="changePayment();"><option value="">'.JText::translate('VBCHANGEPAYLABEL').'</option>';
2154 foreach ($payments as $pay) {
2155 $chpayment .= '<option value="'.$pay['id'].'">'.(is_array($payment) && $payment['id'] == $pay['id'] ? ' ::' : '').$pay['name'].'</option>';
2156 }
2157 $chpayment .= '</select></div>';
2158 }
2159 echo $chpayment;
2160 ?>
2161
2162 <!-- Define role to detect the supported hook -->
2163 <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderAdministrationSidebar","key":"payment","type":"field"} -->
2164
2165 <?php
2166 if (isset($adminSidebarForms['payment']))
2167 {
2168 echo $adminSidebarForms['payment'];
2169 }
2170 ?>
2171
2172 </div>
2173 <?php
2174 $tn = VikBooking::getTranslator();
2175 $all_langs = $tn->getLanguagesList();
2176 if (count($all_langs) > 1) {
2177 ?>
2178 <div class="vbo-bookingdet-admin-entry">
2179 <label for="newlang"><?php echo JText::translate('VBOBOOKINGLANG'); ?></label>
2180 <select name="newlang" id="newlang" onchange="document.adminForm.submit();">
2181 <?php
2182 foreach ($all_langs as $lk => $lv) {
2183 ?>
2184 <option value="<?php echo $lk; ?>"<?php echo $row['lang'] == $lk ? ' selected="selected"' : ''; ?>><?php echo isset($lv['nativeName']) ? $lv['nativeName'] : $lv['name']; ?></option>
2185 <?php
2186 }
2187 ?>
2188 </select>
2189
2190 <!-- Define role to detect the supported hook -->
2191 <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderAdministrationSidebar","key":"language","type":"field"} -->
2192
2193 <?php
2194 if (isset($adminSidebarForms['language']))
2195 {
2196 echo $adminSidebarForms['language'];
2197 }
2198 ?>
2199 </div>
2200 <?php
2201 }
2202 ?>
2203
2204 <!-- Define role to detect the supported hook -->
2205 <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderAdministrationSidebar","type":"fieldset"} -->
2206
2207 <?php
2208 foreach ($adminSidebarForms as $legend => $form)
2209 {
2210 if (in_array($legend, ['customer', 'payment', 'language']))
2211 {
2212 // skip default forms
2213 continue;
2214 }
2215 ?>
2216 <div class="vbo-bookingdet-admin-entry">
2217 <h3><?php echo JText::translate($legend); ?></h3>
2218
2219 <?php echo $form; ?>
2220 </div>
2221 <?php
2222 }
2223 ?>
2224
2225 </div>
2226 <div class="vbo-bookingdet-noteslogs">
2227 <?php
2228 $history = $history_obj->loadHistory();
2229 ?>
2230 <div class="vbo-bookingdet-noteslogs-btns">
2231 <div class="vbo-bookingdet-noteslogs-btn vbo-bookingdet-noteslogs-btn-active" data-id="notes">
2232 <a href="javascript: void(0);" id="vbo-trig-notes" onclick="javascript: vbToggleNotes(this);">
2233 <?php VikBookingIcons::e('user-lock'); ?>
2234 <span class="vbo-bookingdet-admintab-lbl"><?php echo JText::translate('VBADMINNOTESTOGGLE'); ?></span>
2235 </a>
2236 </div>
2237 <?php
2238 /**
2239 * Initialize chat instance by getting the proper channel name
2240 *
2241 * @since 1.12
2242 */
2243 if (empty($row['channel'])) {
2244 // front-end reservation chat handler
2245 $chat_channel = 'vikbooking';
2246 } else {
2247 $channelparts = explode('_', $row['channel']);
2248 // check if this is a meta search channel
2249 $is_meta_search = false;
2250 if (preg_match("/(customer).*[0-9]$/", $channelparts[0]) || !strcasecmp($channelparts[0], 'googlehotel') || !strcasecmp($channelparts[0], 'trivago')) {
2251 $is_meta_search = empty($row['idorderota']);
2252 }
2253 if ($is_meta_search) {
2254 // customer of type sales channel should use front-end reservation chat handler
2255 $chat_channel = 'vikbooking';
2256 } else {
2257 // let the getInstance method validate the channel chat handler
2258 $chat_channel = $row['channel'];
2259 }
2260 }
2261 $messaging = VikBooking::getVcmChatInstance($row['id'], $chat_channel);
2262 //
2263 if (!$printreceipt && !is_null($messaging)) {
2264 ?>
2265 <div class="vbo-bookingdet-noteslogs-btn" data-id="messaging">
2266 <a name="messaging" href="javascript: void(0);" id="vbo-trig-messaging" onclick="javascript: vbToggleMessaging(this);">
2267 <?php VikBookingIcons::e('comment-dots'); ?>
2268 <span class="vbo-bookingdet-admintab-lbl"><?php echo JText::translate('VBO_GUEST_MESSAGING'); ?></span>
2269 </a>
2270 </div>
2271 <?php
2272 }
2273
2274 /**
2275 * Build up a tab to summarize the "takings" for this sole booking in case of relevant events.
2276 *
2277 * @since 1.16.9 (J) - 1.6.9 (WP)
2278 */
2279 $takings = [];
2280 if ($history) {
2281 // payment related events
2282 $h_payment_group = $history_obj->getTypeGroups($group = 'GPM');
2283
2284 // merge default types with 'PU' for the manually set "new amount paid" and with 'RU' (refunded amount updated)
2285 $takings_events = array_unique(array_merge(($h_payment_group['types'] ?? []), ['PU', 'RU']));
2286
2287 // load the relevant events with data
2288 $takings = $history_obj->getEventsWithData($takings_events, null, false);
2289
2290 if ($takings) {
2291 ?>
2292 <div class="vbo-bookingdet-noteslogs-btn pro-feature" data-id="takings">
2293 <a href="javascript: void(0);" id="vbo-trig-bookhistory" onclick="javascript: vbToggleDynamicPanel(this, '#vboextrapanel-takings');">
2294 <?php VikBookingIcons::e('wallet'); ?>
2295 <span class="vbo-bookingdet-admintab-lbl"><?php echo JText::translate('VBO_TAKINGS'); ?></span>
2296 </a>
2297 </div>
2298 <?php
2299 }
2300 }
2301
2302 if ($history) {
2303 ?>
2304 <div class="vbo-bookingdet-noteslogs-btn" data-id="history">
2305 <a href="javascript: void(0);" id="vbo-trig-bookhistory" onclick="javascript: vbToggleHistory(this);">
2306 <?php VikBookingIcons::e('history'); ?>
2307 <span class="vbo-bookingdet-admintab-lbl"><?php echo JText::translate('VBOBOOKHISTORYTAB'); ?></span>
2308 </a>
2309 </div>
2310 <script type="text/javascript">
2311 if (window.location.hash == '#bookhistory') {
2312 setTimeout(function() {
2313 jQuery(".vbo-bookingdet-tab[data-vbotab='vbo-tab-admin']").trigger('click');
2314 vbToggleHistory(document.getElementById('vbo-trig-bookhistory'));
2315 }, 500);
2316 }
2317 </script>
2318 <?php
2319 }
2320 ?>
2321 <div class="vbo-bookingdet-noteslogs-btn pro-feature" data-id="invnotes">
2322 <a href="javascript: void(0);" class="hasTooltip" id="vbo-trig-invnotes" onclick="javascript: vbToggleInvNotes(this);" title="<?php echo addslashes(JText::translate('VBBOOKINGINVNOTESHELP')); ?>">
2323 <?php VikBookingIcons::e('file-invoice'); ?>
2324 <span class="vbo-bookingdet-admintab-lbl"><?php echo JText::translate('VBBOOKINGINVNOTES'); ?></span>
2325 </a>
2326 </div>
2327
2328 <!-- Define role to detect the supported hook -->
2329 <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderAdministration","type":"fieldset"} -->
2330
2331 <?php
2332 foreach ($adminPanelForms as $legend => $form)
2333 {
2334 $legendId = preg_replace("/[^a-zA-Z0-9_\-]+/", '', $legend);
2335 ?>
2336 <div class="vbo-bookingdet-noteslogs-btn" data-id="<?php echo $legendId; ?>">
2337 <a href="javascript: void(0);" class="hasTooltip" id="vbo-trig-<?php echo $legendId; ?>" onclick="javascript: vbToggleDynamicPanel(this, '#vboextrapanel-<?php echo $legendId; ?>');">
2338 <?php VikBookingIcons::e(!empty($adminFormsSetup->icons[$legend]) ? $adminFormsSetup->icons[$legend] : 'plug'); ?>
2339 <span class="vbo-bookingdet-admintab-lbl"><?php echo JText::translate($legend); ?></span>
2340 </a>
2341 </div>
2342 <?php
2343 }
2344
2345 if (!empty($row['paymentlog'])) {
2346 $paylogs_lbl = JText::translate('VBPAYMENTLOGTOGGLE');
2347 if (stripos($row['paymentlog'], 'card number') !== false && strpos($row['paymentlog'], '****') !== false) {
2348 $paylogs_lbl = JText::translate('VBO_CREDIT_CARD');
2349 }
2350 ?>
2351 <div class="vbo-bookingdet-noteslogs-btn" data-id="paylogs">
2352 <a href="javascript: void(0);" id="vbo-trig-paylogs" onclick="javascript: vbToggleLog(this);">
2353 <?php VikBookingIcons::e('credit-card'); ?>
2354 <span class="vbo-bookingdet-admintab-lbl"><?php echo $paylogs_lbl; ?></span>
2355 </a>
2356 <a name="paymentlog" href="javascript: void(0);"></a>
2357 </div>
2358 <?php
2359 }
2360 ?>
2361 </div>
2362 <div class="vbo-bookingdet-noteslogs-cont">
2363 <div id="vbadminnotesdiv" class="vbo-extra-panel" style="display: block;">
2364 <textarea name="adminnotes" class="vbadminnotestarea"><?php echo strip_tags((string)$row['adminnotes']); ?></textarea>
2365 <input type="submit" name="updadmnotes" value="<?php echo JText::translate('VBADMINNOTESUPD'); ?>" class="btn btn-success" />
2366 </div>
2367 <?php
2368 if ($takings) {
2369 ?>
2370 <div class="vbo-extra-panel" id="vboextrapanel-takings" style="display: none;">
2371 <div class="vbo-booking-takings-container table-responsive">
2372 <table class="table">
2373 <thead>
2374 <tr class="vbo-booking-takings-firstrow">
2375 <td class="vbo-booking-takings-td-totpaid"><?php echo JText::translate('VBO_TAKINGS'); ?></td>
2376 <td class="vbo-booking-takings-td-date"><?php echo JText::translate('VBOBOOKHISTORYLBLDATE'); ?></td>
2377 <td class="vbo-booking-takings-td-type"><?php echo JText::translate('VBOBOOKHISTORYLBLTYPE'); ?></td>
2378 <td class="vbo-booking-takings-td-fees"><?php echo JText::translate('VBO_PROCESSING_FEES'); ?></td>
2379 <td class="vbo-booking-takings-td-descr"><?php echo JText::translate('VBOBOOKHISTORYLBLDESC'); ?></td>
2380 </tr>
2381 </thead>
2382 <tbody>
2383 <?php
2384 $booking_total_taking = 0;
2385 $booking_total_prfees = 0;
2386 foreach (array_reverse($takings) as $hist) {
2387 // calculate amount paid and description
2388 $tn_amount_paid = 0;
2389 $tn_amount_fees = 0;
2390 $tn_description = strpos($hist['descr'], '<') !== false ? $hist['descr'] : preg_replace("/\R/", ' - ', $hist['descr']);
2391 if (is_object($hist['data'])) {
2392 // calculate amount paid or amount refunded
2393 if (($hist['data']->amount_paid ?? 0)) {
2394 $tn_amount_paid = $hist['data']->amount_paid;
2395 if (in_array($hist['type'], ['RF', 'RU'])) {
2396 // turn the amount paid to negative
2397 $tn_amount_paid = $tn_amount_paid < 0 ? $tn_amount_paid : ($tn_amount_paid - ($tn_amount_paid * 2));
2398 if ($hist['type'] === 'RU' && $hist['data']->amount_paid < 0) {
2399 // this indicates a lower amount refunded, so we double it to make it positive
2400 $tn_amount_paid = abs($hist['data']->amount_paid);
2401 }
2402 }
2403 }
2404
2405 // calculate processing fees, if set and if any
2406 if (($hist['data']->processing_fees ?? 0)) {
2407 $tn_amount_fees += $hist['data']->processing_fees;
2408 }
2409
2410 // build the event description
2411 if (($hist['data']->payment_method ?? '')) {
2412 $tn_description = ucwords($hist['data']->payment_method);
2413 } elseif (($hist['data']->driver ?? '')) {
2414 $tn_description = ucwords(str_replace('_', ' ', basename($hist['data']->driver, '.php')));
2415 }
2416 }
2417
2418 // increase (or decrease) booking total takings and processing fees amounts
2419 $booking_total_taking += $tn_amount_paid;
2420 $booking_total_prfees += $tn_amount_fees;
2421 ?>
2422 <tr class="vbo-booking-takings-row">
2423 <td><?php echo $currencysymb . ' ' . VikBooking::numberFormat($tn_amount_paid); ?></td>
2424 <td><?php echo JHtml::fetch('date', $hist['dt'], 'Y-m-d H:i:s'); ?></td>
2425 <td><?php echo $history_obj->validType($hist['type'], true); ?></td>
2426 <td><?php echo $currencysymb . ' ' . VikBooking::numberFormat($tn_amount_fees); ?></td>
2427 <td><?php echo $tn_description; ?></td>
2428 </tr>
2429 <?php
2430 }
2431 ?>
2432 </tbody>
2433 <tfoot>
2434 <tr>
2435 <td colspan="2">
2436 <span><?php echo $currencysymb . ' ' . VikBooking::numberFormat($booking_total_taking); ?></span>
2437 </td>
2438 <td></td>
2439 <td colspan="2">
2440 <span><?php echo $currencysymb . ' ' . VikBooking::numberFormat($booking_total_prfees); ?></span>
2441 </td>
2442 </tr>
2443 </tfoot>
2444 </table>
2445 </div>
2446 </div>
2447 <?php
2448 }
2449 if ($history) {
2450 ?>
2451 <div id="vbhistorydiv" class="vbo-extra-panel" style="display: none;">
2452 <div class="vbo-booking-history-container table-responsive">
2453 <table class="table">
2454 <thead>
2455 <tr class="vbo-booking-history-firstrow">
2456 <td class="vbo-booking-history-td-type"><?php echo JText::translate('VBOBOOKHISTORYLBLTYPE'); ?></td>
2457 <td class="vbo-booking-history-td-date"><?php echo JText::translate('VBOBOOKHISTORYLBLDATE'); ?></td>
2458 <td class="vbo-booking-history-td-descr"><?php echo JText::translate('VBOBOOKHISTORYLBLDESC'); ?></td>
2459 <td class="vbo-booking-history-td-totpaid"><?php echo JText::translate('VBOBOOKHISTORYLBLTPAID'); ?></td>
2460 <td class="vbo-booking-history-td-tot"><?php echo JText::translate('VBOBOOKHISTORYLBLTOT'); ?></td>
2461 </tr>
2462 </thead>
2463 <tbody>
2464 <?php
2465 foreach ($history as $hist) {
2466 $hdescr = strpos($hist['descr'], '<') !== false ? $hist['descr'] : nl2br($hist['descr']);
2467 ?>
2468 <tr class="vbo-booking-history-row">
2469 <td><?php echo $history_obj->validType($hist['type'], true); ?></td>
2470 <td><?php echo JHtml::fetch('date', $hist['dt'], 'Y-m-d H:i:s'); ?></td>
2471 <td><?php echo $hdescr; ?></td>
2472 <td><?php echo $currencyname.' '.VikBooking::numberFormat($hist['totpaid']); ?></td>
2473 <td><?php echo $currencyname.' '.VikBooking::numberFormat($hist['total']); ?></td>
2474 </tr>
2475 <?php
2476 }
2477 ?>
2478 </tbody>
2479 </table>
2480 </div>
2481 </div>
2482 <?php
2483 }
2484 ?>
2485 <div id="vbinvnotesdiv" class="vbo-extra-panel" style="display: none;">
2486 <textarea name="invnotes" id="invnotes" class="vbadminnotestarea"><?php echo $row['inv_notes']; ?></textarea>
2487 <input type="submit" name="updinvnotes" value="<?php echo JText::translate('VBADMINNOTESUPD'); ?>" class="btn btn-success" />
2488 <button type="button" class="btn vbo-config-btn btn-secondary pull-right" onclick="document.getElementById('invnotes-hid').value=document.getElementById('invnotes').value;document.getElementById('vbo-gen-invoice').submit();"><?php VikBookingIcons::e('file-invoice'); ?> <?php echo JText::translate('VBOGENBOOKINGINVOICE'); ?></button>
2489 </div>
2490 <?php
2491 if (!empty($row['paymentlog'])) {
2492 ?>
2493 <div id="vbpaymentlogdiv" class="vbo-extra-panel" style="display: none;">
2494 <div class="vbo-eorder-paymentlog-buttons">
2495 <?php
2496 // PCI Data Retrieval
2497 $cc_acl_denied = false;
2498 if (!empty($row['idorderota']) && !empty($row['channel'])) {
2499 $channel_source = $row['channel'];
2500 if (strpos($row['channel'], '_') !== false) {
2501 $channelparts = explode('_', $row['channel']);
2502 $channel_source = $channelparts[0];
2503 }
2504 $checkout_info = getdate($row['checkout']);
2505
2506 // validate ACL for credit card details
2507 if (!$canDo->authorise('core.admin', 'com_vikchannelmanager')) {
2508 // permissions to access VCM are required
2509 $cc_acl_denied = true;
2510 ?>
2511 <p class="err"><?php echo JText::translate('JERROR_ALERTNOAUTHOR'); ?></p>
2512 <?php
2513 } else {
2514 /**
2515 * Limit for accessing the credit card details has been changed to check-out
2516 * day at 23:59:59 + 10 extra days. It used to be at 23:59:59 on check-out day.
2517 *
2518 * @since 1.13
2519 */
2520 $cardlimit = mktime(23, 59, 59, $checkout_info['mon'], ($checkout_info['mday'] + 10), $checkout_info['year']);
2521 if (time() < $cardlimit) {
2522 $plain_log = htmlspecialchars($row['paymentlog']);
2523 if (stripos($plain_log, 'card number') !== false && strpos($plain_log, '****') !== false) {
2524 // log contains credit card details
2525 // Prepare modal (Credit Card Details)
2526 array_push($vbo_modals_html, $vbo_app->getJmodalHtml('vbo-vcm-pcid', JText::translate('GETFULLCARDDETAILS'), '', 'width: 80%; height: 60%; margin-left: -40%; top: 20% !important;'));
2527 // end Prepare modal
2528 ?>
2529 <div class="vcm-notif-pcidrq-container">
2530 <button type="button" class="btn vbo-config-btn vcm-pcid-launch" onclick="vboOpenJModal('vbo-vcm-pcid', 'index.php?option=com_vikchannelmanager&task=execpcid&channel_source=<?php echo $channel_source; ?>&otaid=<?php echo $row['idorderota']; ?>&tmpl=component');"><?php VikBookingIcons::e('credit-card'); ?> <?php echo JText::translate('GETFULLCARDDETAILS'); ?></button>
2531 </div>
2532 <?php
2533 }
2534 }
2535 }
2536 } elseif (empty($row['idorderota']) && !empty($row['paymentlog']) && $row['status'] == 'standby') {
2537 ?>
2538 <div class="vbo-eorder-emptyccdata">
2539 <a class="btn btn-warning" href="index.php?option=com_vikbooking&task=editorder&cid[]=<?php echo $row['id']; ?>&unset_cc=1" onclick="return confirm(Joomla.JText._('VBDELCONFIRM'));"><?php VikBookingIcons::e('broom'); ?> <?php echo JText::translate('VBO_EMPTY_DATA'); ?></a>
2540 </div>
2541 <?php
2542 }
2543
2544 /**
2545 * Attempt to display the reporting invalid credit card layout from VCM.
2546 *
2547 * @requires VCM >= 1.8.27
2548 *
2549 * @since 1.16.9 (J) - 1.6.9 (WP)
2550 */
2551 try {
2552 // prepare the layout data array
2553 $layout_data = [
2554 'caller' => 'vikbooking',
2555 'booking' => $row,
2556 ];
2557
2558 ?>
2559 <div class="vbo-eorder-vcm-reporting-invalidcc">
2560 <?php
2561 // render the reporting-invalidcc layout
2562 echo JLayoutHelper::render('reporting.invalidcc', $layout_data, null, [
2563 'component' => 'com_vikchannelmanager',
2564 'client' => 'administrator',
2565 ]);
2566 ?>
2567 </div>
2568 <?php
2569 } catch(Throwable $e) {
2570 // do nothing
2571 }
2572
2573 ?>
2574 </div>
2575 <?php
2576
2577 if (!$cc_acl_denied) {
2578 ?>
2579 <pre><?php echo htmlspecialchars($row['paymentlog']); ?></pre>
2580 <?php
2581 }
2582 ?>
2583 </div>
2584
2585 <script type="text/javascript">
2586 if (window.location.hash == '#paymentlog') {
2587 setTimeout(function() {
2588 jQuery(".vbo-bookingdet-tab[data-vbotab='vbo-tab-admin']").trigger('click');
2589 vbToggleLog(document.getElementById('vbo-trig-paylogs'));
2590 }, 500);
2591 }
2592 </script>
2593 <?php
2594 }
2595 if (!$printreceipt && !is_null($messaging)) {
2596 ?>
2597 <div id="vbmessagingdiv" class="vbo-extra-panel" style="display: none;">
2598 <?php echo $messaging->renderChat(); ?>
2599 </div>
2600 <script type="text/javascript">
2601 jQuery(function() {
2602 if (window.location.hash == '#messaging') {
2603 setTimeout(function() {
2604 jQuery(".vbo-bookingdet-tab[data-vbotab='vbo-tab-admin']").trigger('click');
2605 vbToggleMessaging(document.getElementById('vbo-trig-messaging'));
2606 }, 100);
2607 }
2608 });
2609 </script>
2610 <?php
2611 }
2612
2613 foreach ($adminPanelForms as $legend => $form)
2614 {
2615 $legendId = preg_replace("/[^a-zA-Z0-9_\-]+/", '', $legend);
2616 ?>
2617 <div class="vbo-extra-panel" id="vboextrapanel-<?php echo $legendId; ?>" style="display: none;">
2618 <?php echo $form; ?>
2619 </div>
2620 <?php
2621 }
2622 ?>
2623 </div>
2624 </div>
2625 </div>
2626 </div>
2627
2628 <input type="hidden" name="task" value="editorder">
2629 <input type="hidden" name="vbo_active_tab" id="vbo_active_tab" value="">
2630 <input type="hidden" name="whereup" value="<?php echo $row['id']; ?>">
2631 <input type="hidden" name="cid[]" value="<?php echo $row['id']; ?>">
2632 <input type="hidden" name="option" value="com_vikbooking">
2633 <?php
2634 $tmpl = VikRequest::getVar('tmpl');
2635 if ($tmpl == 'component') {
2636 echo '<input type="hidden" name="tmpl" value="component" />';
2637 }
2638 $pgoto = VikRequest::getString('goto', '', 'request');
2639 if (in_array($pgoto, ['overv', 'ratesoverv'])) {
2640 echo '<input type="hidden" name="goto" value="' . $pgoto . '" />';
2641 }
2642 ?>
2643 </form>
2644 </div>
2645 <?php
2646 foreach ($vbo_modals_html as $modalhtml) {
2647 echo $modalhtml;
2648 }
2649 ?>
2650 <form action="index.php?option=com_vikbooking&amp;task=orders" method="post" id="vbo-gen-invoice">
2651 <input type="hidden" name="option" value="com_vikbooking" />
2652 <input type="hidden" name="task" value="orders" />
2653 <input type="hidden" name="cid[]" value="<?php echo $row['id']; ?>" />
2654 <input type="hidden" name="invnotes" id="invnotes-hid" value="" />
2655 </form>
2656
2657 <div class="vbo-modal-overlay-block vbo-modal-overlay-block-sms-email">
2658 <a class="vbo-modal-overlay-close" href="javascript: void(0);"></a>
2659 <div class="vbo-modal-overlay-content vbo-modal-overlay-content-large vbo-modal-overlay-content-sms-email">
2660
2661 <div class="vbo-modal-overlay-content-head vbo-modal-overlay-content-sms-email-head">
2662 <h3>
2663 <span></span>
2664 <span class="vbo-modal-overlay-close-times" onclick="vboToggleSendEmail();">&times;</span>
2665 </h3>
2666 </div>
2667
2668 <div class="vbo-modal-overlay-content-body vbo-modal-overlay-content-body-scroll">
2669
2670 <div id="vbo-overlay-sms-cont" style="display: none;">
2671 <h4 style="display: none;"><?php echo JText::translate('VBSENDSMSACTION'); ?>: <span id="smstophone-lbl"><?php echo $row['phone']; ?></span></h4>
2672 <form action="index.php?option=com_vikbooking" method="post" id="vbo-modal-form-sms">
2673 <div class="vbo-calendar-cfield-entry">
2674 <label for="smscont"><?php echo JText::translate('VBSENDSMSCUSTCONT'); ?></label>
2675 <span><textarea name="smscont" id="smscont" style="width: 99%; min-width: 99%;max-width: 99%; height: 120px;"></textarea></span>
2676 </div>
2677 <input type="hidden" name="phone" id="smstophone" value="<?php echo $row['phone']; ?>" />
2678 <input type="hidden" name="goto" value="<?php echo urlencode('index.php?option=com_vikbooking&task=editorder&cid[]='.$row['id']); ?>" />
2679 <input type="hidden" name="task" value="sendcustomsms" />
2680 </form>
2681 </div>
2682
2683 <div id="vbo-overlay-email-cont" style="display: none;">
2684 <h4 style="display: none;"><?php echo JText::translate('VBSENDEMAILACTION'); ?>: <span id="emailto-lbl"><?php echo $row['custmail']; ?></span></h4>
2685 <form action="index.php?option=com_vikbooking" method="post" enctype="multipart/form-data" id="vbo-modal-form-email">
2686 <input type="hidden" name="bid" value="<?php echo $row['id']; ?>" />
2687 <?php
2688 $q = "SELECT `setting` FROM `#__vikbooking_config` WHERE `param`='customemailtpls';";
2689 $dbo->setQuery($q);
2690 $cur_emtpl = $dbo->loadResult();
2691
2692 $cur_emtpl = empty($cur_emtpl) ? array() : json_decode($cur_emtpl, true);
2693 $cur_emtpl = is_array($cur_emtpl) ? $cur_emtpl : array();
2694
2695 if ($cur_emtpl) {
2696 ?>
2697 <div class="vbo-calendar-custmail-tpls-wrap">
2698 <select id="emtpl-customemail" onchange="vboLoadEmailTpl(this.value);">
2699 <option value=""><?php echo JText::translate('VBEMAILCUSTFROMTPL'); ?></option>
2700 <?php
2701 foreach ($cur_emtpl as $emk => $emv) {
2702 ?>
2703 <optgroup label="<?php echo $emv['emailsubj']; ?>">
2704 <option value="<?php echo $emk; ?>"><?php echo JText::translate('VBEMAILCUSTFROMTPLUSE'); ?></option>
2705 <option value="rm<?php echo $emk; ?>"><?php echo JText::translate('VBEMAILCUSTFROMTPLRM'); ?></option>
2706 </optgroup>
2707 <?php
2708 }
2709 ?>
2710 </select>
2711 </div>
2712 <?php
2713 }
2714
2715 /**
2716 * Load all conditional text special tags.
2717 *
2718 * @since 1.14 (J) - 1.4.0 (WP)
2719 */
2720 $extra_btns = array();
2721 $condtext_tags = VikBooking::getConditionalRulesInstance()->getSpecialTags();
2722 if (count($condtext_tags)) {
2723 $condtext_tags = array_keys($condtext_tags);
2724 foreach ($condtext_tags as $tag) {
2725 array_push($extra_btns, '<button type="button" class="btn btn-secondary btn-small vbo-condtext-specialtag-btn" onclick="setSpecialTplTag(\'emailcont\', \'' . $tag . '\');">' . $tag . '</button>');
2726 }
2727 }
2728 //
2729 ?>
2730 <div class="vbo-calendar-cfields-wrap">
2731 <div class="vbo-calendar-cfield-entry">
2732 <label for="emailsubj"><?php echo JText::translate('VBSENDEMAILCUSTSUBJ'); ?></label>
2733 <span><input type="text" name="emailsubj" id="emailsubj" value="" size="30" /></span>
2734 </div>
2735 <div class="vbo-calendar-cfield-entry">
2736 <label for="emailcont"><?php echo JText::translate('VBSENDEMAILCUSTCONT'); ?></label>
2737 <?php
2738 $special_tags_base = array(
2739 '{customer_name}',
2740 '{booking_id}',
2741 '{checkin_date}',
2742 '{checkout_date}',
2743 '{num_nights}',
2744 '{rooms_booked}',
2745 '{rooms_names}',
2746 '{tot_adults}',
2747 '{tot_children}',
2748 '{tot_guests}',
2749 '{total}',
2750 '{total_paid}',
2751 '{remaining_balance}',
2752 '{booking_link}',
2753 );
2754
2755 $special_tags_base_html = '';
2756 foreach ($special_tags_base as $sp_tag) {
2757 $special_tags_base_html .= '<button type="button" class="btn btn-secondary btn-small" onclick="setSpecialTplTag(\'emailcont\', \'' . $sp_tag . '\');">' . $sp_tag . '</button>' . "\n";
2758 }
2759
2760 /**
2761 * Use the rich text editor (visual editor) to build custom email messages.
2762 *
2763 * @since 1.15.0 (J) - 1.5.0 (WP)
2764 */
2765 $tarea_attr = array(
2766 'id' => 'emailcont',
2767 'rows' => '7',
2768 'cols' => '170',
2769 'style' => 'width: 99%; min-width: 99%; max-width: 99%; height: 120px; margin-bottom: 1px;',
2770 );
2771 $editor_opts = array(
2772 'modes' => array(
2773 'text',
2774 'visual',
2775 ),
2776 );
2777 $editor_btns = $special_tags_base;
2778 if (count($condtext_tags)) {
2779 $editor_btns = array_merge($editor_btns, $condtext_tags);
2780 }
2781 echo $vbo_app->renderVisualEditor('emailcont', '', $tarea_attr, $editor_opts, $editor_btns);
2782 ?>
2783 <div class="btn-group pull-left vbo-smstpl-bgroup vbo-custmail-bgroup vik-contentbuilder-textmode-sptags">
2784 <?php echo $special_tags_base_html . "\n" . implode("\n", $extra_btns); ?>
2785 </div>
2786 </div>
2787 <div class="vbo-calendar-cfield-entry">
2788 <label for="emailattch"><?php echo JText::translate('VBSENDEMAILCUSTATTCH'); ?></label>
2789 <span><input type="file" name="emailattch" id="emailattch" /></span>
2790 </div>
2791 <div class="vbo-calendar-cfield-entry">
2792 <label for="emailfrom"><?php echo JText::translate('VBSENDEMAILCUSTFROM'); ?></label>
2793 <span><input type="text" name="emailfrom" id="emailfrom" value="<?php echo VikBooking::getSenderMail(); ?>" size="30" /></span>
2794 </div>
2795 </div>
2796 <input type="hidden" name="email" id="emailto" value="<?php echo $row['custmail']; ?>" />
2797 <input type="hidden" name="goto" value="<?php echo urlencode('index.php?option=com_vikbooking&task=editorder&cid[]='.$row['id']); ?>" />
2798 <input type="hidden" name="task" value="sendcustomemail" />
2799 </form>
2800 </div>
2801
2802 </div>
2803
2804 <div class="vbo-modal-overlay-content-footer">
2805 <div class="vbo-modal-overlay-content-footer-right">
2806 <div id="vbo-modal-footer-sms" style="display: none;">
2807 <button type="submit" class="btn vbo-config-btn" onclick="document.getElementById('vbo-modal-form-sms').submit();"><?php VikBookingIcons::e('comment'); ?> <?php echo JText::translate('VBSENDSMSACTION'); ?></button>
2808 </div>
2809 <div id="vbo-modal-footer-email" style="display: none;">
2810 <button type="submit" class="btn vbo-config-btn" onclick="document.getElementById('vbo-modal-form-email').submit();"><?php VikBookingIcons::e('envelope'); ?> <?php echo JText::translate('VBSENDEMAILACTION'); ?></button>
2811 </div>
2812 </div>
2813 </div>
2814
2815 </div>
2816 </div>
2817
2818 <script type="text/javascript">
2819 var vbo_overlay_on = false;
2820 var vbo_print_only = false;
2821 if (jQuery.isFunction(jQuery.fn.tooltip)) {
2822 jQuery(".hasTooltip").tooltip();
2823 }
2824 function vboToggleSendSMS() {
2825 var cur_phone = jQuery("#smstophone").val();
2826 var phone_set = jQuery("#custphone").trigger('vboupdatephonenumber').val();
2827 if (phone_set.length && phone_set != cur_phone) {
2828 jQuery("#smstophone").val(phone_set);
2829 jQuery("#smstophone-lbl").text(phone_set);
2830 }
2831
2832 // toggle email/sms contents
2833 jQuery("#vbo-overlay-email-cont, #vbo-modal-footer-email").hide();
2834 jQuery("#vbo-overlay-sms-cont, #vbo-modal-footer-sms").show();
2835 var use_modal_title = jQuery("#vbo-overlay-sms-cont").find('h4').first().html();
2836 jQuery('.vbo-modal-overlay-content-sms-email-head').find('h3').find('span').first().html(use_modal_title);
2837
2838 jQuery(".vbo-modal-overlay-block-sms-email").fadeToggle(400, function() {
2839 if (jQuery(".vbo-modal-overlay-block-sms-email").is(":visible")) {
2840 vbo_overlay_on = true;
2841 } else {
2842 vbo_overlay_on = false;
2843 }
2844 });
2845 }
2846 function vboToggleSendEmail() {
2847 var cur_email = jQuery("#emailto").val();
2848 var email_set = jQuery("#custmail").val();
2849 if (email_set.length && email_set != cur_email) {
2850 jQuery("#emailto").val(email_set);
2851 jQuery("#emailto-lbl").text(email_set);
2852 }
2853
2854 // toggle email/sms contents
2855 jQuery("#vbo-overlay-sms-cont, #vbo-modal-footer-sms").hide();
2856 jQuery("#vbo-overlay-email-cont, #vbo-modal-footer-email").show();
2857 var use_modal_title = jQuery("#vbo-overlay-email-cont").find('h4').first().html();
2858 jQuery('.vbo-modal-overlay-content-sms-email-head').find('h3').find('span').first().html(use_modal_title);
2859
2860 jQuery(".vbo-modal-overlay-block-sms-email").fadeToggle(400, function() {
2861 if (jQuery(".vbo-modal-overlay-block-sms-email").is(":visible")) {
2862 vbo_overlay_on = true;
2863 } else {
2864 vbo_overlay_on = false;
2865 }
2866 });
2867 }
2868 function vboKeyupEmail(event) {
2869 if (event.key && event.key == 'Enter') {
2870 event.preventDefault();
2871 document.adminForm.submit();
2872 return;
2873 }
2874 jQuery('.vbo-bookingdet-save-email').show();
2875 }
2876 function setSpecialTplTag(taid, tpltag) {
2877 var tplobj = document.getElementById(taid);
2878 if (tplobj != null) {
2879 var start = tplobj.selectionStart;
2880 var end = tplobj.selectionEnd;
2881 tplobj.value = tplobj.value.substring(0, start) + tpltag + tplobj.value.substring(end);
2882 tplobj.selectionStart = tplobj.selectionEnd = start + tpltag.length;
2883 tplobj.focus();
2884 }
2885 }
2886 jQuery(function() {
2887 // register to the event emitted when a new payment is made through the virtual terminal widget
2888 document.addEventListener('vbo_new_payment_transaction', (e) => {
2889 if (!e || !e.detail || !e.detail.hasOwnProperty('tn') || !e.detail['tn']) {
2890 // do nothing
2891 return;
2892 }
2893 // reload the page to display the updated information
2894 location.reload();
2895 });
2896 // register to the event emitted when a booking is modified through an admin widget
2897 document.addEventListener('vbo_booking_modified', (e) => {
2898 if (!e || !e.detail || !e.detail.hasOwnProperty('bid') || !e.detail['bid']) {
2899 // do nothing
2900 return;
2901 }
2902 // reload the page to display the new information about the booking just modified
2903 location.reload();
2904 });
2905 // remove overbooking flag
2906 jQuery('.vbo-label-overbooking').on('click', function() {
2907 if (confirm(Joomla.JText._('VBO_CONF_RM_OVERBOOKING_FLAG'))) {
2908 VBOCore.doAjax(
2909 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=bookings.delete_type_flag'); ?>",
2910 {
2911 bid: '<?php echo $row['id']; ?>',
2912 flag: 'overbooking',
2913 },
2914 (success) => {
2915 // remove "overbooking" label
2916 let parent_label = jQuery('.vbo-bookdet-container').find('.vbo-label-overbooking').parent('.label');
2917 jQuery('.vbo-bookdet-container').find('.vbo-label-overbooking').remove();
2918 parent_label.text(parent_label.text().replace(' / ', ''));
2919 },
2920 (error) => {
2921 alert(error.responseText);
2922 }
2923 );
2924 }
2925 });
2926 // sessionStorage for current tab
2927 if (typeof sessionStorage !== 'undefined' && !window.location.hash && <?php echo $printreceipt ? 'false' : 'true'; ?>) {
2928 var curtab = sessionStorage.getItem('vboEditOrderTab<?php echo $row['id']; ?>');
2929
2930 setTimeout(() => {
2931 let link = jQuery('.vbo-bookingdet-noteslogs-btn[data-id="' + curtab + '"] a');
2932
2933 if (link.length) {
2934 jQuery(".vbo-bookingdet-tab[data-vbotab='vbo-tab-admin']").trigger('click');
2935 link.trigger('click');
2936 }
2937 }, 128);
2938 }
2939 if (window.location.hash == '#tab-admin') {
2940 setTimeout(function() {
2941 jQuery(".vbo-bookingdet-tab[data-vbotab='vbo-tab-admin']").trigger('click');
2942 }, 100);
2943 }
2944 // Search customer - Start
2945 var vbocustsdelay = (function() {
2946 var timer = 0;
2947 return function(callback, ms) {
2948 clearTimeout(timer);
2949 timer = setTimeout(callback, ms);
2950 };
2951 })();
2952 function vboCustomerSearch(words) {
2953 jQuery("#vbo-searchcust-res").hide().html("");
2954 jQuery("#vbo-searchcust-loading").show();
2955 var jqxhr = jQuery.ajax({
2956 type: "POST",
2957 url: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=searchcustomer'); ?>",
2958 data: {
2959 kw: words,
2960 tmpl: "component"
2961 }
2962 }).done(function(cont) {
2963 if (cont) {
2964 var obj_res = typeof cont === 'string' ? JSON.parse(cont) : cont;
2965 customers_search_vals = obj_res[0];
2966 jQuery("#vbo-searchcust-res").html(obj_res[1]);
2967 } else {
2968 customers_search_vals = "";
2969 jQuery("#vbo-searchcust-res").html("----");
2970 }
2971 jQuery("#vbo-searchcust-res").show();
2972 jQuery("#vbo-searchcust-loading").hide();
2973 }).fail(function() {
2974 jQuery("#vbo-searchcust-loading").hide();
2975 alert("Error Searching.");
2976 });
2977 }
2978 jQuery("#vbo-searchcust").keyup(function(event) {
2979 vbocustsdelay(function() {
2980 var keywords = jQuery("#vbo-searchcust").val();
2981 var chars = keywords.length;
2982 if (chars > 1) {
2983 if ((event.which > 96 && event.which < 123) || (event.which > 64 && event.which < 91) || event.which == 13) {
2984 vboCustomerSearch(keywords);
2985 }
2986 } else {
2987 if (jQuery("#vbo-searchcust-res").is(":visible")) {
2988 jQuery("#vbo-searchcust-res").hide();
2989 }
2990 }
2991 }, 600);
2992 });
2993 jQuery("body").on("click", ".vbo-custsearchres-entry", function() {
2994 var custid = jQuery(this).attr("data-custid");
2995 if (confirm('<?php echo addslashes(JText::translate('VBOASSIGNNEWCUSTCONF')); ?>')) {
2996 jQuery('#newcustid').val(custid);
2997 document.adminForm.submit();
2998 return;
2999 }
3000 });
3001 // Search customer - End
3002 jQuery(document).mouseup(function(e) {
3003 if (!vbo_overlay_on) {
3004 return false;
3005 }
3006 var vbo_overlay_cont = jQuery(".vbo-modal-overlay-content-sms-email");
3007 if (!vbo_overlay_cont.is(e.target) && vbo_overlay_cont.has(e.target).length === 0 && !jQuery(e.target).is('svg')) {
3008 jQuery(".vbo-modal-overlay-block-sms-email").fadeOut();
3009 vbo_overlay_on = false;
3010 }
3011 });
3012 jQuery(document).keyup(function(e) {
3013 if (e.keyCode == 27 && vbo_overlay_on) {
3014 jQuery(".vbo-modal-overlay-block-sms-email").fadeOut();
3015 vbo_overlay_on = false;
3016 }
3017 });
3018 jQuery(".vbo-bookingdet-tab").click(function() {
3019 var newtabrel = jQuery(this).attr('data-vbotab');
3020 var oldtabrel = jQuery(".vbo-bookingdet-tab-active").attr('data-vbotab');
3021 if (newtabrel == oldtabrel) {
3022 return;
3023 }
3024 if (newtabrel == 'vbo-tab-details' && typeof sessionStorage !== 'undefined') {
3025 sessionStorage.setItem('vboEditOrderTab<?php echo $row['id']; ?>', 'details');
3026 }
3027 jQuery(".vbo-bookingdet-tab").removeClass("vbo-bookingdet-tab-active");
3028 jQuery(this).addClass("vbo-bookingdet-tab-active");
3029 jQuery("#"+oldtabrel).hide();
3030 jQuery("#"+newtabrel).fadeIn();
3031 jQuery("#vbo_active_tab").val(newtabrel);
3032 });
3033 jQuery(".vbo-bookingdet-tab[data-vbotab='<?php echo $pactive_tab; ?>']").trigger('click');
3034 // edit amount paid
3035 jQuery('#vbo-amountpaid-edit').click(function() {
3036 jQuery('#vbo-amountpaid-cont').hide();
3037 jQuery('#vbo-amountpaid-modcont').show();
3038 jQuery('input[name="newamountpaid"]').prop('disabled', false);
3039 if (jQuery('input[name="newamountrefunded"]').length) {
3040 jQuery('input[name="newamountrefunded"]').val('');
3041 }
3042 });
3043 jQuery('#vbo-amountpaid-cancedit').click(function() {
3044 jQuery('#vbo-amountpaid-modcont').hide();
3045 jQuery('#vbo-amountpaid-cont').show();
3046 });
3047 // edit amount refunded
3048 jQuery('#vbo-amountrefunded-edit').click(function() {
3049 jQuery('#vbo-amountrefunded-cont').hide();
3050 jQuery('#vbo-amountrefunded-modcont').show();
3051 jQuery('input[name="newamountrefunded"]').prop('disabled', false);
3052 if (jQuery('input[name="newamountpaid"]').length) {
3053 jQuery('input[name="newamountpaid"]').val('');
3054 }
3055 });
3056 jQuery('#vbo-amountrefunded-cancedit').click(function() {
3057 jQuery('#vbo-amountrefunded-modcont').hide();
3058 jQuery('#vbo-amountrefunded-cont').show();
3059 });
3060 // edit amount payable
3061 jQuery('#vbo-amountpayable-edit').click(function() {
3062 jQuery('#vbo-amountpayable-cont').hide();
3063 jQuery('#vbo-amountpayable-modcont').show();
3064 jQuery('input[name="newamountpayable"]').prop('disabled', false);
3065 });
3066 jQuery('#vbo-amountpayable-cancedit').click(function() {
3067 jQuery('#vbo-amountpayable-modcont').hide();
3068 jQuery('#vbo-amountpayable-cont').show();
3069 });
3070 // edit cancellation fee
3071 jQuery('#vbo-cancfee-edit').click(function() {
3072 jQuery('#vbo-cancfee-cont').hide();
3073 jQuery('#vbo-cancfee-modcont').show();
3074 jQuery('input[name="newcancfee"]').prop('disabled', false);
3075 });
3076 jQuery('#vbo-cancfee-cancedit').click(function() {
3077 jQuery('#vbo-cancfee-modcont').hide();
3078 jQuery('#vbo-cancfee-cont').show();
3079 });
3080 // chat listener
3081 if (typeof VCMChat !== 'undefined') {
3082 jQuery(window).on('chatsync', function(e) {
3083 if (!jQuery("#vcm-chat-audio-notification").length) {
3084 jQuery("body").append("<audio id=\"vcm-audio-notification\" preload=\"auto\"><source type=\"audio/mp3\" src=\"<?php echo VCM_ADMIN_URI; ?>assets/css/audio/new_chat_message.mp3\"></source></audio>");
3085 }
3086 try {
3087 var promise = document.getElementById('vcm-audio-notification').play();
3088 console.log(promise);
3089 } catch (err) {
3090 console.warn('Could not play sound', err);
3091 }
3092 });
3093 }
3094
3095 // zoom-able avatars
3096 jQuery('.vbo-customer-info-box-avatar').each(function() {
3097 var img = jQuery(this).find('img');
3098 if (!img.length) {
3099 return;
3100 }
3101 // register click listener
3102 img.on('click', function(e) {
3103 // stop events propagation
3104 e.preventDefault();
3105 e.stopPropagation();
3106
3107 // check for caption
3108 var caption = jQuery(this).attr('data-caption');
3109
3110 // build modal content
3111 var zoom_modal = jQuery('<div></div>').addClass('vbo-modal-overlay-block vbo-modal-overlay-zoom-image').css('display', 'block');
3112 var zoom_dismiss = jQuery('<a></a>').addClass('vbo-modal-overlay-close');
3113 zoom_dismiss.on('click', function() {
3114 jQuery('.vbo-modal-overlay-zoom-image').fadeOut();
3115 });
3116 zoom_modal.append(zoom_dismiss);
3117 var zoom_content = jQuery('<div></div>').addClass('vbo-modal-overlay-content vbo-modal-overlay-content-zoom-image');
3118 var zoom_head = jQuery('<div></div>').addClass('vbo-modal-overlay-content-head');
3119 var zoom_head_title = jQuery('<span></span>');
3120 if (caption) {
3121 zoom_head_title.text(caption);
3122 }
3123 var zoom_head_close = jQuery('<span></span>').addClass('vbo-modal-overlay-close-times').html('&times;');
3124 zoom_head_close.on('click', function() {
3125 jQuery('.vbo-modal-overlay-zoom-image').fadeOut();
3126 });
3127 zoom_head.append(zoom_head_title).append(zoom_head_close);
3128 var zoom_body = jQuery('<div></div>').addClass('vbo-modal-overlay-content-body vbo-modal-overlay-content-body-scroll');
3129 var zoom_image = jQuery('<div></div>').addClass('vbo-modal-zoom-image-wrap');
3130 zoom_image.append(jQuery(this).clone());
3131 zoom_body.append(zoom_image);
3132 zoom_content.append(zoom_head).append(zoom_body);
3133 zoom_modal.append(zoom_content);
3134 // append modal to body
3135 if (jQuery('.vbo-modal-overlay-zoom-image').length) {
3136 jQuery('.vbo-modal-overlay-zoom-image').remove();
3137 }
3138 jQuery('body').append(zoom_modal);
3139 });
3140 });
3141
3142 // emit the event to read all notifications in the current context
3143 VBOCore.emitEvent('vbo-nc-read-notifications', {
3144 criteria: {
3145 group: '<?php echo !empty($row['idorderota']) && !empty($row['channel']) ? 'otas' : 'website'; ?>',
3146 idorder: '<?php echo $row['id']; ?>',
3147 }
3148 });
3149
3150 });
3151 var cur_emtpl = <?php echo json_encode($cur_emtpl); ?>;
3152 function vboLoadEmailTpl(tplind) {
3153 if (!(tplind.length > 0)) {
3154 jQuery('#emailsubj').val('');
3155 jQuery('#emailcont').val('').trigger('change');
3156 return true;
3157 }
3158 if (tplind.substr(0, 2) == 'rm') {
3159 if (confirm(Joomla.JText._('VBDELCONFIRM'))) {
3160 document.location.href = 'index.php?option=com_vikbooking&task=rmcustomemailtpl&cid[]=<?php echo $row['id']; ?>&tplind='+tplind.substr(2);
3161 }
3162 return false;
3163 }
3164 if (!cur_emtpl.hasOwnProperty(tplind)) {
3165 jQuery('#emailsubj').val('');
3166 jQuery('#emailcont').val('').trigger('change');
3167 return true;
3168 }
3169 jQuery('#emailsubj').val(cur_emtpl[tplind]['emailsubj']);
3170 jQuery('#emailcont').val(cur_emtpl[tplind]['emailcont']).trigger('change');
3171 jQuery('#emailfrom').val(cur_emtpl[tplind]['emailfrom']);
3172 return true;
3173 }
3174 <?php
3175 $pcustomemail = VikRequest::getInt('customemail', '', 'request');
3176 if ($pcustomemail > 0) {
3177 ?>
3178 vboToggleSendEmail();
3179 <?php
3180 }
3181 if ($printreceipt) {
3182 ?>
3183 jQuery(function() {
3184 jQuery('button, .vbo-bookingdet-innertop').hide();
3185 jQuery('body').find('a').each(function(k, v) {
3186 jQuery(this).replaceWith(jQuery(this).html());
3187 });
3188 jQuery('body').find("input[type='text']").each(function(k, v) {
3189 jQuery(this).replaceWith(jQuery(this).val());
3190 });
3191 });
3192 function vboMakePrintOnly() {
3193 vbo_print_only = true;
3194 jQuery(".vbo-receipt-numdate-block").remove();
3195 jQuery("#vbo-receipt-print-btn-name").text("<?php echo addslashes(JText::translate('VBOPRINT')); ?>");
3196 }
3197 function vboLaunchPrintReceipt() {
3198 var rcnotes = jQuery('#vbo-receipt-notes').val();
3199 var rnewnum = jQuery('#vbo-receipt-num-inp').val();
3200 if (rcnotes.length) {
3201 if (rcnotes.indexOf('<') < 0) {
3202 rcnotes = rcnotes.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1<br />$2');
3203 }
3204 jQuery('#vbo-receipt-notes-val').html(rcnotes);
3205 } else {
3206 jQuery('.vbo-receipt-notes-container').remove();
3207 }
3208 if (vbo_print_only === true) {
3209 window.print();
3210 return;
3211 }
3212 jQuery.ajax({
3213 type: "POST",
3214 url: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=updatereceiptnum'); ?>",
3215 data: {
3216 newnum: rnewnum,
3217 newnotes: rcnotes,
3218 oid: "<?php echo $row['id']; ?>"
3219 }
3220 }).done(function(res) {
3221 window.print();
3222 }).fail(function() {
3223 alert('Could not update the next receipt number.')
3224 window.print();
3225 });
3226 }
3227 <?php
3228 }
3229 ?>
3230 </script>
3231