PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.8.16
VikBooking Hotel Booking Engine & PMS v1.8.16
1.8.16 1.8.15 1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 All 37 releases
← All changes | admin/views/editorder/tmpl/default.php +4615 -0 1.6.2 → 1.8.16 View file →
@@ -1,0 +1,4615 @@
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 +// load registry and history
20 +$registry = VBOBookingRegistry::getInstance($this->row, $this->rooms);
21 +$history_obj = VikBooking::getBookingHistoryInstance($row['id']);
22 +
23 +// availability helper
24 +$av_helper = VikBooking::getAvailabilityInstance();
25 +
26 +// load datepicker for all CMS compatibility
27 +JHtml::fetch('stylesheet', VBO_SITE_URI.'resources/jquery-ui.min.css');
28 +JHtml::fetch('jquery.framework', true, true);
29 +JHtml::fetch('script', VBO_SITE_URI.'resources/jquery-ui.min.js');
30 +
31 +// js lang def
32 +JText::script('VBO_CONV_RES_OTA_CURRENCY_APPLY');
33 +JText::script('VBDELCONFIRM');
34 +JText::script('VBSENDCANCORDEMAIL');
35 +JText::script('VBO_SET_STANDBY');
36 +JText::script('VBO_CONF_RM_OVERBOOKING_FLAG');
37 +JText::script('VBO_NEW_PAYSCHEDULE');
38 +JText::script('VBANNULLA');
39 +JText::script('VBOCLOSE');
40 +JText::script('VBSAVE');
41 +JText::script('VBELIMINA');
42 +JText::script('VBO_REG_NEW_PAYMENT');
43 +JText::script('VBO_UPDATE_PAYMENT');
44 +JText::script('VBSENDSMSACTION');
45 +JText::script('VBSENDEMAILACTION');
46 +JText::script('VBO_AI_AUTO_GUEST_REV_EXCLUDE');
47 +JText::script('VBO_AI_AUTO_GUEST_REV_INCLUDE');
48 +
49 +$dbo = JFactory::getDbo();
50 +
51 +$vbo_app = VikBooking::getVboApplication();
52 +$vbo_app->loadVisualEditorAssets();
53 +$vbo_app->prepareJavaScriptCurrency();
54 +
55 +// preload chat assets
56 +VBOFactory::getChatMediator()->useAssets();
57 +
58 +/**
59 + * This View can render within a modal the "bookingcheckin" View, and with WP
60 + * this is loaded via AJAX. In order to not interfere or reset the contextual menu,
61 + * we load the assets from the parent View. Context menu may also be used in this View.
62 + *
63 + * @since 1.16.0 (J) - 1.6.0 (WP)
64 + */
65 +$vbo_app->loadContextMenuAssets();
66 +if (VBOPlatformDetection::isWordPress()) {
67 + JText::script('VBRENTALORD');
68 + JText::script('VBPVIEWORDERSPEOPLE');
69 +}
70 +
71 +$canDo = JFactory::getUser();
72 +$vbo_auth_bookings = $canDo->authorise('core.vbo.bookings', 'com_vikbooking');
73 +
74 +// check if automatic payment collection is enabled for all bookings
75 +$automatic_payment_collection = VBOFactory::getConfig()->getBool('auto_payment_collection', false);
76 +
77 +$booking_has_damage_dep = 0;
78 +$current_ts = time();
79 +$ota_type_data = !empty($row['ota_type_data']) ? ((array) json_decode($row['ota_type_data'], true)) : [];
80 +$currencyname = VikBooking::getCurrencyName();
81 +$currencysymb = VikBooking::getCurrencySymb();
82 +$after_tax = VikBooking::ivaInclusa();
83 +$nowdf = VikBooking::getDateFormat(true);
84 +if ($nowdf == "%d/%m/%Y") {
85 + $df = 'd/m/Y';
86 +} elseif ($nowdf == "%m/%d/%Y") {
87 + $df = 'm/d/Y';
88 +} else {
89 + $df = 'Y/m/d';
90 +}
91 +$datesep = VikBooking::getDateSeparator(true);
92 +$vbo_modals_html = array();
93 +$payment = VikBooking::getPayment($row['idpayment']);
94 +$pactive_tab = VikRequest::getString('vbo_active_tab', 'vbo-tab-details', 'request');
95 +$printreceipt = VikRequest::getInt('print', 0, 'request');
96 +$printreceipt = ($printreceipt > 0);
97 +if ($printreceipt) {
98 + //we set a different page title when printing the receipt for the "PDF Printer" to give the file a good name.
99 + JFactory::getDocument()->setTitle(VikBooking::getFrontTitle()." - ".JText::translate('VBOFISCRECEIPT')." #".$row['id']);
100 +}
101 +$gotouri = 'index.php?option=com_vikbooking&task=editorder&cid[]='.$row['id'];
102 +
103 +if ($row['status'] == "confirmed") {
104 + $use_js_bid = $row['id'];
105 + JFactory::getDocument()->addScriptDeclaration(
106 +<<<JS
107 +window["vbo_current_bid"] = $use_js_bid;
108 +JS
109 + );
110 +}
111 +
112 +$tars = array();
113 +$arrpeople = array();
114 +$is_package = !empty($row['pkg']) ? true : false;
115 +$is_cust_cost = false;
116 +foreach ($rooms as $ind => $or) {
117 + $num = $ind + 1;
118 + $arrpeople[$num]['adults'] = $or['adults'];
119 + $arrpeople[$num]['children'] = $or['children'];
120 + $arrpeople[$num]['children_age'] = $or['childrenage'];
121 + $arrpeople[$num]['t_first_name'] = $or['t_first_name'];
122 + $arrpeople[$num]['t_last_name'] = $or['t_last_name'];
123 + $arrpeople[$num]['pets'] = $or['pets'];
124 + if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
125 + //package or custom cost set from the back-end
126 + $is_cust_cost = true;
127 + continue;
128 + }
129 + $q = "SELECT * FROM `#__vikbooking_dispcost` WHERE `id`=".(int)$or['idtar'].";";
130 + $dbo->setQuery($q);
131 + $tar = $dbo->loadAssocList();
132 + $tar = VikBooking::applySeasonsRoom($tar, $row['checkin'], $row['checkout']);
133 +
134 + // apply OBP rules
135 + $tar = VBORoomHelper::getInstance()->applyOBPRules($tar, $or, $or['adults']);
136 +
137 + $tars[$num] = $tar;
138 +}
139 +$pcheckin = $row['checkin'];
140 +$pcheckout = $row['checkout'];
141 +$secdiff = $pcheckout - $pcheckin;
142 +$daysdiff = $secdiff / 86400;
143 +if (is_int($daysdiff)) {
144 + if ($daysdiff < 1) {
145 + $daysdiff = 1;
146 + }
147 +} else {
148 + if ($daysdiff < 1) {
149 + $daysdiff = 1;
150 + } else {
151 + $sum = floor($daysdiff) * 86400;
152 + $newdiff = $secdiff - $sum;
153 + $maxhmore = VikBooking::getHoursMoreRb() * 3600;
154 + if ($maxhmore >= $newdiff) {
155 + $daysdiff = floor($daysdiff);
156 + } else {
157 + $daysdiff = ceil($daysdiff);
158 + }
159 + }
160 +}
161 +
162 +$otachannel = '';
163 +$otachannel_name = '';
164 +$otachannel_bid = '';
165 +$otacurrency = '';
166 +if (!empty($row['channel'])) {
167 + $channelparts = explode('_', $row['channel']);
168 + $otachannel = array_key_exists(1, $channelparts) && strlen($channelparts[1]) > 0 ? $channelparts[1] : ucwords($channelparts[0]);
169 + $otachannel_name = $otachannel;
170 + $otachannel_bid = $otachannel.(!empty($row['idorderota']) ? ' - Booking ID: '.$row['idorderota'] : '');
171 + if (strstr($otachannel, '.') !== false) {
172 + $otaccparts = explode('.', $otachannel);
173 + $otachannel = $otaccparts[0];
174 + }
175 + $otacurrency = strlen((string) $row['chcurrency']) > 0 ? $row['chcurrency'] : '';
176 +}
177 +
178 +/**
179 + * Tell whether the current reservation has or may have a CC/VCC available.
180 + */
181 +$may_have_cc_details = false;
182 +if (!empty($row['paymentlog']) && stripos($row['paymentlog'], 'card number') !== false && strpos($row['paymentlog'], '****') !== false) {
183 + // turn flag on for partial card details available
184 + $may_have_cc_details = true;
185 +} elseif (!empty($row['channel']) && !strcasecmp($otachannel_name, 'Booking.com')) {
186 + // the CM may be able to retrieve the CC details via API
187 + $may_have_cc_details = true;
188 +}
189 +
190 +$status_type = '';
191 +if (!empty($row['type'])) {
192 + $status_type = JText::translate('VBO_BTYPE_' . strtoupper($row['type']));
193 + if (!strcasecmp($row['type'], 'overbooking')) {
194 + $status_type = '<span class="label label-error vbo-label-nested vbo-label-overbooking">' . $status_type . '</span>';
195 + }
196 + $status_type .= ' / ';
197 +}
198 +$extra_status = $row['refund'] > 0 ? ' / ' . JText::translate('VBO_STATUS_REFUNDED') : '';
199 +if ($row['status'] == "confirmed") {
200 + $saystaus = '<span class="label label-success">' . $status_type . JText::translate('VBCONFIRMED') . $extra_status . '</span>';
201 +} elseif ($row['status'] == "standby") {
202 + $saystaus = '<span class="label label-warning">' . $status_type . JText::translate('VBSTANDBY') . $extra_status . '</span>';
203 +} else {
204 + $saystaus = '<span class="label label-error">' . $status_type . JText::translate('VBCANCELLED') . $extra_status . '</span>';
205 +}
206 +
207 +// extend booking details main panel
208 +$bookingPanelForms = $this->onDisplayView();
209 +
210 +// extend booking details sidebar
211 +$bookingSidebarForms = $this->onDisplayView('Sidebar');
212 +
213 +// extend administration main panel
214 +$adminFormsSetup = new stdClass;
215 +$adminFormsSetup->icons = [];
216 +$adminPanelForms = $this->onDisplayView('Administration', $adminFormsSetup);
217 +
218 +// extend administration sidebar
219 +$adminSidebarForms = $this->onDisplayView('AdministrationSidebar');
220 +
221 +/**
222 + * Check if messaging accounts have been configured through the E4jConnect Channel Manager.
223 + * If some messaging API accounts have been configured, SMS fallback will no longer be displayed.
224 + *
225 + * @since 1.18.8 (J) - 1.8.8 (WP)
226 + */
227 +$messagingAccountConfigurations = [];
228 +if (class_exists('VCMMessagingAccountsModel')) {
229 + $messagingAccountConfigurations = VCMMessagingAccountsModel::getInstance()->getConfigurationsData(
230 + new VCMMessagingTemplateDecoratorBooking($registry),
231 + [
232 + 'listings' => $registry->getBookedListingIds(),
233 + ]
234 + );
235 +}
236 +
237 +//Prepare modal (used for the Registration and for reconstructing the credit card details through the channel manager)
238 +echo $vbo_app->getJmodalScript();
239 +//end Prepare modal
240 +?>
241 +<script type="text/javascript">
242 +function changePayment() {
243 + var newpayment = document.getElementById('newpayment').value;
244 + if (newpayment != '') {
245 + var paymentname = document.getElementById('newpayment').options[document.getElementById('newpayment').selectedIndex].text;
246 + if (confirm('<?php echo addslashes(JText::translate('VBCHANGEPAYCONFIRM')); ?>' + paymentname + '?')) {
247 + document.adminForm.submit();
248 + } else {
249 + document.getElementById('newpayment').selectedIndex = 0;
250 + }
251 + }
252 +}
253 +function vbToggleLog(elem) {
254 + vbToggleDynamicPanel(elem, '#vbpaymentlogdiv');
255 +}
256 +function vbToggleNotes(elem) {
257 + vbToggleDynamicPanel(elem, '#vbadminnotesdiv');
258 +}
259 +function vbToggleHistory(elem) {
260 + vbToggleDynamicPanel(elem, '#vbhistorydiv');
261 +}
262 +function vbToggleInvNotes(elem) {
263 + vbToggleDynamicPanel(elem, '#vbinvnotesdiv');
264 +}
265 +function vbToggleMessaging(elem) {
266 + vbToggleDynamicPanel(elem, '#vbmessagingdiv');
267 + if (typeof VCMChat !== 'undefined') {
268 + VCMChat.getInstance().scrollToBottom();
269 + }
270 +}
271 +function vbToggleDynamicPanel(elem, target) {
272 + if (jQuery(target).is(':visible')) {
273 + return;
274 + }
275 +
276 + jQuery(".vbo-bookingdet-noteslogs-btn-active").removeClass("vbo-bookingdet-noteslogs-btn-active");
277 +
278 + jQuery('.vbo-extra-panel').hide();
279 + jQuery(target).show();
280 +
281 + jQuery(elem).parent(".vbo-bookingdet-noteslogs-btn").addClass("vbo-bookingdet-noteslogs-btn-active");
282 +
283 + if (typeof sessionStorage !== 'undefined') {
284 + sessionStorage.setItem('vboEditOrderTab<?php echo $row['id']; ?>', jQuery(elem).parent().data('id'));
285 + }
286 +}
287 +function toggleDiscount(elem) {
288 + var discsp = document.getElementById('vbdiscenter').style.display;
289 + if (discsp == 'block') {
290 + document.getElementById('vbdiscenter').style.display = 'none';
291 + jQuery(elem).find('i').attr('class', '<?php echo VikBookingIcons::i('chevron-down'); ?>');
292 + } else {
293 + document.getElementById('vbdiscenter').style.display = 'block';
294 + jQuery(elem).find('i').attr('class', '<?php echo VikBookingIcons::i('chevron-up'); ?>');
295 + }
296 +}
297 +</script>
298 +
299 +<div class="vbo-bookingdet-topcontainer">
300 + <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">
301 + <?php
302 + if ($printreceipt) {
303 + //print the company details
304 + $companylogo = VikBooking::getSiteLogo();
305 + $next_receipt = VikBooking::getNextReceiptNumber($row['id']);
306 + ?>
307 + <div class="vbo-receipt-company-block-outer">
308 + <div class="vbo-receipt-company-block">
309 + <?php
310 + if (!empty($companylogo)) {
311 + ?>
312 + <div class="vbo-receipt-company-logo"><img src="<?php echo VBO_ADMIN_URI.'resources/'.$companylogo; ?>" /></div>
313 + <?php
314 + }
315 + ?>
316 + <div class="vbo-receipt-company-info"><?php echo VikBooking::getInvoiceCompanyInfo(); ?></div>
317 + </div>
318 + <div class="vbo-receipt-numdate-block">
319 + <div class="vbo-receipt-numdate-inner">
320 + <div class="vbo-receipt-numdate-title">
321 + <span><?php echo JText::translate('VBOFISCRECEIPT'); ?></span>
322 + <span style="float: right; cursor: pointer; color: #ff0000;" onclick="vboMakePrintOnly();"><?php VikBookingIcons::e('times-circle'); ?></span>
323 + </div>
324 + <div class="vbo-receipt-numdate-num">
325 + <span class="vbo-receipt-numdate-num-lbl"><?php echo JText::translate('VBOFISCRECEIPTNUM'); ?></span>
326 + <span class="vbo-receipt-numdate-num-val">
327 + <span class="vbo-showin-print" id="vbo-receipt-num"><?php echo $next_receipt; ?></span>
328 + <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;" />
329 + </span>
330 + </div>
331 + <div class="vbo-receipt-numdate-date">
332 + <span class="vbo-receipt-numdate-date-lbl"><?php echo JText::translate('VBOFISCRECEIPTDATE'); ?></span>
333 + <span class="vbo-receipt-numdate-date-val"><?php echo date(str_replace("/", $datesep, $df)); ?></span>
334 + </div>
335 + </div>
336 + </div>
337 + <div class="vbo-receipt-print-confirm vbo-hidein-print">
338 + <div class="vbo-receipt-print-btn">
339 + <span onclick="vboLaunchPrintReceipt();">
340 + <?php VikBookingIcons::e('print'); ?>
341 + <span id="vbo-receipt-print-btn-name"><?php echo JText::translate('VBOPRINTRECEIPT'); ?></span>
342 + </span>
343 + </div>
344 + </div>
345 + </div>
346 + <?php
347 + }
348 + ?>
349 +
350 + <div class="vbo-bookdet-container">
351 + <div class="vbo-bookdet-wrap">
352 + <div class="vbo-bookdet-head">
353 + <span>ID</span>
354 + </div>
355 + <div class="vbo-bookdet-foot">
356 + <span><?php echo $row['id']; ?></span>
357 + </div>
358 + </div>
359 + <div class="vbo-bookdet-wrap">
360 + <div class="vbo-bookdet-head">
361 + <span><?php echo JText::translate('VBEDITORDERONE'); ?></span>
362 + </div>
363 + <div class="vbo-bookdet-foot">
364 + <span><?php echo date(str_replace("/", $datesep, $df).' H:i', $row['ts']); ?></span>
365 + </div>
366 + </div>
367 + <?php
368 + if (!$printreceipt && $customer) {
369 + ?>
370 + <div class="vbo-bookdet-wrap">
371 + <div class="vbo-bookdet-head">
372 + <span><?php echo JText::translate('VBCUSTOMERNOMINATIVE'); ?></span>
373 + </div>
374 + <div class="vbo-bookdet-foot">
375 + <div class="vbo-customer-info-box">
376 + <div class="vbo-customer-info-box-name">
377 + <?php echo (isset($customer['country_img']) ? $customer['country_img'] . ' ' : ''); ?>
378 +
379 + <?php if ($canDo->authorise('core.edit', 'com_vikbooking') && $canDo->authorise('core.vbo.management', 'com_vikbooking')): ?>
380 + <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>
381 + <?php else: ?>
382 + <?php echo ltrim($customer['first_name'] . ' ' . $customer['last_name']); ?>
383 + <?php endif; ?>
384 + </div>
385 + <?php
386 + if (!empty($customer['pic'])) {
387 + $avatar_caption = ltrim($customer['first_name'] . ' ' . $customer['last_name']);
388 + ?>
389 + <div class="vbo-customer-info-box-avatar vbo-customer-avatar-small">
390 + <span>
391 + <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); ?>" />
392 + </span>
393 + </div>
394 + <?php
395 + }
396 + ?>
397 + </div>
398 + </div>
399 + </div>
400 + <?php
401 + }
402 + if (!$printreceipt) {
403 + ?>
404 + <div class="vbo-bookdet-wrap">
405 + <div class="vbo-bookdet-head">
406 + <span><?php echo JText::translate('VBEDITORDERROOMSNUM'); ?></span>
407 + </div>
408 + <div class="vbo-bookdet-foot">
409 + <?php echo $row['roomsnum']; ?>
410 + </div>
411 + </div>
412 + <?php
413 + }
414 + ?>
415 + <div class="vbo-bookdet-wrap">
416 + <div class="vbo-bookdet-head">
417 + <span><?php echo JText::translate('VBEDITORDERFOUR'); ?></span>
418 + </div>
419 + <div class="vbo-bookdet-foot">
420 + <span><?php echo $row['days']; ?></span>
421 + <?php
422 + if ($row['split_stay']) {
423 + ?>
424 + <span class="hasTooltip" title="<?php echo JHtml::fetch('esc_attr', JText::translate('VBO_SPLIT_STAY')); ?>"><?php VikBookingIcons::e('random'); ?></span>
425 + <?php
426 + }
427 + ?>
428 + </div>
429 + </div>
430 + <div class="vbo-bookdet-wrap">
431 + <div class="vbo-bookdet-head">
432 + <span><?php echo JText::translate('VBEDITORDERFIVE'); ?></span>
433 + </div>
434 + <div class="vbo-bookdet-foot">
435 + <?php
436 + $checkin_info = getdate($row['checkin']);
437 + $short_wday = JText::translate('VB'.strtoupper(substr($checkin_info['weekday'], 0, 3)));
438 + ?>
439 + <?php echo $short_wday.', '.date(str_replace("/", $datesep, $df).' H:i', $row['checkin']); ?>
440 + </div>
441 + </div>
442 + <div class="vbo-bookdet-wrap">
443 + <div class="vbo-bookdet-head">
444 + <span><?php echo JText::translate('VBEDITORDERSIX'); ?></span>
445 + </div>
446 + <div class="vbo-bookdet-foot">
447 + <?php
448 + $checkout_info = getdate($row['checkout']);
449 + $short_wday = JText::translate('VB'.strtoupper(substr($checkout_info['weekday'], 0, 3)));
450 + ?>
451 + <?php echo $short_wday.', '.date(str_replace("/", $datesep, $df).' H:i', $row['checkout']); ?>
452 + </div>
453 + </div>
454 + <?php
455 + if (!$printreceipt && $vbo_auth_bookings && $row['closure'] != 1 && $row['status'] == 'confirmed') {
456 + // we don't need to check in the IF above "&& $row['checked'] != 0" because the registration is useful for all bookings.
457 + $checked_btn = 'btn-primary';
458 + switch ($row['checked']) {
459 + case -1:
460 + $checked_status = JText::translate('VBOCHECKEDSTATUSNOS');
461 + $checked_btn = 'btn-danger';
462 + break;
463 + case 1:
464 + $checked_status = JText::translate('VBOCHECKEDSTATUSIN');
465 + $checked_btn = 'btn-success';
466 + break;
467 + case 2:
468 + $checked_status = JText::translate('VBOCHECKEDSTATUSOUT');
469 + $checked_btn = 'btn-warning';
470 + break;
471 + default:
472 + $checked_status = JText::translate('VBOCHECKEDSTATUSZERO');
473 + if ($customer && isset($customer['pax_data']) && !empty($customer['pax_data'])) {
474 + // pre check-in performed via front-end
475 + $checked_status = JText::translate('VBOCHECKEDSTATUSPRECHECKIN');
476 + }
477 + break;
478 + }
479 + ?>
480 + <div class="vbo-bookdet-wrap pro-feature">
481 + <div class="vbo-bookdet-head">
482 + <span><?php echo JText::translate('VBOCHECKEDSTATUS'); ?></span>
483 + </div>
484 + <div class="vbo-bookdet-foot">
485 + <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');">
486 + <?php echo $checked_status; ?>
487 + </button>
488 + </div>
489 + </div>
490 + <?php
491 + //Prepare modal (Registration)
492 + array_push($vbo_modals_html, $vbo_app->getJmodalHtml('vbo-checkin-booking', JText::translate('VBOMANAGECHECKSINOUT')));
493 + //end Prepare modal
494 + }
495 +
496 + /**
497 + * Check whether the booking can be refunded or charged through an off-session capturing.
498 + *
499 + * @since 1.14 (J) - 1.4.0 (WP)
500 + * @since 1.18.0 (J) - 1.8.0 (WP) added support to off-session capturing.
501 + */
502 +
503 + // refundable/capturable up to 7 days after check-out day
504 + $max_refund_ts = mktime(23, 59, 59, $checkout_info['mon'], ($checkout_info['mday'] + 7), $checkout_info['year']);
505 +
506 + // current payment driver must be set
507 + $tn_driver = is_array($payment) ? $payment['file'] : null;
508 +
509 + // transaction data validation callback
510 + $tn_data_callback = function($data) use ($tn_driver) {
511 + return (is_object($data) && isset($data->driver) && basename($data->driver, '.php') == basename($tn_driver, '.php'));
512 + };
513 + $prev_tn_data = $history_obj->getEventsWithData(array('P0', 'PN'), $tn_data_callback);
514 +
515 + // whether it's refundable/capturable
516 + $refundable = ($row['status'] != 'standby' && !empty($row['totpaid']) && $max_refund_ts >= $current_ts && is_array($prev_tn_data) && $prev_tn_data);
517 + $off_session_capturing = ($row['status'] != 'standby' && $max_refund_ts >= $current_ts && is_array($prev_tn_data) && array_filter($prev_tn_data, function($data) {
518 + return is_object($data) && ($data->future_usage ?? null);
519 + }));
520 +
521 + if ($off_session_capturing) {
522 + ?>
523 + <div class="vbo-bookdet-wrap">
524 + <div class="vbo-bookdet-head">
525 + <span><?php echo JText::translate('VBO_CREDIT_CARD'); ?></span>
526 + </div>
527 + <div class="vbo-bookdet-foot">
528 + <button type="button" class="btn btn-small vbo-config-btn vbo-offsessioncapture-btn" onclick="VBOCore.handleDisplayWidgetNotification({widget_id: 'virtual_terminal'}, {bid: <?php echo $row['id']; ?>});">
529 + <?php VikBookingIcons::e('credit-card'); ?>
530 + <?php echo JText::translate('VBO_W_VIRTUALTERMINAL_TITLE'); ?>
531 + </button>
532 + </div>
533 + </div>
534 + <?php
535 + }
536 +
537 + if ($refundable) {
538 + // prepare modal (refundtn) with a custom function to trigger the opening
539 + array_push($vbo_modals_html, $vbo_app->getJmodalHtml('vbo-refund-tn', JText::translate('VBO_ISSUE_REFUND')));
540 + echo $vbo_app->getJmodalScript('Refund', 'vboDetectRefundChanges();');
541 + // count the number of refunds made
542 + $refunds = $history_obj->getEventsWithData('RF', null, false);
543 + $refunds = !is_array($refunds) ? array() : $refunds;
544 + ?>
545 + <script type="text/javascript">
546 + var vbo_refund_performed = false;
547 + function vboDetectRefundChanges() {
548 + if (vbo_refund_performed === true) {
549 + location.reload();
550 + }
551 + }
552 + </script>
553 +
554 + <div class="vbo-bookdet-wrap">
555 + <div class="vbo-bookdet-head">
556 + <span><?php echo JText::translate('VBO_ISSUE_REFUND'); ?></span>
557 + </div>
558 + <div class="vbo-bookdet-foot">
559 + <button type="button" class="btn btn-small btn-danger vbo-dorefund-btn"<?php echo $refunds ? ' data-totrefunds="' . count($refunds) . '"' : ''; ?> onclick="vboOpenJModalRefund('vbo-refund-tn', 'index.php?option=com_vikbooking&task=refundtn&cid[]=<?php echo $row['id']; ?>&tmpl=component');">
560 + <?php echo JText::translate('VBO_REFUND'); ?>
561 + </button>
562 + </div>
563 + </div>
564 + <?php
565 + }
566 +
567 + if (!$printreceipt && !empty($row['channel'])) {
568 + $ota_logo_img = VikBooking::getVcmChannelsLogo($row['channel']);
569 + if ($ota_logo_img === false) {
570 + $ota_logo_img = $otachannel_name;
571 + } else {
572 + $ota_logo_img = '<img src="'.$ota_logo_img.'" class="vbo-channelimg-medium"/>';
573 + }
574 + ?>
575 + <div class="vbo-bookdet-wrap">
576 + <div class="vbo-bookdet-head">
577 + <span><?php echo JText::translate('VBPVIEWORDERCHANNEL'); ?></span>
578 + </div>
579 + <div class="vbo-bookdet-foot">
580 + <span><?php echo $ota_logo_img; ?></span>
581 + </div>
582 + </div>
583 + <?php
584 + } elseif (!$printreceipt && class_exists('VCMOtaBooking')) {
585 + /**
586 + * Vik Channel Manager booking assignable channels.
587 + *
588 + * @since 1.16.3 (J) - 1.6.3 (WP)
589 + */
590 + $assignable_channels = VCMOtaBooking::getInstance($row, true)->getChannelsAssignable();
591 + if ($assignable_channels) {
592 + JText::script('VBO_ASSIGN_BOOKING_TO_OTA_CONFIRM');
593 + JFactory::getDocument()->addScriptDeclaration(
594 +<<<JS
595 +function vboConfirmAssignChannel(ch_key, ch_name) {
596 + if (!ch_key || !ch_name) {
597 + return true;
598 + }
599 + if (confirm(Joomla.JText._('VBO_ASSIGN_BOOKING_TO_OTA_CONFIRM').replace('%s', ch_name))) {
600 + document.adminForm.submit();
601 + return true;
602 + } else {
603 + return false;
604 + }
605 +}
606 +JS
607 + );
608 + ?>
609 + <div class="vbo-bookdet-wrap">
610 + <div class="vbo-bookdet-head">
611 + <span><?php echo JText::translate('VBPVIEWORDERCHANNEL'); ?></span>
612 + </div>
613 + <div class="vbo-bookdet-foot">
614 + <select name="vcm_assign_channel" class="vbo-select-small" onchange="return vboConfirmAssignChannel(this.value, this.options[this.selectedIndex].text);">
615 + <option value=""><?php echo JText::translate('VBORDFROMSITE'); ?></option>
616 + <?php
617 + foreach ($assignable_channels as $assign_ch_key => $assign_ch_name) {
618 + ?>
619 + <option value="<?php echo JHtml::fetch('esc_attr', $assign_ch_key); ?>"><?php echo $assign_ch_name; ?></option>
620 + <?php
621 + }
622 + ?>
623 + </select>
624 + </div>
625 + </div>
626 + <?php
627 + }
628 + }
629 + if (!$printreceipt) {
630 + ?>
631 + <div class="vbo-bookdet-wrap">
632 + <div class="vbo-bookdet-head">
633 + <span><?php echo JText::translate('VBSTATUS'); ?></span>
634 + </div>
635 + <div class="vbo-bookdet-foot">
636 + <span><?php echo $saystaus; ?></span>
637 + </div>
638 + </div>
639 + <?php
640 + if (is_array($this->vcm_pre_approval)) {
641 + ?>
642 + <div class="vbo-bookdet-wrap">
643 + <div class="vbo-bookdet-head">
644 + <span><?php echo $this->vcm_pre_approval[1]; ?></span>
645 + </div>
646 + <div class="vbo-bookdet-foot">
647 + <span>
648 + <?php
649 + if (empty($this->vcm_pre_approval[2]) || !empty($this->vcm_pre_approval[3])) {
650 + // no pre-approvals before, or withdrawn before
651 + ?>
652 + <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>
653 + <?php
654 + } else {
655 + // pre-approved before, pass the ID
656 + ?>
657 + <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>
658 + <?php
659 + }
660 + ?>
661 + </span>
662 + </div>
663 + </div>
664 + <?php
665 + }
666 + if (!empty($row['channel']) && stripos($row['channel'], 'booking.com') !== false && $row['checkin'] <= $current_ts && strtotime('+ 7 days', $row['checkout']) >= $current_ts) {
667 + /**
668 + * Guest misconduct reporting API for Booking.com.
669 + * Only after reservation check-in date and no later than 7 days after check-out date.
670 + *
671 + * @since 1.13.5 - VCM 1.7.2
672 + */
673 + $misconduct_reported = $history_obj->hasEvent('GM');
674 + ?>
675 + <div class="vbo-bookdet-wrap">
676 + <div class="vbo-bookdet-head">
677 + <span><?php echo JText::translate('VBOGUESTMISCONDUCT'); ?></span>
678 + </div>
679 + <div class="vbo-bookdet-foot">
680 + <?php
681 + if ($misconduct_reported === false) {
682 + // allow to report the guest misconduct
683 + ?>
684 + <button type="button" class="btn btn-small btn-danger" onclick="vboRenderGuestMisconduct();"><?php VikBookingIcons::e('user-slash'); ?> <?php echo JText::translate('VBOREPORTMISCONDUCT'); ?></button>
685 + <?php
686 + } else {
687 + // guest misconduct already reported
688 + ?>
689 + <button type="button" class="btn btn-small btn-warning" onclick="vboShowGuestMisconductReported();"><?php VikBookingIcons::e('user-slash'); ?> <?php echo $misconduct_reported; ?></button>
690 + <?php
691 + }
692 + ?>
693 + <a id="vbo-gm-reloadlink" style="display: none;" href="index.php?option=com_vikbooking&task=editorder&cid[]=<?php echo $row['id']; ?>"></a>
694 + </div>
695 +
696 + <div class="vbo-modal-overlay-block vbo-modal-overlay-block-guestmisconduct">
697 + <a class="vbo-modal-overlay-close" href="javascript: void(0);"></a>
698 + <div class="vbo-modal-overlay-content vbo-modal-overlay-content-guestmisconduct">
699 + <div class="vbo-modal-overlay-content-head vbo-modal-overlay-content-head-guestmisconduct">
700 + <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>
701 + </div>
702 + <div class="vbo-modal-overlay-content-body">
703 + <div class="vbo-modal-guestmisconduct-addnew" data-bid="<?php echo $row['id']; ?>" data-otabid="<?php echo $row['idorderota']; ?>">
704 + <div class="vbo-modal-guestmisconduct-report-elems"></div>
705 + <div class="vbo-modal-guestmisconduct-addnew-save">
706 + <button type="button" id="vbo-guest-misconduct-submit-btn" class="btn btn-success" onclick="vboSubmitGuestMisconduct();" style="display: none;"><?php echo JText::translate('VBCHANNELMANAGERSENDRQ'); ?></button>
707 + <button type="button" class="btn btn-secondary" onclick="hideVboDialogGuestMisconduct();"><?php echo JText::translate('VBOCLOSE'); ?></button>
708 + </div>
709 + </div>
710 + </div>
711 + </div>
712 + </div>
713 +
714 + <script type="text/javascript">
715 + var vbodialogguestmisconduct_on = false;
716 + var vbo_guest_misconduct_fields = new Array;
717 +
718 + function vboShowGuestMisconductReported() {
719 + // this is like simulating the navigation to the booking history tab
720 + jQuery(".vbo-bookingdet-tab[data-vbotab='vbo-tab-admin']").trigger('click');
721 + vbToggleHistory(document.getElementById('vbo-trig-bookhistory'));
722 + }
723 +
724 + function vboRenderGuestMisconduct() {
725 + // empty content
726 + jQuery('.vbo-modal-guestmisconduct-report-elems').html('<?php echo $this->escape(JText::translate('VIKLOADING') . '...'); ?>');
727 + vbo_guest_misconduct_fields = new Array;
728 +
729 + // display modal
730 + jQuery('.vbo-modal-overlay-block-guestmisconduct').fadeIn();
731 + vbodialogguestmisconduct_on = true;
732 +
733 + // make AJAX request to VCM to always reload the form fields
734 + VBOCore.doAjax(
735 + "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikchannelmanager&task=get_bcom_misconduct_categories'); ?>",
736 + {
737 + tmpl: "component"
738 + },
739 + (res) => {
740 + // parse the JSON response that contains the categories object with all fields for the reporting
741 + try {
742 + var misconduct_fields_rs = typeof res === 'string' ? JSON.parse(res) : res;
743 +
744 + // make sure the request was successful
745 + if (!misconduct_fields_rs.status) {
746 + alert(misconduct_fields_rs.error);
747 + hideVboDialogGuestMisconduct();
748 + return false;
749 + }
750 +
751 + // render form from response obtained
752 + var misconduct_html = '';
753 + var misconduct_fields = misconduct_fields_rs.data;
754 + if (!misconduct_fields.hasOwnProperty('categories') || !misconduct_fields.hasOwnProperty('fields')) {
755 + alert('Unexptected response. Vik Channel Manager needs to be installed, configured and updated to the latest version.');
756 + hideVboDialogGuestMisconduct();
757 + return false;
758 + }
759 +
760 + // main category of misconduct
761 + misconduct_html += '<div class="vbo-modal-form-addnew-elem vbo-modal-guestmisconduct-addnew-elem">' + "\n";
762 + misconduct_html += '<label for="vbo-gm-category">' + misconduct_fields['labels']['category'] + '</label>';
763 + misconduct_html += '<select id="vbo-gm-category" data-gmname="category_id" onchange="vboGuestMisconductChangeCategory(this.value);">' + "\n";
764 + for (var category in misconduct_fields['categories']) {
765 + if (!misconduct_fields['categories'].hasOwnProperty(category)) {
766 + continue;
767 + }
768 + misconduct_html += '<option value="' + misconduct_fields['categories'][category]['id'] + '">' + misconduct_fields['categories'][category]['title'] + '</option>' + "\n";
769 + }
770 + misconduct_html += '</select>' + "\n";
771 + misconduct_html += '</div>' + "\n";
772 + // push category field in fields list for later submit
773 + vbo_guest_misconduct_fields.push('vbo-gm-category');
774 +
775 + // sub-categories or additional fields of misconduct categories
776 + for (var category in misconduct_fields['categories']) {
777 + if (!misconduct_fields['categories'].hasOwnProperty(category)) {
778 + continue;
779 + }
780 + if (!misconduct_fields['categories'][category].hasOwnProperty('subcategories') && !misconduct_fields['categories'][category].hasOwnProperty('additional_fields')) {
781 + // at least one of these two properties must be set
782 + continue;
783 + }
784 + if (misconduct_fields['categories'][category].hasOwnProperty('subcategories') && misconduct_fields['categories'][category]['subcategories'].length) {
785 + // sub-categories in drop down
786 + var subcat_field_id = 'vbo-gm-subcategory' + misconduct_fields['categories'][category]['id'];
787 + 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";
788 + misconduct_html += '<label for="' + subcat_field_id + '">' + misconduct_fields['labels']['subcategory'] + '</label>';
789 + misconduct_html += '<select id="' + subcat_field_id + '" data-gmname="subcategory_id">' + "\n";
790 + for (var subcategory in misconduct_fields['categories'][category]['subcategories']) {
791 + if (!misconduct_fields['categories'][category]['subcategories'].hasOwnProperty(subcategory)) {
792 + continue;
793 + }
794 + misconduct_html += '<option value="' + misconduct_fields['categories'][category]['subcategories'][subcategory]['id'] + '">' + misconduct_fields['categories'][category]['subcategories'][subcategory]['title'] + '</option>' + "\n";
795 + }
796 + misconduct_html += '</select>' + "\n";
797 + misconduct_html += '</div>' + "\n";
798 + // push sub-category field in fields list for later submit
799 + if (vbo_guest_misconduct_fields.indexOf(subcat_field_id) < 0) {
800 + vbo_guest_misconduct_fields.push(subcat_field_id);
801 + }
802 + } else if (misconduct_fields['categories'][category].hasOwnProperty('additional_fields') && misconduct_fields['categories'][category]['additional_fields'].length) {
803 + // additional fields
804 + for (var extra_field in misconduct_fields['categories'][category]['additional_fields']) {
805 + if (!misconduct_fields['categories'][category]['additional_fields'].hasOwnProperty(extra_field)) {
806 + continue;
807 + }
808 + var field_id = 'vbo-gm-extrafield-' + misconduct_fields['categories'][category]['additional_fields'][extra_field]['name'];
809 + var field_name = misconduct_fields['categories'][category]['additional_fields'][extra_field]['name'];
810 + 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";
811 + misconduct_html += '<label for="' + field_id + '">' + misconduct_fields['categories'][category]['additional_fields'][extra_field]['label'] + '</label>';
812 + if (misconduct_fields['categories'][category]['additional_fields'][extra_field]['type'] == 'number') {
813 + misconduct_html += '<input data-gmname="' + field_name + '" type="number" id="' + field_id + '" value="" step="any" min="0" />';
814 + } else if (misconduct_fields['categories'][category]['additional_fields'][extra_field]['type'] == 'text') {
815 + misconduct_html += '<input data-gmname="' + field_name + '" type="text" id="' + field_id + '" value="" />';
816 + } else if (misconduct_fields['categories'][category]['additional_fields'][extra_field]['type'] == 'text') {
817 + misconduct_html += '<input data-gmname="' + field_name + '" type="text" id="' + field_id + '" value="" />';
818 + } else if (misconduct_fields['categories'][category]['additional_fields'][extra_field]['type'] == 'textarea') {
819 + misconduct_html += '<textarea data-gmname="' + field_name + '" id="' + field_id + '" rows="5" cols="50" maxlength="240"></textarea>';
820 + } else if (misconduct_fields['categories'][category]['additional_fields'][extra_field]['type'] == 'select') {
821 + misconduct_html += '<select data-gmname="' + field_name + '" id="' + field_id + '">';
822 + for (var choicekey in misconduct_fields['categories'][category]['additional_fields'][extra_field]['choices']) {
823 + // 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
824 + if (!misconduct_fields['categories'][category]['additional_fields'][extra_field]['choices'].hasOwnProperty(choicekey)) {
825 + continue;
826 + }
827 + misconduct_html += '<option value="' + choicekey + '">' + misconduct_fields['categories'][category]['additional_fields'][extra_field]['choices'][choicekey] + '</option>';
828 + }
829 + misconduct_html += '</select>';
830 + }
831 + misconduct_html += '</div>' + "\n";
832 + // push additional field in fields list for later submit
833 + vbo_guest_misconduct_fields.push(field_id);
834 + }
835 + }
836 + }
837 +
838 + // mandatory fields for all categories of guest misconduct reporting
839 + for (var mandfield in misconduct_fields['fields']) {
840 + if (!misconduct_fields['fields'].hasOwnProperty(mandfield)) {
841 + continue;
842 + }
843 + var field_id = 'vbo-gm-mandfield-' + misconduct_fields['fields'][mandfield]['name'];
844 + var field_name = misconduct_fields['fields'][mandfield]['name'];
845 + misconduct_html += '<div class="vbo-modal-form-addnew-elem vbo-modal-guestmisconduct-addnew-elem">' + "\n";
846 + misconduct_html += '<label for="' + field_id + '">' + misconduct_fields['fields'][mandfield]['label'] + '</label>';
847 + if (misconduct_fields['fields'][mandfield]['type'] == 'number') {
848 + misconduct_html += '<input data-gmname="' + field_name + '" type="number" id="' + field_id + '" value="" step="any" min="0" />';
849 + } else if (misconduct_fields['fields'][mandfield]['type'] == 'text') {
850 + misconduct_html += '<input data-gmname="' + field_name + '" type="text" id="' + field_id + '" value="" />';
851 + } else if (misconduct_fields['fields'][mandfield]['type'] == 'text') {
852 + misconduct_html += '<input data-gmname="' + field_name + '" type="text" id="' + field_id + '" value="" />';
853 + } else if (misconduct_fields['fields'][mandfield]['type'] == 'textarea') {
854 + misconduct_html += '<textarea data-gmname="' + field_name + '" id="' + field_id + '" rows="5" cols="50" maxlength="240"></textarea>';
855 + } else if (misconduct_fields['fields'][mandfield]['type'] == 'select') {
856 + misconduct_html += '<select data-gmname="' + field_name + '" id="' + field_id + '">';
857 + for (var choicekey in misconduct_fields['fields'][mandfield]['choices']) {
858 + if (!misconduct_fields['fields'][mandfield]['choices'].hasOwnProperty(choicekey)) {
859 + continue;
860 + }
861 + misconduct_html += '<option value="' + choicekey + '">' + misconduct_fields['fields'][mandfield]['choices'][choicekey] + '</option>';
862 + }
863 + misconduct_html += '</select>';
864 + }
865 + misconduct_html += '</div>' + "\n";
866 + // push mandatory field in fields list for later submit
867 + vbo_guest_misconduct_fields.push(field_id);
868 + }
869 +
870 + // display HTML content and submit button
871 + jQuery('.vbo-modal-guestmisconduct-report-elems').html(misconduct_html);
872 + jQuery('#vbo-guest-misconduct-submit-btn').show();
873 + // trigger change of main category drop down
874 + jQuery('#vbo-gm-category').trigger('change');
875 + } catch (e) {
876 + console.log(res);
877 + alert('Invalid response. Vik Channel Manager needs to be installed, configured and updated to the latest version.');
878 + hideVboDialogGuestMisconduct();
879 + return false;
880 + }
881 + },
882 + (err) => {
883 + hideVboDialogGuestMisconduct();
884 + alert('Request failed. Vik Channel Manager needs to be installed, configured and updated to the latest version.');
885 + }
886 + );
887 + }
888 +
889 + function vboSubmitGuestMisconduct() {
890 + if (!vbo_guest_misconduct_fields.length) {
891 + alert('Empty data to submit. Vik Channel Manager needs to be installed, configured and updated to the latest version.');
892 + return false;
893 + }
894 +
895 + // prevent double submissions
896 + vboGuestMisconductDisableSubmit();
897 + //
898 +
899 + var submit_fields = {
900 + tmpl: "component",
901 + bid: jQuery('.vbo-modal-guestmisconduct-addnew').attr('data-bid'),
902 + otabid: jQuery('.vbo-modal-guestmisconduct-addnew').attr('data-otabid'),
903 + bcom_keys: new Array
904 + };
905 + for (var elemid in vbo_guest_misconduct_fields) {
906 + if (!vbo_guest_misconduct_fields.hasOwnProperty(elemid)) {
907 + continue;
908 + }
909 + if (!jQuery('#' + vbo_guest_misconduct_fields[elemid]).length || !jQuery('#' + vbo_guest_misconduct_fields[elemid]).closest('.vbo-modal-guestmisconduct-addnew-elem').length) {
910 + // form element not found, or parent container not found
911 + continue;
912 + }
913 + if (jQuery('#' + vbo_guest_misconduct_fields[elemid]).closest('.vbo-modal-guestmisconduct-addnew-elem').is(':visible')) {
914 + // we include this value in the AJAX request
915 + var field_name = jQuery('#' + vbo_guest_misconduct_fields[elemid]).attr('data-gmname');
916 + var submit_key = 'bcom_' + field_name;
917 + submit_fields[submit_key] = jQuery('#' + vbo_guest_misconduct_fields[elemid]).val();
918 + submit_fields['bcom_keys'].push(submit_key);
919 + }
920 + }
921 +
922 + // make the AJAX request to VCM
923 + var jqxhr = jQuery.ajax({
924 + type: "POST",
925 + url: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikchannelmanager&task=submit_bcom_guestmisconduct'); ?>",
926 + data: submit_fields
927 + }).done(function(res) {
928 + try {
929 + var misconduct_rs = typeof res === 'string' ? JSON.parse(res) : res;
930 + console.log(submit_fields, misconduct_rs);
931 +
932 + // make sure the request was successful
933 + if (!misconduct_rs.status) {
934 + alert(misconduct_rs.error);
935 + vboGuestMisconductEnableSubmit();
936 + return false;
937 + }
938 +
939 + // make another AJAX request (now on VBO) to update the booking history
940 + var event_descr = jQuery('#vbo-gm-mandfield-details_text').length ? jQuery('#vbo-gm-mandfield-details_text').val() : '';
941 + jQuery.ajax({
942 + type: "POST",
943 + url: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=store_booking_history_event'); ?>",
944 + data: {
945 + tmpl: "component",
946 + bid: jQuery('.vbo-modal-guestmisconduct-addnew').attr('data-bid'),
947 + event: 'GM',
948 + descr: event_descr
949 + }
950 + }).done(function(res) {
951 + // just reload the page in case of success
952 + document.location.href = jQuery('#vbo-gm-reloadlink').attr('href');
953 + }).fail(function() {
954 + // we reload the page even in case of failure
955 + document.location.href = jQuery('#vbo-gm-reloadlink').attr('href');
956 + });
957 + } catch (e) {
958 + console.log(res);
959 + alert('Invalid update response. Vik Channel Manager needs to be installed, configured and updated to the latest version.');
960 + vboGuestMisconductEnableSubmit();
961 + hideVboDialogGuestMisconduct();
962 + return false;
963 + }
964 + }).fail(function() {
965 + alert('Update Request failed. Vik Channel Manager needs to be installed, configured and updated to the latest version.');
966 + vboGuestMisconductEnableSubmit();
967 + return false;
968 + });
969 + }
970 +
971 + function hideVboDialogGuestMisconduct() {
972 + if (vbodialogguestmisconduct_on === true) {
973 + jQuery(".vbo-modal-overlay-block-guestmisconduct").fadeOut(400, function () {
974 + jQuery(".vbo-modal-overlay-content-guestmisconduct").show();
975 + });
976 + // turn flag off
977 + vbodialogguestmisconduct_on = false;
978 + }
979 + }
980 +
981 + function vboGuestMisconductChangeCategory(gmcid) {
982 + jQuery('.vbo-modal-guestmisconduct-addnew-cond').each(function() {
983 + if (jQuery(this).attr('data-gmcid') == gmcid) {
984 + jQuery(this).show();
985 + } else {
986 + jQuery(this).hide();
987 + }
988 + });
989 + }
990 +
991 + function vboGuestMisconductDisableSubmit() {
992 + jQuery('#vbo-guest-misconduct-submit-btn').prepend('<i class="<?php echo VikBookingIcons::i('refresh', 'fa-spin fa-fw'); ?>"></i> ').prop('disabled', true);
993 + }
994 +
995 + function vboGuestMisconductEnableSubmit() {
996 + jQuery('#vbo-guest-misconduct-submit-btn').prop('disabled', false).find('i').remove();
997 + }
998 + </script>
999 +
1000 + </div>
1001 + <?php
1002 + }
1003 + if ($this->vcm_host_to_guest_review) {
1004 + ?>
1005 + <div class="vbo-bookdet-wrap">
1006 + <div class="vbo-bookdet-head">
1007 + <span><?php echo JText::translate('VBO_REVIEW_YOUR_GUEST'); ?></span>
1008 + </div>
1009 + <div class="vbo-bookdet-foot">
1010 + <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');">
1011 + <?php VikBookingIcons::e('smile'); ?>
1012 + <?php echo JText::translate('VBO_WRITE_REVIEW'); ?>
1013 + </button>
1014 + </div>
1015 + </div>
1016 + <?php
1017 + // prepare modal (host-to-guest review)
1018 + array_push($vbo_modals_html, $vbo_app->getJmodalHtml('vbo-vcm-host-to-guest-review', JText::translate('VBO_REVIEW_YOUR_GUEST')));
1019 +
1020 + // check if a notification was clicked
1021 + if (VikRequest::getString('notif_action', '', 'request') == 'airbnb_host_guest_review') {
1022 + JFactory::getDocument()->addScriptDeclaration(
1023 +<<<JS
1024 +jQuery(function() {
1025 + setTimeout(() => {
1026 + jQuery('.vcm-btn-channel-airbnbapi').trigger('click');
1027 + }, 500);
1028 +});
1029 +JS
1030 + );
1031 + }
1032 + }
1033 + }
1034 + ?>
1035 + </div>
1036 +
1037 + <?php
1038 + if (!$printreceipt && $this->allows_conversion !== false) {
1039 + ?>
1040 + <div class="vbo-bookdet-container vbo-bookdet-conv-currency">
1041 + <div class="vbo-bookdet-conv-currency-inner">
1042 + <div class="vbo-bookdet-conv-currency-info">
1043 + <span><?php echo JText::sprintf('VBO_CONV_RES_OTA_CURRENCY', $this->conv_from_currency, $this->conv_to_currency); ?></span>
1044 + <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>
1045 + </div>
1046 + <div class="vbo-bookdet-conv-currency-apply">
1047 + <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>
1048 + </div>
1049 + </div>
1050 + </div>
1051 + <?php
1052 + }
1053 +
1054 + if (!$printreceipt && $row['status'] == "standby" && empty($row['idorderota']) && !strcasecmp((string)$row['type'], 'Inquiry')) {
1055 + // website pending reservation inquiry
1056 + $ir_data_callback = function($data) {
1057 + return (is_object($data) && !empty($data->av_type));
1058 + };
1059 + $prev_ir_data = $history_obj->getEventsWithData('IR', $ir_data_callback, true);
1060 + if (is_array($prev_ir_data) && $prev_ir_data) {
1061 + // display a message about the availability type at the time of creation of the inquiry reservation
1062 +
1063 + // parse original stay dates into DateTime objects
1064 + $orig_checkin_dt_obj = new JDate($prev_ir_data[0]->checkin_date);
1065 + $orig_checkout_dt_obj = new JDate($prev_ir_data[0]->checkout_date);
1066 + ?>
1067 + <div class="vbo-bookdet-container vbo-bookdet-inquiry-alert">
1068 + <div class="vbo-bookdet-inquiry-alert-dismiss">
1069 + <button type="button" class="btn btn-small btn-warning" onclick="jQuery('.vbo-bookdet-inquiry-alert').remove();"><?php VikBookingIcons::e('times-circle'); ?> <?php echo JText::translate('VBOBTNKEEPREMIND'); ?></button>
1070 + </div>
1071 + <div class="vbo-bookdet-inquiry-alert-message">
1072 + <div class="vbo-bookdet-inquiry-alert-top">
1073 + <span><?php echo JText::translate('VBO_WEB_INQUIRY_ALERT'); ?></span>
1074 + </div>
1075 + <div class="vbo-bookdet-inquiry-alert-avtype">
1076 + <span class="vbo-bookdet-inquiry-alert-mess-avtype"><?php
1077 + // explain what was the availability at the time of inquiry
1078 + if ($prev_ir_data[0]->av_type === 1) {
1079 + echo JText::translate('VBO_WEB_INQUIRY_AVTYPE_1');
1080 + } elseif ($prev_ir_data[0]->av_type === 2) {
1081 + echo JText::translate('VBO_WEB_INQUIRY_AVTYPE_2');
1082 + } elseif ($prev_ir_data[0]->av_type === 3) {
1083 + echo JText::translate('VBO_WEB_INQUIRY_AVTYPE_3');
1084 + } else {
1085 + echo JText::translate('VBO_WEB_INQUIRY_AVTYPE_4');
1086 + }
1087 + ?></span>
1088 + <span class="vbo-bookdet-inquiry-alert-mess-origrq">
1089 + <strong><?php echo JText::translate('VBO_WEB_INQUIRY_ORIGRQ') . ':'; ?></strong>
1090 + <span class="badge"><?php echo JText::translate('VBPICKUPAT') . ': ' . $orig_checkin_dt_obj->format('D, d M Y', true); ?></span>
1091 + <span class="badge"><?php echo JText::translate('VBRELEASEAT') . ': ' . $orig_checkout_dt_obj->format('D, d M Y', true); ?></span>
1092 + <span class="badge"><?php echo JText::translate('VBEDITORDERADULTS') . ': ' . $prev_ir_data[0]->adults; ?></span>
1093 + <?php
1094 + if (!empty($prev_ir_data[0]->children)) {
1095 + ?>
1096 + <span class="badge"><?php echo JText::translate('VBEDITORDERCHILDREN') . ': ' . $prev_ir_data[0]->children; ?></span>
1097 + <?php
1098 + }
1099 + ?>
1100 + </span>
1101 + </div>
1102 + <div class="vbo-bookdet-inquiry-alert-bottom">
1103 + <span><?php echo JText::translate('VBO_WEB_INQUIRY_SUGG'); ?></span>
1104 + </div>
1105 + <?php
1106 + if (empty($row['idquote'])) {
1107 + // even if it cannot be a quote, we make sure it's just an inquiry for now
1108 + $createQuoteUri = 'index.php?option=com_vikbooking&view=managequote&' . http_build_query([
1109 + 'customer' => [
1110 + 'id' => $customer['id'] ?? null,
1111 + 'first_name' => $customer['first_name'] ?? null,
1112 + 'last_name' => $customer['last_name'] ?? null,
1113 + 'email' => $customer['email'] ?? null,
1114 + 'phone' => $customer['phone'] ?? null,
1115 + 'country' => $customer['country'] ?? null,
1116 + ],
1117 + 'inquiry' => [
1118 + 'checkin' => date('Y-m-d', $row['checkin']),
1119 + 'checkout' => date('Y-m-d', $row['checkout']),
1120 + 'parties' => array_map(function($or) {
1121 + return [
1122 + 'adults' => $or['adults'] ?? 1,
1123 + 'children' => $or['children'] ?? 0,
1124 + ];
1125 + }, $rooms),
1126 + 'rooms' => array_map(function($or) {
1127 + return [
1128 + 'id' => $or['idroom'] ?? 0,
1129 + ];
1130 + }, $rooms),
1131 + ],
1132 + ]);
1133 + ?>
1134 + <div class="vbo-bookdet-inquiry-alert-bottom">
1135 + <a class="btn vbo-config-btn" href="<?php echo VBOFactory::getPlatform()->getUri()->admin($createQuoteUri); ?>"><?php VikBookingIcons::e('file-alt'); ?> <?php echo JText::translate('VBO_CREATE_QUOTE'); ?></a>
1136 + </div>
1137 + <?php
1138 + }
1139 + ?>
1140 + </div>
1141 + </div>
1142 + <?php
1143 + }
1144 + }
1145 + ?>
1146 +
1147 + <div class="vbo-bookingdet-innertop">
1148 + <div class="vbo-bookingdet-commands">
1149 + <?php
1150 + if ($busy || $row['status'] == "standby") {
1151 + ?>
1152 + <div class="vbo-bookingdet-command">
1153 + <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>
1154 + </div>
1155 + <?php
1156 + }
1157 + if (!empty($row['idquote'])) {
1158 + ?>
1159 + <div class="vbo-bookingdet-command">
1160 + <button class="btn vbo-config-btn vbo-quote-details-btn" type="button"><?php VikBookingIcons::e('file-alt'); ?> <?php echo JText::translate('VBO_QUOTE_DETAILS'); ?></button>
1161 + </div>
1162 + <?php
1163 + }
1164 + if ((array_key_exists(1, $tars) && $tars[1]) || ($is_package || $is_cust_cost)) {
1165 +
1166 + if (VBOPlatformDetection::isWordPress()) {
1167 + /**
1168 + * @wponly display warning message if no valid Shortcodes found
1169 + */
1170 + $model = JModel::getInstance('vikbooking', 'shortcodes');
1171 + $itemid = $model->best('booking');
1172 + if (!$itemid) {
1173 + VikError::raiseWarning('', 'No Shortcodes found, or no Shortcodes being used in Pages/Posts.');
1174 + }
1175 + }
1176 +
1177 + ?>
1178 + <div class="vbo-bookingdet-command">
1179 + <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>
1180 + </div>
1181 + <?php
1182 + }
1183 + if (($row['status'] == "confirmed" || ($row['status'] == "standby" && !empty($row['custmail']))) && ((array_key_exists(1, $tars) && $tars[1]) || ($is_package || $is_cust_cost))) {
1184 + ?>
1185 + <div class="vbo-bookingdet-command">
1186 + <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>
1187 + </div>
1188 + <?php
1189 + }
1190 + if (is_array($this->vcm_special_offer)) {
1191 + if (empty($this->vcm_special_offer[3]) || !empty($this->vcm_special_offer[4])) {
1192 + // no special offer sent before, or withdrawn
1193 + ?>
1194 + <div class="vbo-bookingdet-command">
1195 + <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>
1196 + </div>
1197 + <?php
1198 + // prepare modal (VCM prepare special offer)
1199 + array_push($vbo_modals_html, $vbo_app->getJmodalHtml('vbo-vcm-special-offer', JText::sprintf('VBO_VCM_SPECIAL_OFFER', $this->vcm_special_offer[2])));
1200 + // end prepare modal
1201 + } else {
1202 + // special offer sent before, link to withdraw it
1203 + ?>
1204 + <div class="vbo-bookingdet-command">
1205 + <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>
1206 + </div>
1207 + <?php
1208 + }
1209 + }
1210 + if ($row['status'] == "standby" || ($row['status'] == "cancelled" && $row['checkout'] >= $current_ts)) {
1211 + ?>
1212 + <div class="vbo-bookingdet-command">
1213 + <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>
1214 + </div>
1215 + <?php
1216 + }
1217 + if ($row['status'] == "cancelled" && !$row['closure']) {
1218 + ?>
1219 + <div class="vbo-bookingdet-command">
1220 + <button type="button" class="btn btn-warning vbo-context-menu-btn vbo-context-menu-actionscanc">
1221 + <span class="vbo-context-menu-lbl"><?php echo JText::translate('VBCRONACTIONS'); ?></span>
1222 + <span class="vbo-context-menu-ico"><?php VikBookingIcons::e('sort-down'); ?></span>
1223 + </button>
1224 + </div>
1225 +
1226 + <script type="text/javascript">
1227 + jQuery(function() {
1228 + jQuery('.vbo-context-menu-actionscanc').vboContextMenu({
1229 + placement: 'bottom-right',
1230 + buttons: [
1231 + <?php
1232 + if (!empty($row['custmail'])) :
1233 + ?>
1234 + {
1235 + icon: '<?php echo VikBookingIcons::i('envelope'); ?>',
1236 + text: Joomla.JText._('VBSENDCANCORDEMAIL'),
1237 + class: 'vbo-context-menu-entry-danger',
1238 + separator: true,
1239 + action: (root, config) => {
1240 + document.location.href = 'index.php?option=com_vikbooking&task=sendcancordemail&cid[]=<?php echo $row['id']; ?>';
1241 + },
1242 + },
1243 + <?php
1244 + endif;
1245 + ?>
1246 + {
1247 + icon: '<?php echo VikBookingIcons::i('hourglass-half'); ?>',
1248 + text: Joomla.JText._('VBO_SET_STANDBY'),
1249 + class: 'vbo-context-menu-entry-warning',
1250 + separator: false,
1251 + action: (root, config) => {
1252 + document.location.href = '<?php echo VBOFactory::getPlatform()->getUri()->addCSRF('index.php?option=com_vikbooking&task=bookings.set_to_pending&bid=' . $row['id']); ?>';
1253 + },
1254 + },
1255 + ],
1256 + });
1257 + });
1258 + </script>
1259 + <?php
1260 + }
1261 + if ($row['status'] == 'confirmed' && $row['closure'] < 1) {
1262 + ?>
1263 + <div class="vbo-bookingdet-command pro-feature">
1264 + <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>
1265 + </div>
1266 + <?php
1267 + }
1268 + if ($row['status'] == 'confirmed' && $row['closure'] < 1) {
1269 + ?>
1270 + <div class="vbo-bookingdet-command pro-feature">
1271 + <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>
1272 + </div>
1273 + <?php
1274 + }
1275 + if ($row['status'] != 'confirmed' || $row['closure'] > 0 || $this->vcm_cancel_active_res) {
1276 + if ($this->vcm_decline_actions) {
1277 + // this booking requires some decline actions before being removed
1278 + ?>
1279 + <div class="vbo-bookingdet-command">
1280 + <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>
1281 + </div>
1282 + <?php
1283 + // prepare modal (VCM decline booking)
1284 + array_push($vbo_modals_html, $vbo_app->getJmodalHtml('vbo-vcm-decline-booking', JText::translate('VBMAINEBUSYDEL')));
1285 + // end prepare modal
1286 + } elseif ($this->vcm_cancel_active_res) {
1287 + // the active OTA booking can be cancelled
1288 + ?>
1289 + <div class="vbo-bookingdet-command">
1290 + <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>
1291 + </div>
1292 + <?php
1293 + // prepare modal (VCM cancel reservation)
1294 + array_push($vbo_modals_html, $vbo_app->getJmodalHtml('vbo-vcm-cancel-reservation', JText::translate('VBMAINEBUSYDEL')));
1295 + // end prepare modal
1296 + } else {
1297 + // regular remove button with confirmation
1298 + ?>
1299 + <div class="vbo-bookingdet-command">
1300 + <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>
1301 + </div>
1302 + <?php
1303 + }
1304 + }
1305 + ?>
1306 +
1307 + <!-- Define role to detect the supported hook -->
1308 + <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorder","key":"buttons","type":"field"} -->
1309 +
1310 + <?php
1311 + if (isset($bookingPanelForms['buttons']))
1312 + {
1313 + echo $bookingPanelForms['buttons'];
1314 + }
1315 + ?>
1316 + </div>
1317 +
1318 + <div class="vbo-bookingdet-tabs">
1319 + <div class="vbo-bookingdet-tab vbo-bookingdet-tab-active" data-vbotab="vbo-tab-details"><?php echo JText::translate('VBOBOOKDETTABDETAILS'); ?></div>
1320 + <div class="vbo-bookingdet-tab" data-vbotab="vbo-tab-admin"><?php echo JText::translate('VBOBOOKDETTABADMIN'); ?></div>
1321 + </div>
1322 + </div>
1323 +
1324 + <?php
1325 + /**
1326 + * Check if the booking has got some tasks assigned.
1327 + *
1328 + * @since 1.18.0 (J) - 1.8.0 (WP)
1329 + */
1330 + $taskManager = VBOFactory::getTaskManager();
1331 + $bookingTasks = VBOTaskModelTask::getInstance()->filterItems(['id_order' => $row['id']]);
1332 +
1333 + /**
1334 + * Check if the booking should have had passcodes generated.
1335 + *
1336 + * @since 1.18.16 (J) - 1.8.16 (WP)
1337 + */
1338 + $shouldHavePasscodes = !$history_obj->hasEvent(['ND', 'MD']) && VBOFactory::getDoorAccessControl()->shouldBookingHavePasscodes($registry);
1339 + ?>
1340 +
1341 + <div class="vbo-bookingdet-tab-cont" id="vbo-tab-details" style="display: block;">
1342 + <div class="vbo-bookingdet-innercontainer">
1343 + <div class="vbo-bookingdet-customer">
1344 + <?php
1345 + if ($bookingTasks) {
1346 + ?>
1347 + <div class="vbo-bookingdet-detcont vbo-bookingdet-detcont-tm vbo-hidein-print">
1348 + <div class="vbo-bookingdet-lblcont">
1349 + <label><?php echo JText::translate('VBO_TASK_MANAGER'); ?></label>
1350 + </div>
1351 + <div class="vbo-bookingdet-inpwrap vbo-bookingdet-tasks-list">
1352 + <?php
1353 + foreach ($bookingTasks as $taskRecord) {
1354 + $task = VBOTaskTaskregistry::getInstance((array) $taskRecord);
1355 + ?>
1356 + <div class="vbo-bookingdet-task-details" data-task-id="<?php echo $task->getID(); ?>">
1357 + <div class="vbo-bookingdet-task-detail" data-type="info">
1358 + <span class="vbo-bookingdet-task-title"><?php echo $task->getTitle(); ?></span>
1359 + <span class="vbo-bookingdet-task-sub-title"><?php echo $task->getAreaName($task->getAreaID()); ?></span>
1360 + </div>
1361 + <?php
1362 + $taskUnreadMessages = (bool) $task->get('hasUnreadMessages', false);
1363 + if ($taskUnreadMessages) {
1364 + ?>
1365 + <div class="vbo-bookingdet-task-detail" data-type="unread-messages">
1366 + <span class="unread-message-dot"><?php VikBookingIcons::e('comment'); ?></span>
1367 + </div>
1368 + <?php
1369 + }
1370 + if ($taskManager->statusTypeExists($task->getStatus())) {
1371 + $taskStatus = $taskManager->getStatusTypeInstance($task->getStatus());
1372 + ?>
1373 + <div class="vbo-bookingdet-task-detail" data-type="status">
1374 + <span class="vbo-tm-task-status-badge vbo-tm-color <?php echo $taskStatus->getColor(); ?>" data-status="<?php echo $this->escape($taskStatus->getEnum()); ?>"><?php echo $taskStatus->getName(); ?></span>
1375 + </div>
1376 + <?php
1377 + }
1378 + ?>
1379 + </div>
1380 + <?php
1381 + }
1382 + ?>
1383 + </div>
1384 + </div>
1385 + <?php
1386 + }
1387 + if ($shouldHavePasscodes) {
1388 + ?>
1389 + <div class="vbo-bookingdet-detcont vbo-bookingdet-detcont-dac vbo-hidein-print">
1390 + <div class="vbo-bookingdet-lblcont">
1391 + <label><?php echo JText::translate('VBO_W_DOORACCESSCONTROL_TITLE'); ?></label>
1392 + </div>
1393 + <div class="vbo-bookingdet-inpwrap vbo-bookingdet-dac-gen">
1394 + <a href="<?php echo VBOFactory::getPlatform()->getUri()->addCSRF('index.php?option=com_vikbooking&task=bookings.generatePasscodes&bid=' . $row['id']); ?>" class="btn"><?php echo JText::translate('VBO_CREATE_PASSCODE'); ?></a>
1395 + </div>
1396 + </div>
1397 + <?php
1398 + }
1399 + ?>
1400 + <div class="vbo-bookingdet-detcont<?php echo $row['closure'] > 0 ? ' vbo-bookingdet-closure' : ''; ?>">
1401 + <?php
1402 + $custdata_parts = explode("\n", $row['custdata']);
1403 + if (count($custdata_parts) > 2 && strpos($custdata_parts[0], ':') !== false && strpos($custdata_parts[1], ':') !== false) {
1404 + //attempt to format labels and values
1405 + foreach ($custdata_parts as $custdet) {
1406 + if (strlen($custdet) < 1) {
1407 + continue;
1408 + }
1409 + $custdet_parts = explode(':', $custdet);
1410 + $custd_lbl = '';
1411 + $custd_val = '';
1412 + if (count($custdet_parts) < 2) {
1413 + $custd_val = $custdet;
1414 + } else {
1415 + $custd_lbl = $custdet_parts[0];
1416 + if ($custd_lbl == 'http' || $custd_lbl == 'https') {
1417 + // shift values
1418 + $custdet_parts[2] = $custdet_parts[1];
1419 + $custdet_parts[1] = $custdet_parts[0];
1420 + $custd_lbl = '';
1421 + }
1422 + unset($custdet_parts[0]);
1423 + if ((!strcasecmp(trim($custdet_parts[1]), 'http') || !strcasecmp(trim($custdet_parts[1]), 'https')) && !empty($custdet_parts[2]) && strpos($custdet_parts[2], '//') !== false) {
1424 + // this is a URI
1425 + $custd_val = '<a href="' . htmlspecialchars(trim(implode(':', $custdet_parts))) . '" target="_blank"><i class="' . VikBookingIcons::i('external-link') . '"></i></a>';
1426 + } else {
1427 + $custd_val = htmlspecialchars(trim(implode(':', $custdet_parts)));
1428 + }
1429 + }
1430 + ?>
1431 + <div class="vbo-bookingdet-userdetail">
1432 + <?php
1433 + if (strlen($custd_lbl)) {
1434 + ?>
1435 + <span class="vbo-bookingdet-userdetail-lbl"><?php echo VikBooking::tnCustomerRawDataLabel($custd_lbl); ?></span>
1436 + <?php
1437 + }
1438 + if (strlen($custd_val)) {
1439 + ?>
1440 + <span class="vbo-bookingdet-userdetail-val"><?php echo $custd_val; ?></span>
1441 + <?php
1442 + }
1443 + ?>
1444 + </div>
1445 + <?php
1446 + }
1447 + } else {
1448 + if ($row['closure'] > 0) {
1449 + ?>
1450 + <div class="vbo-bookingdet-userdetail">
1451 + <span class="vbo-bookingdet-userdetail-val"><?php echo nl2br($row['custdata']); ?></span>
1452 + </div>
1453 + <?php
1454 + } else {
1455 + echo nl2br($row['custdata']);
1456 + ?>
1457 + <div class="vbo-bookingdet-userdetail">
1458 + <span class="vbo-bookingdet-userdetail-val">&nbsp;</span>
1459 + </div>
1460 + <?php
1461 + }
1462 + }
1463 + if (!empty($row['ujid'])) {
1464 + $orig_user = JFactory::getUser($row['ujid']);
1465 + $author_name = is_object($orig_user) && property_exists($orig_user, 'name') && !empty($orig_user->name) ? $orig_user->name : '';
1466 + ?>
1467 + <div class="vbo-bookingdet-userdetail">
1468 + <span class="vbo-bookingdet-userdetail-val"><?php echo JText::sprintf('VBOBOOKINGCREATEDBY', $row['ujid'].(!empty($author_name) ? ' ('.$author_name.')' : '')); ?></span>
1469 + </div>
1470 + <?php
1471 + }
1472 + ?>
1473 +
1474 + <!-- Define role to detect the supported hook -->
1475 + <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderSidebar","key":"userdetails","type":"field"} -->
1476 +
1477 + <?php
1478 + if (isset($bookingSidebarForms['userdetails']))
1479 + {
1480 + echo $bookingSidebarForms['userdetails'];
1481 + }
1482 + ?>
1483 +
1484 + </div>
1485 +
1486 + <?php
1487 + // build the proper invoice SID for bc
1488 + $inv_sid = $row['sid'] ?: $row['idorderota'] ?: '';
1489 + if (empty($row['sid']) && is_file(implode(DIRECTORY_SEPARATOR, [VBO_SITE_PATH, 'helpers', 'invoices', 'generated', "{$row['id']}_{$row['sid']}.pdf"]))) {
1490 + // use the old file name signature for OTA bookings
1491 + $inv_sid = $row['sid'];
1492 + }
1493 +
1494 + // build list of invoice details (path/uri & label/button), one by default
1495 + $invoice_details = [
1496 + [
1497 + 'path' => implode(DIRECTORY_SEPARATOR, [VBO_SITE_PATH, 'helpers', 'invoices', 'generated', "{$row['id']}_{$inv_sid}.pdf"]),
1498 + 'uri' => VBO_SITE_URI . 'helpers/invoices/generated/' . "{$row['id']}_{$inv_sid}.pdf",
1499 + 'label' => JText::translate('VBOCOLORTAGRULEINVONE'),
1500 + 'btn' => JText::translate('VBOINVDOWNLOAD'),
1501 + ]
1502 + ];
1503 +
1504 + /**
1505 + * Merge the additional invoices generated by the e-invoicing drivers for this booking.
1506 + *
1507 + * @since 1.16.7 (J) - 1.6.7 (WP)
1508 + */
1509 + $invoice_details = array_merge($invoice_details, VBOEinvoicingFactory::getInstance()->getBookingExtraInvoices($row['id']));
1510 +
1511 + /**
1512 + * Trigger event to allow third-party plugins to define additional invoices or paths/urls.
1513 + *
1514 + * @since 1.16.7 (J) - 1.6.7 (WP)
1515 + */
1516 + VBOFactory::getPlatform()->getDispatcher()->trigger('onBeforeListInvoices', [$row, &$invoice_details]);
1517 +
1518 + // check if an invoice exists
1519 + $invoiced = false;
1520 + foreach ((array) $invoice_details as $invoice_detail) {
1521 + $invoiced = $invoiced || is_file($invoice_detail['path']);
1522 + }
1523 +
1524 + // extra booking details
1525 + if (!$printreceipt && ((!empty($row['channel']) && !empty($row['idorderota'])) || strlen((string)$row['confirmnumber']) || $invoiced)) {
1526 + ?>
1527 + <div class="vbo-bookingdet-detcont vbo-bookingdet-detcont-labels-wrap vbo-hidein-print">
1528 + <?php
1529 + if (!empty($row['channel']) && !empty($row['idorderota'])) {
1530 + $tiny_logo_url = '';
1531 + $channelparts = explode('_', $row['channel']);
1532 + if ($ch_logo = VikBooking::getVcmChannelsLogo($row['channel'], true)) {
1533 + $tiny_logo_url = $ch_logo->getTinyLogoURL();
1534 + }
1535 + $displayOtaBid = !strcasecmp((string) $row['type'], 'Inquiry') && $row['status'] == 'standby' ? '' : $row['idorderota'];
1536 + ?>
1537 + <div class="vbo-bookingdet-detcont-label vbo-bookingdet-detcont-label-idorderota <?php echo strtolower(preg_replace('/[^a-z0-9]/i', '', $channelparts[0])); ?>">
1538 + <span class="label label-info">
1539 + <span class="vbo-bookingdet-ota-details">
1540 + <?php
1541 + if ($tiny_logo_url) {
1542 + ?>
1543 + <span class="vbo-bookingdet-ota-logo"><img src="<?php echo $tiny_logo_url; ?>" /></span>
1544 + <?php
1545 + }
1546 + ?>
1547 + <span class="vbo-bookingdet-ota-name"><?php echo $otachannel_name . ' ID'; ?></span>
1548 + </span>
1549 + <span class="badge<?php echo $displayOtaBid ? ' vbo-tooltip vbo-tooltip-top vbo-reservation-copy-otabid' : ''; ?>" data-tooltiptext="<?php echo JHtml::fetch('esc_attr', JText::translate('VBO_COPY')); ?>"><?php echo $displayOtaBid ? $row['idorderota'] : '-----'; ?></span>
1550 + </span>
1551 + <textarea class="vbo-textarea-copyable" data-copy="otabid"><?php echo htmlentities($displayOtaBid); ?></textarea>
1552 + </div>
1553 + <?php
1554 + }
1555 + if (strlen((string)$row['confirmnumber'])) {
1556 + ?>
1557 + <div class="vbo-bookingdet-detcont-label vbo-bookingdet-detcont-label-confirmnumber">
1558 + <span class="label label-success">
1559 + <span><?php echo JText::translate('VBCONFIRMNUMB'); ?></span>
1560 + <span class="badge"><?php echo $row['confirmnumber']; ?></span>
1561 + </span>
1562 + </div>
1563 + <?php
1564 + }
1565 +
1566 + /**
1567 + * Check for AI automated host-to-guest reviews.
1568 + *
1569 + * @since 1.16.10 (J) - 1.6.10 (WP)
1570 + */
1571 + if (class_exists('VikChannelManager') && VikChannelManager::hostToGuestReviewSupported($row, $willbe = true)) {
1572 + if (class_exists('VCMAiModelSettings') && (new VCMAiModelSettings)->isGuestReviewAutoResponderEnabled()) {
1573 + // host-to-guest review will be supported and AI auto-guest-review is enabled
1574 + $ai_auto_guest_review_opt = (array) VBOFactory::getConfig()->getArray('ai_auto_guest_review_opt_' . $row['id'], []);
1575 + ?>
1576 + <div class="vbo-bookingdet-detcont-ai-info">
1577 + <p class="vbo-bookingdet-detcont-ai-info-status">
1578 + <span class="vbo-bookingdet-detcont-ai-info-status-on" style="<?php echo ($ai_auto_guest_review_opt['ignore'] ?? 0) ? 'display: none;' : ''; ?>"><?php VikBookingIcons::e('check-circle'); ?> <span><?php echo JText::translate('VBO_AI_AUTO_GUEST_REV_WILLRUN'); ?></span></span>
1579 + <span class="vbo-bookingdet-detcont-ai-info-status-off" style="<?php echo !($ai_auto_guest_review_opt['ignore'] ?? 0) ? 'display: none;' : ''; ?>"><?php VikBookingIcons::e('ban'); ?> <span><?php echo JText::translate('VBO_AI_AUTO_GUEST_REV_RESIGNORE'); ?></span></span>
1580 + </p>
1581 + <button type="button" class="btn btn-small btn-primary vbo-context-menu-btn vbo-context-menu-ai-autoreview">
1582 + <span class="vbo-context-menu-lbl"><?php echo JText::translate('VBCRONACTIONS'); ?></span>
1583 + <span class="vbo-context-menu-ico"><?php VikBookingIcons::e('sort-down'); ?></span>
1584 + </button>
1585 + </div>
1586 +
1587 + <script type="text/javascript">
1588 + // build context menu
1589 + jQuery(function() {
1590 +
1591 + // toggle ignore AI auto-review guest function
1592 + let vbo_action_ignore_ai_autorg = (now_ignore) => {
1593 + if (confirm(Joomla.JText._((now_ignore ? 'VBO_AI_AUTO_GUEST_REV_INCLUDE' : 'VBO_AI_AUTO_GUEST_REV_EXCLUDE')))) {
1594 + // update the auto-review ignore status for this booking
1595 + VBOCore.doAjax(
1596 + "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=bookings.set_ai_auto_guest_review_opt'); ?>",
1597 + {
1598 + bid: '<?php echo $row['id']; ?>',
1599 + opt: {
1600 + ignore: (now_ignore ? 0 : 1),
1601 + },
1602 + },
1603 + (opt) => {
1604 + // populate the new buttons
1605 + let new_auto_review_opt = [];
1606 + new_auto_review_opt.push({
1607 + icon: ((opt.ignore || 0) ? '<?php echo VikBookingIcons::i('check-circle'); ?>' : '<?php echo VikBookingIcons::i('ban'); ?>'),
1608 + text: Joomla.JText._((opt?.ignore ? 'VBO_AI_AUTO_GUEST_REV_INCLUDE' : 'VBO_AI_AUTO_GUEST_REV_EXCLUDE')),
1609 + class: (opt?.ignore ? 'vbo-context-menu-entry-success' : 'vbo-context-menu-entry-danger'),
1610 + separator: true,
1611 + action: (root, config) => {
1612 + // register callback
1613 + vbo_action_ignore_ai_autorg(opt.ignore || 0);
1614 + },
1615 + });
1616 +
1617 + // set new buttons in context menu
1618 + jQuery('.vbo-context-menu-ai-autoreview').vboContextMenu('buttons', new_auto_review_opt);
1619 +
1620 + // display the proper status label
1621 + if (opt?.ignore) {
1622 + jQuery('.vbo-bookingdet-detcont-ai-info-status-on').hide();
1623 + jQuery('.vbo-bookingdet-detcont-ai-info-status-off').show();
1624 + } else {
1625 + jQuery('.vbo-bookingdet-detcont-ai-info-status-off').hide();
1626 + jQuery('.vbo-bookingdet-detcont-ai-info-status-on').show();
1627 + }
1628 + },
1629 + (error) => {
1630 + // display error message
1631 + alert(error.responseText);
1632 + }
1633 + );
1634 + }
1635 + };
1636 +
1637 + // render context menu
1638 + jQuery('.vbo-context-menu-ai-autoreview').vboContextMenu({
1639 + placement: 'bottom-left',
1640 + buttons: [
1641 + {
1642 + icon: '<?php echo VikBookingIcons::i(($ai_auto_guest_review_opt['ignore'] ?? 0) ? 'check-circle' : 'ban'); ?>',
1643 + text: Joomla.JText._('<?php echo ($ai_auto_guest_review_opt['ignore'] ?? 0) ? 'VBO_AI_AUTO_GUEST_REV_INCLUDE' : 'VBO_AI_AUTO_GUEST_REV_EXCLUDE'; ?>'),
1644 + class: '<?php echo ($ai_auto_guest_review_opt['ignore'] ?? 0) ? 'vbo-context-menu-entry-success' : 'vbo-context-menu-entry-danger'; ?>',
1645 + separator: true,
1646 + action: (root, config) => {
1647 + // register callback
1648 + vbo_action_ignore_ai_autorg(<?php echo ($ai_auto_guest_review_opt['ignore'] ?? 0); ?>);
1649 + },
1650 + }
1651 + ],
1652 + });
1653 +
1654 + });
1655 + </script>
1656 + <?php
1657 + }
1658 + }
1659 +
1660 + if ($invoiced) {
1661 + foreach ($invoice_details as $invoice_detail) {
1662 + ?>
1663 + <div class="vbo-bookingdet-detcont-label vbo-bookingdet-detcont-label-invoice">
1664 + <span class="label label-success">
1665 + <span><?php echo $invoice_detail['label'] ?? JText::translate('VBOCOLORTAGRULEINVONE'); ?></span>
1666 + <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>
1667 + </span>
1668 + </div>
1669 + <?php
1670 + }
1671 + }
1672 + if ($this->vcm_review) {
1673 + ?>
1674 + <div class="vbo-bookingdet-detcont-label vbo-bookingdet-detcont-label-review">
1675 + <span class="label label-warning" onclick="VBOCore.handleDisplayWidgetNotification({widget_id: 'guest_reviews'}, {review_id: '<?php echo $this->vcm_review['id']; ?>'});">
1676 + <a href="javascript: void(0);" style="color: #fff;"><i class="vboicn-star-full"></i> <?php echo JText::translate('VBOSEEGUESTREVIEW'); ?></a>
1677 + </span>
1678 + </div>
1679 + <?php
1680 + // check if a notification was clicked
1681 + if (VikRequest::getString('notif_action', '', 'request') == 'see_guest_review') {
1682 + $vcm_review_link = VBOFactory::getPlatform()->getUri()->admin('index.php?option=com_vikchannelmanager&task=reviews&revid=' . $this->vcm_review['id'], false);
1683 + $vcm_review_id = $this->vcm_review['id'];
1684 + JFactory::getDocument()->addScriptDeclaration(
1685 +<<<JS
1686 +jQuery(function() {
1687 + setTimeout(() => {
1688 + // document.location.href = '$vcm_review_link';
1689 + VBOCore.handleDisplayWidgetNotification({widget_id: 'guest_reviews'}, {review_id: '$vcm_review_id'});
1690 + }, 200);
1691 +});
1692 +JS
1693 + );
1694 + }
1695 + }
1696 + ?>
1697 +
1698 + <!-- Define role to detect the supported hook -->
1699 + <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderSidebar","key":"invoice","type":"field"} -->
1700 +
1701 + <?php
1702 + if (isset($bookingSidebarForms['invoice'])) {
1703 + echo $bookingSidebarForms['invoice'];
1704 + }
1705 + ?>
1706 +
1707 + </div>
1708 + <?php
1709 + }
1710 + if (!$printreceipt && $row['closure'] < 1) {
1711 + ?>
1712 + <div class="vbo-bookingdet-detcont vbo-hidein-print">
1713 + <div class="vbo-bookingdet-lblcont">
1714 + <label for="custmail"><?php echo JText::translate('VBCUSTEMAIL'); ?></label>
1715 + </div>
1716 + <div class="vbo-bookingdet-inpwrap">
1717 + <div class="vbo-bookingdet-inpcont">
1718 + <input type="text" name="custmail" id="custmail" value="<?php echo $this->escape($row['custmail']); ?>" size="25" onkeyup="vboKeyupEmail(event);"/>
1719 + <div class="vbo-bookingdet-btncont vbo-bookingdet-save-email" style="display: none;">
1720 + <button type="button" class="btn btn-success" onclick="document.adminForm.submit();"><?php VikBookingIcons::e('save'); ?> <?php echo JText::translate('VBSAVE'); ?></button>
1721 + </div>
1722 + </div>
1723 + <?php if (!empty($row['custmail'])) : ?>
1724 + <div class="vbo-bookingdet-btncont">
1725 + <button type="button" class="btn vbo-config-btn" onclick="vboDisplaySendEmail();" style="vertical-align: top;"><?php VikBookingIcons::e('envelope'); ?> <?php echo JText::translate('VBSENDEMAILACTION'); ?></button>
1726 + </div>
1727 + <?php endif; ?>
1728 + </div>
1729 +
1730 + <!-- Define role to detect the supported hook -->
1731 + <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderSidebar","key":"email","type":"field"} -->
1732 +
1733 + <?php
1734 + if (isset($bookingSidebarForms['email'])) {
1735 + echo $bookingSidebarForms['email'];
1736 + }
1737 + ?>
1738 +
1739 + </div>
1740 + <div class="vbo-bookingdet-detcont vbo-hidein-print">
1741 + <div class="vbo-bookingdet-lblcont">
1742 + <label for="custphone"><?php echo JText::translate('VBCUSTOMERPHONE'); ?></label>
1743 + </div>
1744 + <div class="vbo-bookingdet-inpwrap">
1745 + <div class="vbo-bookingdet-inpcont">
1746 + <?php echo $vbo_app->printPhoneInputField(array('name' => 'custphone', 'id' => 'custphone', 'value' => $this->escape($row['phone'])), array('nationalMode' => false, 'fullNumberOnBlur' => true)); ?>
1747 + </div>
1748 + <?php
1749 + if (!empty($row['phone'])) {
1750 + if ($messagingAccountConfigurations) {
1751 + // send a message to the guest phone number through the messaging API account(s) configured
1752 + ?>
1753 + <div class="vbo-bookingdet-btncont">
1754 + <button type="button" class="btn vbo-config-btn vbo-bookingdet-send-tplmessage-btn" style="vertical-align: top;"><?php VikBookingIcons::e('paper-plane'); ?> <?php echo JText::translate('VBO_SEND_MESSAGE'); ?></button>
1755 + </div>
1756 + <?php
1757 + } else {
1758 + // fallback onto SMS
1759 + ?>
1760 + <div class="vbo-bookingdet-btncont">
1761 + <button type="button" class="btn vbo-config-btn" onclick="vboDisplaySendSMS();" style="vertical-align: top;"><?php VikBookingIcons::e('comment-dots'); ?> <?php echo JText::translate('VBSENDSMSACTION'); ?></button>
1762 + </div>
1763 + <?php
1764 + }
1765 + }
1766 + ?>
1767 + </div>
1768 +
1769 + <!-- Define role to detect the supported hook -->
1770 + <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderSidebar","key":"phone","type":"field"} -->
1771 +
1772 + <?php
1773 + if (isset($bookingSidebarForms['phone'])) {
1774 + echo $bookingSidebarForms['phone'];
1775 + }
1776 + ?>
1777 +
1778 + </div>
1779 + <?php
1780 + if ($phoneAlias = $registry->getAliasPhoneNumber()) {
1781 + ?>
1782 + <div class="vbo-bookingdet-detcont vbo-hidein-print">
1783 + <div class="vbo-bookingdet-lblcont">
1784 + <label for="phone_alias"><?php VikBookingIcons::e('user-shield'); ?> <?php echo JText::translate('VBO_PHONE_ALIAS'); ?></label>
1785 + </div>
1786 + <div class="vbo-bookingdet-inpwrap">
1787 + <div class="vbo-bookingdet-inpcont">
1788 + <input type="text" id="phone_alias" value="<?php echo $this->escape($phoneAlias); ?>" readonly />
1789 + </div>
1790 + <span class="vbo-param-setting-comment"><?php echo JText::translate('VBO_PHONE_ALIAS_HELP'); ?></span>
1791 + </div>
1792 +
1793 + <!-- Define role to detect the supported hook -->
1794 + <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderSidebar","key":"phone_alias","type":"field"} -->
1795 +
1796 + <?php
1797 + if (isset($bookingSidebarForms['phone_alias'])) {
1798 + echo $bookingSidebarForms['phone_alias'];
1799 + }
1800 + ?>
1801 +
1802 + </div>
1803 + <?php
1804 + }
1805 + ?>
1806 +
1807 + <!-- Define role to detect the supported hook -->
1808 + <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderSidebar","type":"fieldset"} -->
1809 +
1810 + <?php
1811 + foreach ($bookingSidebarForms as $legend => $form) {
1812 + if (in_array($legend, ['userdetails', 'invoice', 'email', 'phone'])) {
1813 + // skip default forms
1814 + continue;
1815 + }
1816 + ?>
1817 + <div class="vbo-bookingdet-detcont vbo-hidein-print">
1818 + <h3><?php echo JText::translate($legend); ?></h3>
1819 +
1820 + <?php echo $form; ?>
1821 + </div>
1822 + <?php
1823 + }
1824 + ?>
1825 +
1826 + <?php
1827 + }
1828 + ?>
1829 + </div>
1830 +
1831 + <?php
1832 + $all_id_prices = array();
1833 + $used_indexes_map = array();
1834 + ?>
1835 + <div class="vbo-bookingdet-summary">
1836 + <div class="table-responsive">
1837 + <table class="table">
1838 + <?php
1839 + // room stay dates in case of split stay (or modified room nights)
1840 + $room_stay_dates = [];
1841 + $room_stay_records = [];
1842 + if ($row['split_stay']) {
1843 + if ($row['status'] == 'confirmed') {
1844 + $room_stay_dates = $av_helper->loadSplitStayBusyRecords($row['id']);
1845 + } else {
1846 + $room_stay_dates = VBOFactory::getConfig()->getArray('split_stay_' . $row['id'], []);
1847 + }
1848 + } elseif (!$row['split_stay'] && $row['roomsnum'] > 1 && $row['days'] > 1 && $row['status'] == 'confirmed') {
1849 + // load the occupied stay dates for each room in case they were modified
1850 + $room_stay_records = $av_helper->loadSplitStayBusyRecords($row['id']);
1851 + }
1852 +
1853 + // parse all rooms booked
1854 + foreach ($rooms as $ind => $or) {
1855 + $num = $ind + 1;
1856 + $room_icon = $row['split_stay'] && $ind > 0 ? 'random' : 'bed';
1857 + $room_stay_nights = $row['days'];
1858 + ?>
1859 + <tr class="vbo-bookingdet-summary-room">
1860 + <td class="vbo-bookingdet-summary-room-firstcell">
1861 + <div class="vbo-bookingdet-summary-room-wrap">
1862 + <div class="vbo-bookingdet-summary-roomnum"><?php VikBookingIcons::e($room_icon); ?> <?php echo JText::translate('VBEDITORDERTHREE').' '.$num; ?></div>
1863 + <?php
1864 + // Room Specific Unit
1865 + if ((!$row['closure'] || ($row['closure'] && count($rooms) === 1) && !empty($or['roomindex'])) && $row['status'] == "confirmed" && !empty($or['params'])) {
1866 + $room_params = json_decode($or['params'], true);
1867 + $arr_features = array();
1868 + $unavailable_indexes = VikBooking::getRoomUnitNumsUnavailable($row, $or['idroom']);
1869 + if (is_array($room_params) && array_key_exists('features', $room_params) && !empty($room_params['features'])) {
1870 + foreach ($room_params['features'] as $rind => $rfeatures) {
1871 + if (in_array($rind, $unavailable_indexes) || (isset($used_indexes_map[$or['idroom']]) && in_array($rind, $used_indexes_map[$or['idroom']]))) {
1872 + continue;
1873 + }
1874 + foreach ($rfeatures as $fname => $fval) {
1875 + if (strlen($fval)) {
1876 + $arr_features[$rind] = '#'.$rind.' - '.JText::translate($fname).': '.$fval;
1877 + break;
1878 + }
1879 + }
1880 + }
1881 + }
1882 + if ($arr_features) {
1883 + // $or['id'] equals to the ID of each matching record in _ordersrooms
1884 + ?>
1885 + <div class="vbo-bookingdet-summary-roomnum-chunit">
1886 + <?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']] : ''); ?>
1887 + </div>
1888 + <?php
1889 + if (!empty($or['idroom']) && !empty($or['roomindex'])) {
1890 + if (!array_key_exists($or['idroom'], $used_indexes_map)) {
1891 + $used_indexes_map[$or['idroom']] = array();
1892 + }
1893 + $used_indexes_map[$or['idroom']][] = $or['roomindex'];
1894 + }
1895 + }
1896 + }
1897 + //
1898 + ?>
1899 + </div>
1900 + <div class="vbo-bookingdet-summary-roomguests">
1901 + <?php VikBookingIcons::e('male'); ?>
1902 + <div class="vbo-bookingdet-summary-roomadults">
1903 + <span><?php echo JText::translate('VBEDITORDERADULTS'); ?>:</span> <?php echo $arrpeople[$num]['adults']; ?>
1904 + </div>
1905 + <?php
1906 + if ($arrpeople[$num]['children'] > 0) {
1907 + $age_str = '';
1908 + if (!empty($arrpeople[$num]['children_age'])) {
1909 + $json_child = json_decode($arrpeople[$num]['children_age'], true);
1910 + if (is_array($json_child) && isset($json_child['age']) && is_array($json_child['age']) && $json_child['age']) {
1911 + $age_str = ' '.JText::sprintf('VBORDERCHILDAGES', implode(', ', $json_child['age']));
1912 + }
1913 + }
1914 + ?>
1915 + <div class="vbo-bookingdet-summary-roomchildren">
1916 + <span><?php echo JText::translate('VBEDITORDERCHILDREN'); ?>:</span> <?php echo $arrpeople[$num]['children'].$age_str; ?>
1917 + </div>
1918 + <?php
1919 + }
1920 + if ($arrpeople[$num]['pets'] > 0) {
1921 + ?>
1922 + <div class="vbo-bookingdet-summary-roompets">
1923 + <span><?php VikBookingIcons::e('dog'); ?> <?php echo JText::translate('VBO_PETS'); ?>:</span> <?php echo $arrpeople[$num]['pets']; ?>
1924 + </div>
1925 + <?php
1926 + }
1927 + ?>
1928 + </div>
1929 + <?php
1930 + if (!empty($arrpeople[$num]['t_first_name'])) {
1931 + ?>
1932 + <div class="vbo-bookingdet-summary-guestname">
1933 + <span><?php echo $arrpeople[$num]['t_first_name'].' '.$arrpeople[$num]['t_last_name']; ?></span>
1934 + </div>
1935 + <?php
1936 + }
1937 + ?>
1938 + </td>
1939 + <td>
1940 + <div class="vbo-bookingdet-summary-roomname"><?php echo $or['name']; ?></div>
1941 + <div class="vbo-bookingdet-summary-roomrate">
1942 + <?php
1943 + $active_rplan_id = 0;
1944 + if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
1945 + if (!empty($or['pkg_name'])) {
1946 + //package
1947 + echo $or['pkg_name'];
1948 + } else {
1949 + //custom cost can have an OTA Rate Plan name
1950 + if (!empty($or['otarplan'])) {
1951 + echo ucwords($or['otarplan']);
1952 + } else {
1953 + echo JText::translate('VBOROOMCUSTRATEPLAN');
1954 + }
1955 + }
1956 + } elseif (!empty($tars[$num]) && !empty($tars[$num][0]['idprice'])) {
1957 + $active_rplan_id = $tars[$num][0]['idprice'];
1958 + $all_id_prices[] = $tars[$num][0]['idprice'];
1959 + echo VikBooking::getPriceName($tars[$num][0]['idprice']);
1960 + if (!empty($tars[$num][0]['attrdata'])) {
1961 + ?>
1962 + <div>
1963 + <?php echo VikBooking::getPriceAttr($tars[$num][0]['idprice']).": ".$tars[$num][0]['attrdata']; ?>
1964 + </div>
1965 + <?php
1966 + }
1967 + } elseif (!empty($or['otarplan'])) {
1968 + echo ucwords($or['otarplan']);
1969 + } elseif ($row['closure'] < 1) {
1970 + echo JText::translate('VBOROOMNORATE');
1971 + }
1972 + ?>
1973 + </div>
1974 + <?php
1975 + // meals included in the room rate
1976 + if (!empty($or['meals'])) {
1977 + // display included meals defined at room-reservation record
1978 + $included_meals = VBOMealplanManager::getInstance()->roomRateIncludedMeals($or);
1979 + } else {
1980 + // fetch default included meals in the selected rate plan
1981 + $included_meals = $active_rplan_id ? VBOMealplanManager::getInstance()->ratePlanIncludedMeals($active_rplan_id) : [];
1982 + }
1983 + if (!$included_meals && empty($or['meals']) && !empty($row['idorderota']) && !empty($row['channel']) && !empty($row['custdata'])) {
1984 + // attempt to fetch the included meal plans from the raw customer data or OTA reservation and room
1985 + $included_meals = VBOMealplanManager::getInstance()->otaDataIncludedMeals($row, $or);
1986 + }
1987 + if ($included_meals) {
1988 + ?>
1989 + <div class="vbo-bookingdet-summary-roomrate vbo-bookingdet-summary-roommeals vbo-wider-badges-wrap">
1990 + <?php
1991 + foreach ($included_meals as $included_meal) {
1992 + ?>
1993 + <span class="badge badge-info"><?php echo $included_meal; ?></span>
1994 + <?php
1995 + }
1996 + ?>
1997 + </div>
1998 + <?php
1999 + }
2000 +
2001 + if ($row['split_stay'] && $room_stay_dates && isset($room_stay_dates[$ind]) && $room_stay_dates[$ind]['idroom'] == $or['idroom']) {
2002 + // print split stay information for this room
2003 + $room_stay_checkin = !empty($room_stay_dates[$ind]['checkin_ts']) ? $room_stay_dates[$ind]['checkin_ts'] : $room_stay_dates[$ind]['checkin'];
2004 + $room_stay_checkout = !empty($room_stay_dates[$ind]['checkout_ts']) ? $room_stay_dates[$ind]['checkout_ts'] : $room_stay_dates[$ind]['checkout'];
2005 + $room_stay_nights = $av_helper->countNightsOfStay($room_stay_checkin, $room_stay_checkout);
2006 + ?>
2007 + <div class="vbo-cal-splitstay-details vbo-bookdet-splitstay-details">
2008 + <div class="vbo-cal-splitstay-dates">
2009 + <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>
2010 + <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>
2011 + <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>
2012 + </div>
2013 + </div>
2014 + <?php
2015 + } elseif (!$row['split_stay'] && $room_stay_records && isset($room_stay_records[$ind]) && $room_stay_records[$ind]['idroom'] == $or['idroom']) {
2016 + // print modified stay dates information for this room
2017 + $room_stay_checkin = $room_stay_records[$ind]['checkin'];
2018 + $room_stay_checkout = $room_stay_records[$ind]['checkout'];
2019 + $room_stay_nights = $av_helper->countNightsOfStay($room_stay_checkin, $room_stay_checkout);
2020 + if ($room_stay_checkin != $row['checkin'] || $room_stay_checkout != $row['checkout']) {
2021 + ?>
2022 + <div class="vbo-cal-splitstay-details vbo-bookdet-splitstay-details vbo-bookdet-roomdatesmod-details">
2023 + <div class="vbo-cal-splitstay-dates">
2024 + <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>
2025 + <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>
2026 + <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>
2027 + </div>
2028 + </div>
2029 + <?php
2030 + }
2031 + }
2032 + ?>
2033 + </td>
2034 + <td>
2035 + <div class="vbo-bookingdet-summary-price">
2036 + <?php
2037 + if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
2038 + echo $currencyname.' '.VikBooking::numberFormat($or['cust_cost']);
2039 + } elseif (!empty($tars[$num]) && !empty($tars[$num][0]['idprice'])) {
2040 + $display_rate = !empty($or['room_cost']) ? $or['room_cost'] : $tars[$num][0]['cost'];
2041 + echo $currencyname.' '.VikBooking::numberFormat(($after_tax ? VikBooking::sayCostPlusIva($display_rate, $tars[$num][0]['idprice']) : $display_rate));
2042 + }
2043 + ?>
2044 + </div>
2045 + </td>
2046 + </tr>
2047 + <?php
2048 + //Options
2049 + if (!empty($or['optionals'])) {
2050 + $stepo = explode(";", $or['optionals']);
2051 + $counter = 0;
2052 + foreach ($stepo as $roptkey => $oo) {
2053 + if (empty($oo)) {
2054 + continue;
2055 + }
2056 + $stept = explode(":", $oo);
2057 + $q = "SELECT * FROM `#__vikbooking_optionals` WHERE `id`=".(int)$stept[0].";";
2058 + $dbo->setQuery($q);
2059 + $actopt = $dbo->loadAssocList();
2060 + if (!$actopt) {
2061 + continue;
2062 + }
2063 +
2064 + // option params
2065 + $opt_params = !empty($actopt[0]['oparams']) ? json_decode($actopt[0]['oparams'], true) : [];
2066 + $opt_params = is_array($opt_params) ? $opt_params : [];
2067 + if ($opt_params['damagedep'] ?? 0) {
2068 + // turn flag on
2069 + $booking_has_damage_dep = 1;
2070 + }
2071 +
2072 + $counter++;
2073 + $chvar = '';
2074 + if (!empty($actopt[0]['ageintervals']) && $or['children'] > 0 && strstr($stept[1], '-') != false) {
2075 + $optagenames = VikBooking::getOptionIntervalsAges($actopt[0]['ageintervals']);
2076 + $optagepcent = VikBooking::getOptionIntervalsPercentage($actopt[0]['ageintervals']);
2077 + $optageovrct = VikBooking::getOptionIntervalChildOverrides($actopt[0], $or['adults'], $or['children']);
2078 + $child_num = VikBooking::getRoomOptionChildNumber($or['optionals'], $actopt[0]['id'], $roptkey, $or['children']);
2079 + $optagecosts = VikBooking::getOptionIntervalsCosts(isset($optageovrct['ageintervals_child' . ($child_num + 1)]) ? $optageovrct['ageintervals_child' . ($child_num + 1)] : $actopt[0]['ageintervals']);
2080 + $agestept = explode('-', $stept[1]);
2081 + $stept[1] = $agestept[0];
2082 + $chvar = $agestept[1];
2083 + if (array_key_exists(($chvar - 1), $optagepcent) && $optagepcent[($chvar - 1)] == 1) {
2084 + //percentage value of the adults tariff
2085 + if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
2086 + $optagecosts[($chvar - 1)] = $or['cust_cost'] * $optagecosts[($chvar - 1)] / 100;
2087 + } else {
2088 + $display_rate = !empty($or['room_cost']) ? $or['room_cost'] : $tars[$num][0]['cost'];
2089 + $optagecosts[($chvar - 1)] = $display_rate * $optagecosts[($chvar - 1)] / 100;
2090 + }
2091 + } elseif (array_key_exists(($chvar - 1), $optagepcent) && $optagepcent[($chvar - 1)] == 2) {
2092 + //VBO 1.10 - percentage value of room base cost
2093 + if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
2094 + $optagecosts[($chvar - 1)] = $or['cust_cost'] * $optagecosts[($chvar - 1)] / 100;
2095 + } else {
2096 + $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']);
2097 + $optagecosts[($chvar - 1)] = $display_rate * $optagecosts[($chvar - 1)] / 100;
2098 + }
2099 + }
2100 + if (!isset($optagenames[($chvar - 1)])) {
2101 + $optagenames[($chvar - 1)] = '';
2102 + }
2103 + if (!isset($optagecosts[($chvar - 1)])) {
2104 + $optagecosts[($chvar - 1)] = 0;
2105 + }
2106 + $actopt[0]['chageintv'] = $chvar;
2107 + $actopt[0]['name'] .= ' ('.$optagenames[($chvar - 1)].')';
2108 + $realcost = (intval($actopt[0]['perday']) == 1 ? (floatval($optagecosts[($chvar - 1)]) * $room_stay_nights * $stept[1]) : (floatval($optagecosts[($chvar - 1)]) * $stept[1]));
2109 + } elseif (is_numeric($stept[1])) {
2110 + // VBO 1.11 - options percentage cost of the room total fee
2111 + if ($is_package === true || (!empty($or['cust_cost']) && $or['cust_cost'] > 0.00)) {
2112 + $deftar_basecosts = $or['cust_cost'];
2113 + } else {
2114 + $use_def_tar = isset($tars[$num]) && isset($tars[$num][0]) ? $tars[$num][0]['cost'] : 0;
2115 + $deftar_basecosts = !empty($or['room_cost']) ? $or['room_cost'] : $use_def_tar;
2116 + }
2117 + $actopt[0]['cost'] = (int)$actopt[0]['pcentroom'] ? ($deftar_basecosts * $actopt[0]['cost'] / 100) : $actopt[0]['cost'];
2118 + //
2119 + $realcost = (intval($actopt[0]['perday']) == 1 ? ($actopt[0]['cost'] * $room_stay_nights * $stept[1]) : ($actopt[0]['cost'] * $stept[1]));
2120 + } else {
2121 + $realcost = 0;
2122 + }
2123 + if ($actopt[0]['maxprice'] > 0 && $realcost > $actopt[0]['maxprice']) {
2124 + $realcost = $actopt[0]['maxprice'];
2125 + if (intval($actopt[0]['hmany']) == 1 && intval($stept[1]) > 1) {
2126 + $realcost = $actopt[0]['maxprice'] * $stept[1];
2127 + }
2128 + }
2129 + $realcost = $actopt[0]['perperson'] == 1 ? ($realcost * $arrpeople[$num]['adults']) : $realcost;
2130 +
2131 + /**
2132 + * Trigger event to allow third party plugins to apply a custom calculation for the option/extra fee or tax.
2133 + *
2134 + * @since 1.17.7 (J) - 1.7.7 (WP)
2135 + */
2136 + $custom_calculation = VBOFactory::getPlatform()->getDispatcher()->filter('onCalculateBookingOptionFeeCost', [$realcost, &$actopt[0], $row, $or]);
2137 + if ($custom_calculation) {
2138 + $realcost = (float) $custom_calculation[0];
2139 + }
2140 +
2141 + $tmpopr = VikBooking::sayOptionalsPlusIva($realcost, $actopt[0]['idiva']);
2142 + ?>
2143 + <tr class="vbo-bookingdet-summary-options">
2144 + <td class="vbo-bookingdet-summary-options-title"><?php echo $counter == 1 ? JText::translate('VBEDITORDEREIGHT') : '&nbsp;'; ?></td>
2145 + <td>
2146 + <span class="vbo-bookingdet-summary-lbl"><?php echo ($stept[1] > 1 ? $stept[1]." " : "").$actopt[0]['name']; ?></span>
2147 + </td>
2148 + <td>
2149 + <span class="vbo-bookingdet-summary-cost"><?php echo $currencyname." ".VikBooking::numberFormat(($after_tax ? $tmpopr : $realcost)); ?></span>
2150 + </td>
2151 + </tr>
2152 + <?php
2153 + }
2154 + }
2155 + //Custom extra costs
2156 + if (!empty($or['extracosts'])) {
2157 + $counter = 0;
2158 + $cur_extra_costs = json_decode($or['extracosts'], true);
2159 + foreach ($cur_extra_costs as $eck => $ecv) {
2160 + $counter++;
2161 + $ecv['idtax'] = isset($ecv['idtax']) ? $ecv['idtax'] : 0;
2162 + ?>
2163 + <tr class="vbo-bookingdet-summary-custcosts">
2164 + <td class="vbo-bookingdet-summary-custcosts-title"><?php echo $counter == 1 ? JText::translate('VBPEDITBUSYEXTRACOSTS') : '&nbsp;'; ?></td>
2165 + <td>
2166 + <?php
2167 + if (!empty($ecv['type'])) {
2168 + ?>
2169 + <span class="vbo-tooltip vbo-tooltip-top" data-tooltiptext="<?php echo JHtml::fetch('esc_attr', JText::translate('VBPSHOWSEASONSTHREE') . ': ' . $ecv['type']); ?>">
2170 + <span class="vbo-bookingdet-summary-lbl"><?php echo $ecv['name']; ?></span>
2171 + </span>
2172 + <?php
2173 + } else {
2174 + ?>
2175 + <span class="vbo-bookingdet-summary-lbl"><?php echo $ecv['name']; ?></span>
2176 + <?php
2177 + }
2178 + ?>
2179 + </td>
2180 + <td>
2181 + <span class="vbo-bookingdet-summary-cost"><?php echo $currencyname." ".VikBooking::numberFormat(($after_tax ? VikBooking::sayOptionalsPlusIva($ecv['cost'], $ecv['idtax']) : $ecv['cost'])); ?></span>
2182 + </td>
2183 + </tr>
2184 + <?php
2185 + }
2186 + }
2187 + }
2188 + //vikbooking 1.1 coupon
2189 + if (strlen((string)$row['coupon']) > 0) {
2190 + $expcoupon = explode(";", $row['coupon']);
2191 + ?>
2192 + <tr class="vbo-bookingdet-summary-coupon">
2193 + <td><?php echo JText::translate('VBCOUPON'); ?></td>
2194 + <td>
2195 + <span class="vbo-bookingdet-summary-lbl"><?php echo $expcoupon[2]; ?></span>
2196 + </td>
2197 + <td>
2198 + <span class="vbo-bookingdet-summary-cost">- <?php echo $currencyname; ?> <?php echo VikBooking::numberFormat($expcoupon[1]); ?></span>
2199 + </td>
2200 + </tr>
2201 + <?php
2202 + }
2203 + if ($row['refund'] > 0) {
2204 + ?>
2205 + <tr class="vbo-bookingdet-summary-totpaid vbo-bookingdet-summary-totrefunded">
2206 + <td>
2207 + <strong><?php echo JText::translate('VBOBOOKHISTORYTRF'); ?></strong>
2208 + </td>
2209 + <td>
2210 + <span class="vbo-amount-refunded-lbl"><?php echo JText::translate('VBO_AMOUNT_REFUNDED'); ?></span>
2211 + </td>
2212 + <td>
2213 + <div id="vbo-amountrefunded-cont">
2214 + <span id="vbo-amountrefunded-current"><?php echo $currencyname.' '.VikBooking::numberFormat($row['refund']); ?></span>
2215 + <span id="vbo-amountrefunded-edit" style="margin-left: 5px; cursor: pointer;"><?php VikBookingIcons::e('edit'); ?></span>
2216 + </div>
2217 + <div id="vbo-amountrefunded-modcont" style="display: none;">
2218 + <span id="vbo-amountrefunded-cancedit" style="margin-right: 5px; cursor: pointer;"><?php VikBookingIcons::e('times'); ?></span>
2219 + <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>
2220 + <span id="vbo-amountrefunded-save"><button type="submit" class="btn btn-success"><?php echo JText::translate('VBAPPLYDISCOUNTSAVE'); ?></button></span>
2221 + </div>
2222 + </td>
2223 + </tr>
2224 + <?php
2225 + }
2226 + //Reservation Total
2227 + //Taxes Breakdown (only if tot_taxes is greater than 0)
2228 + $tax_breakdown = array();
2229 + $base_aliq = 0;
2230 + if ($all_id_prices && $row['tot_taxes'] > 0) {
2231 + //only last type of price assuming that the tax breakdown is equivalent in case of different rates
2232 + $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;";
2233 + $dbo->setQuery($q);
2234 + $breakdown_info = $dbo->loadAssoc();
2235 + if ($breakdown_info) {
2236 + if (!empty($breakdown_info['breakdown']) && !empty($breakdown_info['aliq'])) {
2237 + $tax_breakdown = json_decode($breakdown_info['breakdown'], true);
2238 + $tax_breakdown = is_array($tax_breakdown) && $tax_breakdown ? $tax_breakdown : array();
2239 + $base_aliq = $breakdown_info['aliq'];
2240 + }
2241 + }
2242 + }
2243 + //
2244 + if ($printreceipt && $row['tot_taxes'] > 0) {
2245 + // only when printing the receipt we display an additional row for the total amount of tax
2246 + ?>
2247 + <tr class="vbo-bookingdet-summary-total vbo-bookingdet-summary-totaltax">
2248 + <td>
2249 +
2250 + </td>
2251 + <td>
2252 + <span class="vbo-bookingdet-summary-lbl"><?php echo JText::translate('VBTOTALVAT'); ?></span>
2253 + </td>
2254 + <td>
2255 + <span class="vbo-bookingdet-summary-cost"><?php echo $currencyname; ?> <?php echo VikBooking::numberFormat($row['tot_taxes']); ?></span>
2256 + </td>
2257 + </tr>
2258 + <?php
2259 + }
2260 + ?>
2261 + <tr class="vbo-bookingdet-summary-total">
2262 + <td>
2263 + <?php
2264 + if (!$printreceipt) {
2265 + ?>
2266 + <span class="vbapplydiscsp" onclick="toggleDiscount(this);">
2267 + <i class="<?php echo VikBookingIcons::i('chevron-down'); ?>" title="<?php echo htmlspecialchars(JText::translate('VBAPPLYDISCOUNT')); ?>"></i>
2268 + </span>
2269 + <?php
2270 + }
2271 + ?>
2272 + </td>
2273 + <td>
2274 + <span class="vbo-bookingdet-summary-lbl"><?php echo JText::translate('VBEDITORDERNINE'); ?></span>
2275 +
2276 + <div class="vbdiscenter" id="vbdiscenter" style="display: none;">
2277 + <div class="vbdiscenter-entry">
2278 + <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>
2279 + </div>
2280 + <?php
2281 + if ($tax_breakdown) {
2282 + foreach ($tax_breakdown as $tbkk => $tbkv) {
2283 + $tax_break_cost = $row['tot_taxes'] * floatval($tbkv['aliq']) / $base_aliq;
2284 + ?>
2285 + <div class="vbdiscenter-entry vbdiscenter-entry-breakdown">
2286 + <span class="vbdiscenter-label"><?php echo $tbkv['name']; ?>:</span><span class="vbdiscenter-value"><?php echo $currencyname; ?> <?php echo VikBooking::numberFormat($tax_break_cost); ?></span>
2287 + </div>
2288 + <?php
2289 + }
2290 + }
2291 + ?>
2292 + <div class="vbdiscenter-entry">
2293 + <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>
2294 + </div>
2295 + <div class="vbdiscenter-entry">
2296 + <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>
2297 + </div>
2298 + <div class="vbdiscenter-entry">
2299 + <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>
2300 + </div>
2301 + <?php
2302 + if ($booking_has_damage_dep) {
2303 + // allow to overwrite (or see) the amount of damage deposit
2304 + ?>
2305 + <div class="vbdiscenter-entry">
2306 + <span class="vbdiscenter-label"><?php echo JText::translate('VBO_DAMAGE_DEPOSIT'); ?>:</span><span class="vbdiscenter-value"><?php echo $currencyname; ?> <input type="number" step="any" name="tot_damage_dep" value="<?php echo $row['tot_damage_dep']; ?>" min="0" size="4"/></span>
2307 + </div>
2308 + <?php
2309 + }
2310 + ?>
2311 + <div class="vbdiscenter-entry">
2312 + <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>
2313 + </div>
2314 + <div class="vbdiscenter-entrycentered">
2315 + <button type="submit" class="btn btn-success"><?php echo JText::translate('VBAPPLYDISCOUNTSAVE'); ?></button>
2316 + </div>
2317 + </div>
2318 + </td>
2319 + <td>
2320 + <span class="vbo-bookingdet-summary-cost"><?php echo (!empty($otacurrency) && $otacurrency != $currencyname ? '('.$otacurrency.') ' . $currencyname : $currencyname); ?> <?php echo VikBooking::numberFormat($row['total']); ?></span>
2321 + <?php
2322 + /**
2323 + * Display the information about the expected payout, if available and eligible.
2324 + *
2325 + * @since 1.18.4 (J) - 1.8.4 (WP)
2326 + */
2327 + if ($row['status'] == 'confirmed' && !empty($row['channel']) && !empty($row['idorderota']) && $row['checkout'] >= $current_ts && !empty($ota_type_data['expected_payout'])) {
2328 + ?>
2329 + <div class="vbo-bookingdet-exp-payout">
2330 + <span class="vbo-bookingdet-exp-payout-lbl"><?php echo JText::translate('VBO_EXPECTED_PAYOUT'); ?></span>
2331 + <span class="vbo-bookingdet-exp-payout-txt"><?php
2332 + echo VikBooking::formatCurrencyNumber(VikBooking::numberFormat($ota_type_data['expected_payout']), (!empty($otacurrency) && $otacurrency != $currencyname ? $otacurrency : $currencysymb));
2333 + ?></span>
2334 + </div>
2335 + <?php
2336 + }
2337 + ?>
2338 + </td>
2339 + </tr>
2340 + <?php
2341 + if ($row['total'] > 0 && !$row['closure']) {
2342 + $has_paid = ($row['totpaid'] > 0);
2343 + $diff_to_pay = $has_paid ? ($row['total'] - $row['totpaid']) : 0;
2344 + if ($diff_to_pay && !empty($row['idorderota']) && !empty($row['channel']) && round($row['cmms'], 2) == round($diff_to_pay, 2)) {
2345 + // the outstanding balance is equal to the OTA commissions amount
2346 + $diff_to_pay = 0;
2347 + }
2348 + if ($has_paid || $row['status'] != 'standby') {
2349 + ?>
2350 + <tr class="vbo-bookingdet-summary-totpaid">
2351 + <td>&nbsp;</td>
2352 + <td><?php echo JText::translate('VBAMOUNTPAID'); ?></td>
2353 + <td>
2354 + <div id="vbo-amountpaid-cont">
2355 + <span id="vbo-amountpaid-current"><?php echo $has_paid ? ($currencyname . ' ' . VikBooking::numberFormat($row['totpaid'])) : ''; ?></span>
2356 + <span id="vbo-amountpaid-edit" style="margin-left: 5px; cursor: pointer;"><?php VikBookingIcons::e('edit'); ?></span>
2357 + </div>
2358 + <div id="vbo-amountpaid-modcont" style="display: none;">
2359 + <span id="vbo-amountpaid-cancedit" style="margin-right: 5px; cursor: pointer;"><?php VikBookingIcons::e('times'); ?></span>
2360 + <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>
2361 + <?php
2362 + if ($payments) {
2363 + ?>
2364 + <span id="vbo-amountpaid-paymeth" style="margin: 0 5px; max-width: 160px;">
2365 + <select name="newamountpaymeth" style="margin: 0;">
2366 + <option value=""><?php echo JText::translate('VBPAYMENTMETHOD'); ?></option>
2367 + <?php
2368 + foreach ($payments as $pay) {
2369 + ?>
2370 + <option value="<?php echo JHtml::fetch('esc_attr', $pay['id'] . '_' . $pay['name']); ?>"><?php echo $pay['name']; ?></option>
2371 + <?php
2372 + }
2373 + ?>
2374 + </select>
2375 + </span>
2376 + <?php
2377 + }
2378 + ?>
2379 + <span id="vbo-amountpaid-save"><button type="submit" class="btn btn-success"><?php echo JText::translate('VBAPPLYDISCOUNTSAVE'); ?></button></span>
2380 + </div>
2381 + </td>
2382 + </tr>
2383 + <?php
2384 + }
2385 + if ($diff_to_pay > 1 && $row['status'] != 'cancelled') {
2386 + ?>
2387 + <tr class="vbo-bookingdet-summary-totpaid vbo-bookingdet-summary-totremaining">
2388 + <td>&nbsp;</td>
2389 + <td>
2390 + <div><?php echo JText::translate('VBTOTALREMAINING'); ?></div>
2391 + <?php
2392 + // enable second payment
2393 + if (!$printreceipt && $row['status'] == 'confirmed' && !($row['paymcount'] > 0) && VikBooking::multiplePayments() && is_array($payment) && !empty($payment['id'])) {
2394 + ?>
2395 + <div style="margin-top: 5px;">
2396 + <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>
2397 + </div>
2398 + <?php
2399 + }
2400 + ?>
2401 + </td>
2402 + <td><?php echo $currencyname . ' ' . VikBooking::numberFormat($diff_to_pay); ?></td>
2403 + </tr>
2404 + <?php
2405 + }
2406 + }
2407 + if (!$printreceipt && $row['status'] == 'confirmed' && VikBooking::multiplePayments() && is_array($payment) && !empty($payment['id']) && $row['checkout'] > strtotime('-10 days')) {
2408 + /**
2409 + * The amount payable can be modified by the admin.
2410 + *
2411 + * @since 1.14 (J) - 1.4.0 (WP)
2412 + */
2413 + ?>
2414 + <tr class="vbo-bookingdet-summary-totpaid vbo-bookingdet-summary-totpayable">
2415 + <td>&nbsp;</td>
2416 + <td>
2417 + <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>
2418 + </td>
2419 + <td>
2420 + <div id="vbo-amountpayable-cont">
2421 + <?php
2422 + if ($row['payable'] > 0) {
2423 + ?>
2424 + <span id="vbo-amountpayable-current"><?php echo $currencyname . ' ' . VikBooking::numberFormat($row['payable']); ?></span>
2425 + <?php
2426 + }
2427 + ?>
2428 + <span id="vbo-amountpayable-edit" style="margin-left: 5px; cursor: pointer;"><?php VikBookingIcons::e('edit'); ?></span>
2429 + </div>
2430 + <div id="vbo-amountpayable-modcont" style="display: none;">
2431 + <span id="vbo-amountpayable-cancedit" style="margin-right: 5px; cursor: pointer;"><?php VikBookingIcons::e('times'); ?></span>
2432 + <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>
2433 + <span id="vbo-amountpayable-save"><button type="submit" class="btn btn-success"><?php echo JText::translate('VBAPPLYDISCOUNTSAVE'); ?></button></span>
2434 + </div>
2435 + </td>
2436 + </tr>
2437 + <?php
2438 + }
2439 +
2440 + /**
2441 + * Cancellation fee for cancelled bookings after the deadline.
2442 + *
2443 + * @since 1.16.0 (J) - 1.6.0 (WP)
2444 + */
2445 + if ($row['status'] == 'cancelled' && !$row['closure'] && $row['total'] > 0) {
2446 + ?>
2447 + <tr class="vbo-bookingdet-summary-cancfee">
2448 + <td>&nbsp;</td>
2449 + <td><?php echo JText::translate('VBO_CANC_FEE'); ?></td>
2450 + <td>
2451 + <div id="vbo-cancfee-cont">
2452 + <span id="vbo-cancfee-current"><?php echo $currencyname.' '.VikBooking::numberFormat($row['canc_fee']); ?></span>
2453 + <span id="vbo-cancfee-edit" style="margin-left: 5px; cursor: pointer;"><?php VikBookingIcons::e('edit'); ?></span>
2454 + </div>
2455 + <div id="vbo-cancfee-modcont" style="display: none;">
2456 + <span id="vbo-cancfee-cancedit" style="margin-right: 5px; cursor: pointer;"><?php VikBookingIcons::e('times'); ?></span>
2457 + <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>
2458 + <span id="vbo-cancfee-save"><button type="submit" class="btn btn-success"><?php echo JText::translate('VBAPPLYDISCOUNTSAVE'); ?></button></span>
2459 + </div>
2460 + </td>
2461 + </tr>
2462 + <?php
2463 + }
2464 + ?>
2465 + </table>
2466 + </div>
2467 +
2468 + <!-- Define role to detect the supported hook -->
2469 + <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorder","type":"fieldset"} -->
2470 +
2471 + <?php
2472 + foreach ($bookingPanelForms as $legend => $form)
2473 + {
2474 + if (in_array($legend, ['buttons']))
2475 + {
2476 + // skip default forms
2477 + continue;
2478 + }
2479 + ?>
2480 + <div class="table-responsive">
2481 + <h3><?php echo JText::translate($legend); ?></h3>
2482 +
2483 + <?php echo $form; ?>
2484 + </div>
2485 + <?php
2486 + }
2487 + ?>
2488 +
2489 + </div>
2490 + </div>
2491 + <?php
2492 + if ($printreceipt) {
2493 + $receipt_notes = VikBooking::getReceiptNotes();
2494 + ?>
2495 + <div class="vbo-receipt-notes-container">
2496 + <div class="vbo-receipt-notes-inner">
2497 + <div class="vbo-receipt-notes-val vbo-showin-print" id="vbo-receipt-notes-val"><?php echo $receipt_notes; ?></div>
2498 + <div class="vbo-receipt-notes-tarea vbo-hidein-print">
2499 + <textarea id="vbo-receipt-notes" placeholder="<?php echo JText::translate('VBORECEIPTNOTESDEF'); ?>"><?php echo htmlspecialchars($receipt_notes); ?></textarea>
2500 + </div>
2501 + </div>
2502 + </div>
2503 + <?php
2504 + }
2505 + ?>
2506 + </div>
2507 +
2508 + <div class="vbo-bookingdet-tab-cont" id="vbo-tab-admin" style="display: none;">
2509 + <div class="vbo-bookingdet-innercontainer">
2510 + <div class="vbo-bookingdet-admindata">
2511 + <?php
2512 + if (!$row['closure']) {
2513 + ?>
2514 + <div class="vbo-bookingdet-admin-entry">
2515 + <label for="vbo-searchcust"><?php echo JText::translate($customer ? 'VBOASSIGNNEWCUST' : 'VBFILLCUSTFIELDS'); ?></label>
2516 + <span style="display: block;"><?php echo JText::translate('VBOSEARCHEXISTCUST'); ?></span>
2517 + <span class="vbo-eorder-assigncust" style="margin-bottom: 1px;">
2518 + <input type="text" id="vbo-searchcust" autocomplete="off" value="" placeholder="<?php echo JText::translate('VBOSEARCHCUSTBY'); ?>" size="30" style="margin-bottom: 0;" />
2519 + </span>
2520 + <span id="vbo-searchcust-loading">
2521 + <?php VikBookingIcons::e('hourglass-half'); ?>
2522 + </span>
2523 + <input type="hidden" name="newcustid" id="newcustid" value="" />
2524 + <div id="vbo-searchcust-res" style="position: absolute; background-color: #fff;"></div>
2525 + <span class="vbo-eorder-assignnewcust" style="display: block; margin-top: 10px;">
2526 + <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'); ?>">
2527 + <?php VikBookingIcons::e('user-circle'); ?>
2528 + <span><?php echo JText::translate('VBOCREATENEWCUST'); ?></span>
2529 + </a>
2530 + </span>
2531 +
2532 + <?php
2533 + if (isset($adminSidebarForms['customer']))
2534 + {
2535 + echo $adminSidebarForms['customer'];
2536 + }
2537 + ?>
2538 +
2539 + </div>
2540 + <?php
2541 + }
2542 + ?>
2543 + <div class="vbo-bookingdet-admin-entry">
2544 + <label for="newpayment"><?php echo JText::translate('VBPAYMENTMETHOD'); ?></label>
2545 + <?php
2546 + if (is_array($payment)) {
2547 + ?>
2548 + <span><?php echo $payment['name']; ?></span>
2549 + <?php
2550 + }
2551 + $chpayment = '';
2552 + if ($payments) {
2553 + $chpayment = '<div><select name="newpayment" id="newpayment" onchange="changePayment();"><option value="">- ' . JText::translate('VBCHANGEPAYLABEL') . ' -</option>';
2554 + foreach ($payments as $pay) {
2555 + $chpayment .= '<option value="' . $pay['id'] . '">' . (is_array($payment) && $payment['id'] == $pay['id'] ? '- ' : '') . $pay['name'] . '</option>';
2556 + }
2557 + $chpayment .= '</select></div>';
2558 + }
2559 + echo $chpayment;
2560 + ?>
2561 +
2562 + <!-- Define role to detect the supported hook -->
2563 + <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderAdministrationSidebar","key":"payment","type":"field"} -->
2564 +
2565 + <?php
2566 + if (isset($adminSidebarForms['payment']))
2567 + {
2568 + echo $adminSidebarForms['payment'];
2569 + }
2570 + ?>
2571 +
2572 + </div>
2573 + <?php
2574 + $tn = VikBooking::getTranslator();
2575 + $all_langs = $tn->getLanguagesList();
2576 + if (count($all_langs) > 1) {
2577 + ?>
2578 + <div class="vbo-bookingdet-admin-entry">
2579 + <label for="newlang"><?php echo JText::translate('VBOBOOKINGLANG'); ?></label>
2580 + <select name="newlang" id="newlang" onchange="document.adminForm.submit();">
2581 + <?php
2582 + foreach ($all_langs as $lk => $lv) {
2583 + ?>
2584 + <option value="<?php echo $lk; ?>"<?php echo $row['lang'] == $lk ? ' selected="selected"' : ''; ?>><?php echo isset($lv['nativeName']) ? $lv['nativeName'] : $lv['name']; ?></option>
2585 + <?php
2586 + }
2587 + ?>
2588 + </select>
2589 +
2590 + <!-- Define role to detect the supported hook -->
2591 + <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderAdministrationSidebar","key":"language","type":"field"} -->
2592 +
2593 + <?php
2594 + if (isset($adminSidebarForms['language']))
2595 + {
2596 + echo $adminSidebarForms['language'];
2597 + }
2598 + ?>
2599 + </div>
2600 + <?php
2601 + }
2602 + ?>
2603 +
2604 + <!-- Define role to detect the supported hook -->
2605 + <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderAdministrationSidebar","type":"fieldset"} -->
2606 +
2607 + <?php
2608 + foreach ($adminSidebarForms as $legend => $form)
2609 + {
2610 + if (in_array($legend, ['customer', 'payment', 'language']))
2611 + {
2612 + // skip default forms
2613 + continue;
2614 + }
2615 + ?>
2616 + <div class="vbo-bookingdet-admin-entry">
2617 + <h3><?php echo JText::translate($legend); ?></h3>
2618 +
2619 + <?php echo $form; ?>
2620 + </div>
2621 + <?php
2622 + }
2623 + ?>
2624 +
2625 + </div>
2626 + <div class="vbo-bookingdet-noteslogs">
2627 + <?php
2628 + $history = $history_obj->loadHistory();
2629 + ?>
2630 + <div class="vbo-bookingdet-noteslogs-btns">
2631 + <div class="vbo-bookingdet-noteslogs-btn vbo-bookingdet-noteslogs-btn-active" data-id="notes">
2632 + <a href="javascript: void(0);" id="vbo-trig-notes" onclick="javascript: vbToggleNotes(this);">
2633 + <?php VikBookingIcons::e('user-lock'); ?>
2634 + <span class="vbo-bookingdet-admintab-lbl"><?php echo JText::translate('VBADMINNOTESTOGGLE'); ?></span>
2635 + </a>
2636 + </div>
2637 + <?php
2638 + /**
2639 + * Initialize chat instance by getting the proper channel name
2640 + *
2641 + * @since 1.12
2642 + */
2643 + if (empty($row['channel'])) {
2644 + // front-end reservation chat handler
2645 + $chat_channel = 'vikbooking';
2646 + } else {
2647 + $channelparts = explode('_', $row['channel']);
2648 + // check if this is a meta search channel
2649 + $is_meta_search = false;
2650 + if (preg_match("/(customer).*[0-9]$/", $channelparts[0]) || !strcasecmp($channelparts[0], 'googlehotel') || !strcasecmp($channelparts[0], 'googlevr') || !strcasecmp($channelparts[0], 'trivago')) {
2651 + $is_meta_search = empty($row['idorderota']);
2652 + }
2653 + if ($is_meta_search) {
2654 + // customer of type sales channel should use front-end reservation chat handler
2655 + $chat_channel = 'vikbooking';
2656 + } else {
2657 + // let the getInstance method validate the channel chat handler
2658 + $chat_channel = $row['channel'];
2659 + }
2660 + }
2661 + $messaging = VikBooking::getVcmChatInstance($row['id'], $chat_channel);
2662 + //
2663 + if (!$printreceipt && !is_null($messaging)) {
2664 + ?>
2665 + <div class="vbo-bookingdet-noteslogs-btn" data-id="messaging">
2666 + <a name="messaging" href="javascript: void(0);" id="vbo-trig-messaging" onclick="javascript: vbToggleMessaging(this);">
2667 + <?php VikBookingIcons::e('comment-dots'); ?>
2668 + <span class="vbo-bookingdet-admintab-lbl"><?php echo JText::translate('VBO_GUEST_MESSAGING'); ?></span>
2669 + </a>
2670 + </div>
2671 + <?php
2672 + }
2673 +
2674 + /**
2675 + * Build up a tab to summarize the "takings" for this sole booking in case of relevant events.
2676 + *
2677 + * @since 1.16.9 (J) - 1.6.9 (WP)
2678 + */
2679 + $takings = [];
2680 + if ($history) {
2681 + // payment related events
2682 + $h_payment_group = $history_obj->getTypeGroups($group = 'GPM');
2683 +
2684 + // merge default types with 'PU' for the manually set "new amount paid" and with 'RU' (refunded amount updated)
2685 + $takings_events = array_unique(array_merge(($h_payment_group['types'] ?? []), ['PU', 'RU']));
2686 +
2687 + // load the relevant events with data
2688 + $takings = $history_obj->getEventsWithData($takings_events, null, false);
2689 +
2690 + if ($takings) {
2691 + ?>
2692 + <div class="vbo-bookingdet-noteslogs-btn pro-feature" data-id="takings">
2693 + <a href="javascript: void(0);" id="vbo-trig-bookhistory" onclick="javascript: vbToggleDynamicPanel(this, '#vboextrapanel-takings');">
2694 + <?php VikBookingIcons::e('wallet'); ?>
2695 + <span class="vbo-bookingdet-admintab-lbl"><?php echo JText::translate('VBO_TAKINGS'); ?></span>
2696 + </a>
2697 + </div>
2698 + <?php
2699 + }
2700 + }
2701 +
2702 + if ($history) {
2703 + ?>
2704 + <div class="vbo-bookingdet-noteslogs-btn" data-id="history">
2705 + <a href="javascript: void(0);" id="vbo-trig-bookhistory" onclick="javascript: vbToggleHistory(this);">
2706 + <?php VikBookingIcons::e('history'); ?>
2707 + <span class="vbo-bookingdet-admintab-lbl"><?php echo JText::translate('VBOBOOKHISTORYTAB'); ?></span>
2708 + </a>
2709 + </div>
2710 + <script type="text/javascript">
2711 + if (window.location.hash == '#bookhistory') {
2712 + setTimeout(function() {
2713 + jQuery(".vbo-bookingdet-tab[data-vbotab='vbo-tab-admin']").trigger('click');
2714 + vbToggleHistory(document.getElementById('vbo-trig-bookhistory'));
2715 + }, 500);
2716 + }
2717 + </script>
2718 + <?php
2719 + }
2720 + ?>
2721 + <div class="vbo-bookingdet-noteslogs-btn pro-feature" data-id="invnotes">
2722 + <a href="javascript: void(0);" class="hasTooltip" id="vbo-trig-invnotes" onclick="javascript: vbToggleInvNotes(this);" title="<?php echo addslashes(JText::translate('VBBOOKINGINVNOTESHELP')); ?>">
2723 + <?php VikBookingIcons::e('file-invoice'); ?>
2724 + <span class="vbo-bookingdet-admintab-lbl"><?php echo JText::translate('VBBOOKINGINVNOTES'); ?></span>
2725 + </a>
2726 + </div>
2727 +
2728 + <!-- Define role to detect the supported hook -->
2729 + <!-- {"rule":"customizer","event":"onDisplayViewVikBookingEditorderAdministration","type":"fieldset"} -->
2730 +
2731 + <?php
2732 + foreach ($adminPanelForms as $legend => $form)
2733 + {
2734 + $legendId = preg_replace("/[^a-zA-Z0-9_\-]+/", '', $legend);
2735 + ?>
2736 + <div class="vbo-bookingdet-noteslogs-btn" data-id="<?php echo $legendId; ?>">
2737 + <a href="javascript: void(0);" class="hasTooltip" id="vbo-trig-<?php echo $legendId; ?>" onclick="javascript: vbToggleDynamicPanel(this, '#vboextrapanel-<?php echo $legendId; ?>');">
2738 + <?php VikBookingIcons::e(!empty($adminFormsSetup->icons[$legend]) ? $adminFormsSetup->icons[$legend] : 'plug'); ?>
2739 + <span class="vbo-bookingdet-admintab-lbl"><?php echo JText::translate($legend); ?></span>
2740 + </a>
2741 + </div>
2742 + <?php
2743 + }
2744 +
2745 + if (!empty($row['paymentlog'])) {
2746 + $paylogs_lbl = JText::translate('VBPAYMENTLOGTOGGLE');
2747 + if ($may_have_cc_details) {
2748 + $paylogs_lbl = JText::translate('VBO_CREDIT_CARD');
2749 + }
2750 + ?>
2751 + <div class="vbo-bookingdet-noteslogs-btn" data-id="paylogs">
2752 + <a href="javascript: void(0);" id="vbo-trig-paylogs" onclick="javascript: vbToggleLog(this);">
2753 + <?php VikBookingIcons::e('credit-card'); ?>
2754 + <span class="vbo-bookingdet-admintab-lbl"><?php echo $paylogs_lbl; ?></span>
2755 + </a>
2756 + <a name="paymentlog" href="javascript: void(0);"></a>
2757 + </div>
2758 + <?php
2759 + }
2760 + ?>
2761 + </div>
2762 + <div class="vbo-bookingdet-noteslogs-cont">
2763 + <div id="vbadminnotesdiv" class="vbo-extra-panel" style="display: block;">
2764 + <textarea name="adminnotes" class="vbadminnotestarea"><?php echo JHtml::fetch('esc_textarea', (string) $row['adminnotes']); ?></textarea>
2765 + <input type="submit" name="updadmnotes" value="<?php echo JText::translate('VBADMINNOTESUPD'); ?>" class="btn btn-success" />
2766 + </div>
2767 + <?php
2768 + if ($takings) {
2769 + ?>
2770 + <div class="vbo-extra-panel" id="vboextrapanel-takings" style="display: none;">
2771 + <div class="vbo-booking-takings-container table-responsive">
2772 + <table class="table">
2773 + <thead>
2774 + <tr class="vbo-booking-takings-firstrow">
2775 + <td class="vbo-booking-takings-td-totpaid"><?php echo JText::translate('VBO_TAKINGS'); ?></td>
2776 + <td class="vbo-booking-takings-td-date"><?php echo JText::translate('VBOBOOKHISTORYLBLDATE'); ?></td>
2777 + <td class="vbo-booking-takings-td-type"><?php echo JText::translate('VBOBOOKHISTORYLBLTYPE'); ?></td>
2778 + <td class="vbo-booking-takings-td-fees"><?php echo JText::translate('VBO_PROCESSING_FEES'); ?></td>
2779 + <td class="vbo-booking-takings-td-descr"><?php echo JText::translate('VBOBOOKHISTORYLBLDESC'); ?></td>
2780 + </tr>
2781 + </thead>
2782 + <tbody>
2783 + <?php
2784 + $booking_total_taking = 0;
2785 + $booking_total_prfees = 0;
2786 + foreach (array_reverse($takings) as $hist) {
2787 + // calculate amount paid and description
2788 + $tn_amount_paid = 0;
2789 + $tn_amount_fees = 0;
2790 + $tn_description = strpos((string) $hist['descr'], '<') !== false ? $hist['descr'] : preg_replace("/\R/", ' - ', (string) $hist['descr']);
2791 + if (is_object($hist['data'])) {
2792 + // calculate amount paid or amount refunded
2793 + if (($hist['data']->amount_paid ?? 0)) {
2794 + $tn_amount_paid = $hist['data']->amount_paid;
2795 + if (in_array($hist['type'], ['RF', 'RU'])) {
2796 + // turn the amount paid to negative
2797 + $tn_amount_paid = $tn_amount_paid < 0 ? $tn_amount_paid : ($tn_amount_paid - ($tn_amount_paid * 2));
2798 + if ($hist['type'] === 'RU' && $hist['data']->amount_paid < 0) {
2799 + // this indicates a lower amount refunded, so we double it to make it positive
2800 + $tn_amount_paid = abs($hist['data']->amount_paid);
2801 + }
2802 + }
2803 + }
2804 +
2805 + // calculate processing fees, if set and if any
2806 + if (($hist['data']->processing_fees ?? 0)) {
2807 + $tn_amount_fees += $hist['data']->processing_fees;
2808 + }
2809 +
2810 + // build the event description
2811 + if (($hist['data']->payment_method ?? '')) {
2812 + $tn_description = ucwords($hist['data']->payment_method);
2813 + } elseif (($hist['data']->driver ?? '')) {
2814 + $tn_description = ucwords(str_replace('_', ' ', basename($hist['data']->driver, '.php')));
2815 + }
2816 + }
2817 +
2818 + // increase (or decrease) booking total takings and processing fees amounts
2819 + $booking_total_taking += $tn_amount_paid;
2820 + $booking_total_prfees += $tn_amount_fees;
2821 + ?>
2822 + <tr class="vbo-booking-takings-row">
2823 + <td>
2824 + <?php
2825 + echo VikBooking::formatCurrencyNumber(VikBooking::numberFormat($tn_amount_paid), $currencysymb);
2826 + if (!strcasecmp($hist['type'], 'PU')) {
2827 + /**
2828 + * Allow to edit or delete the history record.
2829 + *
2830 + * @since 1.16.10 (J) - 1.6.10 (WP)
2831 + */
2832 + ?>
2833 + <div class="vbo-booking-taking-cmds">
2834 + <button type="button" class="btn btn-small btn-primary vbo-booking-taking-edit vbo-tooltip vbo-tooltip-top" data-tooltiptext="<?php echo $this->escape(JText::translate('VBMAINPAYMENTSEDIT')); ?>" data-historyid="<?php echo $hist['id']; ?>" data-amount="<?php echo $tn_amount_paid; ?>"><?php VikBookingIcons::e('edit'); ?></button>
2835 + <button type="button" class="btn btn-small btn-danger vbo-booking-taking-delete vbo-tooltip vbo-tooltip-top" data-tooltiptext="<?php echo $this->escape(JText::translate('VBELIMINA')); ?>" data-historyid="<?php echo $hist['id']; ?>"><?php VikBookingIcons::e('times-circle'); ?></button>
2836 + </div>
2837 + <?php
2838 + }
2839 + ?>
2840 + </td>
2841 + <td><?php echo JHtml::fetch('date', $hist['dt'], 'Y-m-d H:i:s'); ?></td>
2842 + <td><?php echo $history_obj->validType($hist['type'], true); ?></td>
2843 + <td><?php echo VikBooking::formatCurrencyNumber(VikBooking::numberFormat($tn_amount_fees), $currencysymb); ?></td>
2844 + <td><?php echo $tn_description; ?></td>
2845 + </tr>
2846 + <?php
2847 + }
2848 + ?>
2849 + </tbody>
2850 + <tfoot>
2851 + <tr>
2852 + <td colspan="2">
2853 + <span><?php echo VikBooking::formatCurrencyNumber(VikBooking::numberFormat($booking_total_taking), $currencysymb); ?></span>
2854 + </td>
2855 + <td></td>
2856 + <td>
2857 + <span><?php echo VikBooking::formatCurrencyNumber(VikBooking::numberFormat($booking_total_prfees), $currencysymb); ?></span>
2858 + </td>
2859 + <td>
2860 + <button type="button" class="btn btn-small btn-success vbo-takings-addnew"><?php VikBookingIcons::e('plus-circle'); ?> <?php echo JText::translate('VBO_REG_NEW_PAYMENT'); ?></button>
2861 + </td>
2862 + </tr>
2863 + </tfoot>
2864 + </table>
2865 + </div>
2866 +
2867 + <div class="vbo-eorder-newtaking-helper-wrap" style="display: none;">
2868 + <div class="vbo-eorder-newtaking-helper-cont">
2869 + <div class="vbo-admin-container vbo-admin-container-full vbo-admin-container-compact">
2870 + <div class="vbo-params-wrap">
2871 + <div class="vbo-params-container">
2872 + <div class="vbo-params-block">
2873 + <div class="vbo-param-container">
2874 + <div class="vbo-param-label">
2875 + <label for="new_taking_amount"><?php echo JText::translate('VBO_CC_AMOUNT'); ?></label>
2876 + </div>
2877 + <div class="vbo-param-setting">
2878 + <div class="vbo-input-currency-wrap">
2879 + <span><?php echo $currencysymb; ?></span>
2880 + <input type="number" id="new_taking_amount" value="" min="0" max="<?php echo $row['total']; ?>" step="any" />
2881 + </div>
2882 + <span class="vbo-param-setting-comment">
2883 + <?php echo JText::translate('VBOCUSTOMERCMMSONTOTAL') . ' ' . VikBooking::formatCurrencyNumber(VikBooking::numberFormat($row['total']), $currencysymb) . ' - ' . JText::translate('VBAMOUNTPAID') . ' ' . VikBooking::formatCurrencyNumber(VikBooking::numberFormat($row['totpaid']), $currencysymb); ?>
2884 + </span>
2885 + </div>
2886 + </div>
2887 + <div class="vbo-param-container">
2888 + <div class="vbo-param-label">
2889 + <label for="new_taking_descr"><?php echo JText::translate('VBLIBPAYNAME'); ?></label>
2890 + </div>
2891 + <div class="vbo-param-setting">
2892 + <select id="new_taking_payid">
2893 + <option value="">&nbsp;</option>
2894 + <?php
2895 + foreach ($this->payments as $paymeth) {
2896 + ?>
2897 + <option value="<?php echo $paymeth['id']; ?>"><?php echo $paymeth['name']; ?></option>
2898 + <?php
2899 + }
2900 + ?>
2901 + </select>
2902 + </div>
2903 + </div>
2904 + <div class="vbo-param-container vbo-param-nested" id="vbo-new-taking-custom-wrap">
2905 + <div class="vbo-param-label">&nbsp;</div>
2906 + <div class="vbo-param-setting">
2907 + <input id="new_taking_descr" type="text" value="" maxlength="200" placeholder="<?php echo $this->escape(JText::translate('VBPVIEWOPTIONALSTWO')); ?>" />
2908 + </div>
2909 + </div>
2910 + </div>
2911 + </div>
2912 + </div>
2913 + </div>
2914 + </div>
2915 + </div>
2916 +
2917 + </div>
2918 +
2919 + <script type="text/javascript">
2920 + jQuery(function() {
2921 +
2922 + jQuery('#new_taking_payid').on('change', function() {
2923 + if (jQuery(this).val()) {
2924 + jQuery('#vbo-new-taking-custom-wrap').hide();
2925 + jQuery('#new_taking_descr').val('');
2926 + } else {
2927 + jQuery('#vbo-new-taking-custom-wrap').show();
2928 + }
2929 + });
2930 +
2931 + jQuery('.vbo-takings-addnew').on('click', function() {
2932 + // build modal buttons
2933 + let footer_left = jQuery('<button></button>');
2934 + footer_left.addClass('btn');
2935 + footer_left.attr('type', 'button');
2936 + footer_left.text(Joomla.JText._('VBANNULLA'));
2937 + footer_left.on('click', function() {
2938 + // dismiss the modal
2939 + VBOCore.emitEvent('vbo-eorder-new-taking-dismiss');
2940 + });
2941 +
2942 + let footer_right = jQuery('<button></button>');
2943 + footer_right.addClass('btn btn-success');
2944 + footer_right.attr('type', 'button');
2945 + footer_right.text(Joomla.JText._('VBSAVE'));
2946 + footer_right.on('click', function() {
2947 + // disable button to prevent double submissions
2948 + let submit_btn = jQuery(this);
2949 + submit_btn.prop('disabled', true);
2950 + // make the request
2951 + VBOCore.doAjax(
2952 + "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=bookings.add_taking'); ?>",
2953 + {
2954 + bid: '<?php echo $row['id']; ?>',
2955 + amount: jQuery('#new_taking_amount').val(),
2956 + payid: jQuery('#new_taking_payid').val(),
2957 + descr: jQuery('#new_taking_descr').val(),
2958 + },
2959 + (success) => {
2960 + // dismiss the modal
2961 + VBOCore.emitEvent('vbo-eorder-new-taking-dismiss');
2962 + // reload the page by following the response URL
2963 + document.location.href = success.url;
2964 + },
2965 + (error) => {
2966 + // re-enable submit button
2967 + submit_btn.prop('disabled', false);
2968 + // display error message
2969 + alert(error.responseText);
2970 + }
2971 + );
2972 + });
2973 +
2974 + // display modal
2975 + let modal_body = VBOCore.displayModal({
2976 + suffix: 'vbo-new-taking',
2977 + extra_class: 'vbo-modal-rounded vbo-modal-dialog',
2978 + title: Joomla.JText._('VBO_REG_NEW_PAYMENT'),
2979 + body: '',
2980 + body_prepend: true,
2981 + footer_left: footer_left,
2982 + footer_right: footer_right,
2983 + draggable: true,
2984 + dismiss_event: 'vbo-eorder-new-taking-dismiss',
2985 + onDismiss: () => {
2986 + jQuery('.vbo-eorder-newtaking-helper-cont').appendTo(
2987 + jQuery('.vbo-eorder-newtaking-helper-wrap')
2988 + );
2989 + },
2990 + });
2991 +
2992 + // reset helper input values
2993 + jQuery('#new_taking_amount').val('');
2994 + jQuery('#new_taking_payid').prop('disabled', false).val('').trigger('change');
2995 + jQuery('#new_taking_descr').val('');
2996 +
2997 + // append modal body
2998 + jQuery('.vbo-eorder-newtaking-helper-cont').appendTo(modal_body);
2999 + });
3000 +
3001 + jQuery('.vbo-booking-taking-edit').on('click', function() {
3002 + let edit_btn = jQuery(this);
3003 + let history_id = edit_btn.attr('data-historyid');
3004 + let curr_amount_paid = edit_btn.attr('data-amount');
3005 + let curr_pay_descr = edit_btn.closest('tr.vbo-booking-takings-row').find('td').last().text();
3006 +
3007 + // build modal buttons
3008 + let footer_left = jQuery('<button></button>');
3009 + footer_left.addClass('btn');
3010 + footer_left.attr('type', 'button');
3011 + footer_left.text(Joomla.JText._('VBANNULLA'));
3012 + footer_left.on('click', function() {
3013 + // dismiss the modal
3014 + VBOCore.emitEvent('vbo-eorder-edit-taking-dismiss');
3015 + });
3016 +
3017 + let footer_right = jQuery('<button></button>');
3018 + footer_right.addClass('btn btn-success');
3019 + footer_right.attr('type', 'button');
3020 + footer_right.text(Joomla.JText._('VBO_UPDATE_PAYMENT'));
3021 + footer_right.on('click', function() {
3022 + // disable button to prevent double submissions
3023 + let submit_btn = jQuery(this);
3024 + submit_btn.prop('disabled', true);
3025 + // make the request
3026 + VBOCore.doAjax(
3027 + "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=bookings.update_taking'); ?>",
3028 + {
3029 + bid: '<?php echo $row['id']; ?>',
3030 + hid: history_id,
3031 + amount: jQuery('#new_taking_amount').val(),
3032 + descr: jQuery('#new_taking_descr').val(),
3033 + htype: 'PU',
3034 + },
3035 + (success) => {
3036 + // dismiss the modal
3037 + VBOCore.emitEvent('vbo-eorder-edit-taking-dismiss');
3038 + // reload the page by following the response URL
3039 + document.location.href = success.url;
3040 + },
3041 + (error) => {
3042 + // re-enable submit button
3043 + submit_btn.prop('disabled', false);
3044 + // display error message
3045 + alert(error.responseText);
3046 + }
3047 + );
3048 + });
3049 +
3050 + // display modal
3051 + let modal_body = VBOCore.displayModal({
3052 + suffix: 'vbo-edit-taking',
3053 + extra_class: 'vbo-modal-rounded vbo-modal-dialog',
3054 + title: Joomla.JText._('VBO_UPDATE_PAYMENT'),
3055 + body: '',
3056 + body_prepend: true,
3057 + footer_left: footer_left,
3058 + footer_right: footer_right,
3059 + draggable: true,
3060 + dismiss_event: 'vbo-eorder-edit-taking-dismiss',
3061 + onDismiss: () => {
3062 + jQuery('.vbo-eorder-newtaking-helper-cont').appendTo(
3063 + jQuery('.vbo-eorder-newtaking-helper-wrap')
3064 + );
3065 + },
3066 + });
3067 +
3068 + // populate helper input values
3069 + jQuery('#new_taking_amount').val(curr_amount_paid);
3070 + jQuery('#new_taking_payid').val('').trigger('change').prop('disabled', true);
3071 + jQuery('#new_taking_descr').val(curr_pay_descr);
3072 +
3073 + // append modal body
3074 + jQuery('.vbo-eorder-newtaking-helper-cont').appendTo(modal_body);
3075 + });
3076 +
3077 + jQuery('.vbo-booking-taking-delete').on('click', function() {
3078 + if (!confirm(Joomla.JText._('VBDELCONFIRM'))) {
3079 + return false;
3080 + }
3081 + let del_btn = jQuery(this);
3082 + del_btn.prop('disabled', true);
3083 + let history_id = del_btn.attr('data-historyid');
3084 + // make the request
3085 + VBOCore.doAjax(
3086 + "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=bookings.delete_history_record'); ?>",
3087 + {
3088 + bid: '<?php echo $row['id']; ?>',
3089 + hid: history_id,
3090 + htype: 'PU',
3091 + },
3092 + (success) => {
3093 + // reload the page by following the response URL
3094 + document.location.href = success.url;
3095 + },
3096 + (error) => {
3097 + // re-enable delete button
3098 + del_btn.prop('disabled', false);
3099 + // display error message
3100 + alert(error.responseText);
3101 + }
3102 + );
3103 + });
3104 +
3105 + });
3106 + </script>
3107 + <?php
3108 + }
3109 + if ($history) {
3110 + ?>
3111 + <div id="vbhistorydiv" class="vbo-extra-panel" style="display: none;">
3112 + <div class="vbo-booking-history-container table-responsive">
3113 + <table class="table">
3114 + <thead>
3115 + <tr class="vbo-booking-history-firstrow">
3116 + <td class="vbo-booking-history-td-type"><?php echo JText::translate('VBOBOOKHISTORYLBLTYPE'); ?></td>
3117 + <td class="vbo-booking-history-td-date"><?php echo JText::translate('VBOBOOKHISTORYLBLDATE'); ?></td>
3118 + <td class="vbo-booking-history-td-descr"><?php echo JText::translate('VBOBOOKHISTORYLBLDESC'); ?></td>
3119 + <td class="vbo-booking-history-td-totpaid"><?php echo JText::translate('VBOBOOKHISTORYLBLTPAID'); ?></td>
3120 + <td class="vbo-booking-history-td-tot"><?php echo JText::translate('VBOBOOKHISTORYLBLTOT'); ?></td>
3121 + </tr>
3122 + </thead>
3123 + <tbody>
3124 + <?php
3125 + foreach ($history as $hist) {
3126 + $hdescr = strpos((string) $hist['descr'], '<') !== false ? $hist['descr'] : nl2br((string) $hist['descr']);
3127 + ?>
3128 + <tr class="vbo-booking-history-row">
3129 + <td><?php echo $history_obj->validType($hist['type'], true); ?></td>
3130 + <td><?php echo JHtml::fetch('date', $hist['dt'], 'Y-m-d H:i:s'); ?></td>
3131 + <td><?php echo $hdescr; ?></td>
3132 + <td><?php echo $currencyname.' '.VikBooking::numberFormat($hist['totpaid']); ?></td>
3133 + <td><?php echo $currencyname.' '.VikBooking::numberFormat($hist['total']); ?></td>
3134 + </tr>
3135 + <?php
3136 + }
3137 + ?>
3138 + </tbody>
3139 + </table>
3140 + </div>
3141 + </div>
3142 + <?php
3143 + }
3144 + ?>
3145 + <div id="vbinvnotesdiv" class="vbo-extra-panel" style="display: none;">
3146 + <textarea name="invnotes" id="invnotes" class="vbadminnotestarea"><?php echo $row['inv_notes']; ?></textarea>
3147 + <input type="submit" name="updinvnotes" value="<?php echo JText::translate('VBADMINNOTESUPD'); ?>" class="btn btn-success" />
3148 + <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>
3149 + </div>
3150 + <?php
3151 + if (!empty($row['paymentlog'])) {
3152 + ?>
3153 + <div id="vbpaymentlogdiv" class="vbo-extra-panel" style="display: none;">
3154 + <div class="vbo-eorder-paymentlog-buttons">
3155 + <?php
3156 + // PCI Data Retrieval
3157 + $cc_acl_denied = false;
3158 + if (!empty($row['idorderota']) && !empty($row['channel'])) {
3159 + $channel_source = $row['channel'];
3160 + if (strpos($row['channel'], '_') !== false) {
3161 + $channelparts = explode('_', $row['channel']);
3162 + $channel_source = $channelparts[0];
3163 + }
3164 + $checkout_info = getdate($row['checkout']);
3165 +
3166 + // validate ACL for credit card details
3167 + if (!$canDo->authorise('core.admin', 'com_vikchannelmanager')) {
3168 + // permissions to access VCM are required
3169 + $cc_acl_denied = true;
3170 + ?>
3171 + <p class="err"><?php echo JText::translate('JERROR_ALERTNOAUTHOR'); ?></p>
3172 + <?php
3173 + } else {
3174 + /**
3175 + * Limit for accessing the credit card details has been changed to check-out
3176 + * day at 23:59:59 + 10 extra days. It used to be at 23:59:59 on check-out day.
3177 + *
3178 + * @since 1.13
3179 + */
3180 + $cardlimit = mktime(23, 59, 59, $checkout_info['mon'], ($checkout_info['mday'] + 10), $checkout_info['year']);
3181 + if ($current_ts < $cardlimit && $may_have_cc_details) {
3182 + // log contains credit card details
3183 + // prepare modal (Credit Card Details)
3184 + array_push($vbo_modals_html, $vbo_app->getJmodalHtml('vbo-vcm-pcid', JText::translate('GETFULLCARDDETAILS'), '', 'width: 80%; height: 60%; margin-left: -40%; top: 20% !important;'));
3185 + ?>
3186 + <div class="vcm-notif-pcidrq-container">
3187 + <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>
3188 + </div>
3189 + <?php
3190 + /**
3191 + * Check for automatic payment schedules support when an active CC/VCC is available.
3192 + *
3193 + * @since 1.16.10 (J) - 1.6.10 (WP)
3194 + */
3195 + $can_payschedule = false;
3196 + $active_payschedules = [];
3197 + try {
3198 + $processor = VBOModelReservation::getInstance($row, true)->getPaymentProcessor();
3199 + if (method_exists($processor, 'isDirectChargeSupported') && $processor->isDirectChargeSupported()) {
3200 + // turn flag on
3201 + $can_payschedule = true;
3202 + // load current schedules
3203 + $active_payschedules = VBOModelPayschedules::getInstance()->getItems([
3204 + 'idorder' => [
3205 + 'value' => $row['id'],
3206 + ],
3207 + ]);
3208 + }
3209 + } catch (Exception $e) {
3210 + // do nothing
3211 + }
3212 +
3213 + if ($can_payschedule) {
3214 + // calculate the total amount scheduled
3215 + $tot_scheduled = 0;
3216 + foreach ($active_payschedules as $active_payschedule) {
3217 + if (!$active_payschedule->status) {
3218 + $tot_scheduled += $active_payschedule->amount;
3219 + }
3220 + }
3221 +
3222 + // display action buttons for payment schedules
3223 + ?>
3224 + <div class="vbo-eorder-payschedules-wrap">
3225 + <button type="button" class="btn btn-<?php echo $active_payschedules || $automatic_payment_collection ? 'success' : 'primary'; ?> vbo-context-menu-btn vbo-context-menu-payschedules">
3226 + <span class="vbo-context-menu-lbl"><?php echo JText::translate('VBO_AUTOPAY_SCHEDULED'); ?></span>
3227 + <span class="vbo-context-menu-ico"><?php VikBookingIcons::e('sort-down'); ?></span>
3228 + </button>
3229 + </div>
3230 +
3231 + <div class="vbo-eorder-newpayschedule-helper-wrap" style="display: none;">
3232 + <div class="vbo-eorder-newpayschedule-helper-cont" data-auto-pay-schedules="<?php echo (int) $automatic_payment_collection; ?>">
3233 + <p class="info" data-auto-pay-schedules="help" style="display: none;"><?php echo JText::translate('VBO_AUTO_PAY_COLLECT_HELP'); ?></p>
3234 + <div class="vbo-admin-container vbo-admin-container-full vbo-admin-container-compact">
3235 + <div class="vbo-params-wrap">
3236 + <div class="vbo-params-container">
3237 + <div class="vbo-params-block">
3238 + <div class="vbo-param-container">
3239 + <div class="vbo-param-label">
3240 + <label for="new_payschedule_amount"><?php echo JText::translate('VBO_CC_AMOUNT'); ?></label>
3241 + </div>
3242 + <div class="vbo-param-setting">
3243 + <div class="vbo-input-currency-wrap">
3244 + <span><?php echo $currencysymb; ?></span>
3245 + <input type="number" id="new_payschedule_amount" value="<?php echo $tot_scheduled < $row['total'] ? ($row['total'] - $tot_scheduled) : 0; ?>" min="0" step="any" />
3246 + </div>
3247 + <span class="vbo-param-setting-comment"><?php echo JText::translate('VBEDITORDERNINE') . ' ' . VikBooking::formatCurrencyNumber(VikBooking::numberFormat($row['total']), $currencysymb); ?></span>
3248 + </div>
3249 + </div>
3250 + <div class="vbo-param-container">
3251 + <div class="vbo-param-label">
3252 + <label for="new_payschedule_fordt"><?php echo JText::translate('VBPVIEWORDERSONE'); ?></label>
3253 + </div>
3254 + <div class="vbo-param-setting">
3255 + <?php echo $vbo_app->getCalendar(date($df, $row['checkin']), 'new_payschedule_fordt', 'new_payschedule_fordt', $nowdf, array('class'=>'', 'size'=>'10', 'maxlength'=>'19', 'todayBtn' => 'true')); ?>
3256 + </div>
3257 + </div>
3258 + <div class="vbo-param-container">
3259 + <div class="vbo-param-label">
3260 + <label for="new_payschedule_fordtime"><?php echo JText::translate('VBO_REMINDER_TIME'); ?></label>
3261 + </div>
3262 + <div class="vbo-param-setting">
3263 + <select id="new_payschedule_fordtime">
3264 + <?php
3265 + for ($h = 0; $h < 24; $h++) {
3266 + $say_htime = ($h < 10 ? '0' : '') . $h;
3267 + ?>
3268 + <option value="<?php echo $say_htime; ?>:00"><?php echo $say_htime; ?>:00</option>
3269 + <option value="<?php echo $say_htime; ?>:30"><?php echo $say_htime; ?>:30</option>
3270 + <?php
3271 + }
3272 + ?>
3273 + </select>
3274 + </div>
3275 + </div>
3276 + </div>
3277 + </div>
3278 + </div>
3279 + </div>
3280 + </div>
3281 + </div>
3282 +
3283 + <script type="text/javascript">
3284 +
3285 + // build base buttons list for context menu
3286 + var vbo_payschedule_btns = [
3287 + // toggle automatic payment collection scheduling for all bookings
3288 + {
3289 + activeState: <?php echo $automatic_payment_collection ? 'true' : 'false'; ?>,
3290 + text: <?php echo json_encode(JText::translate('VBO_ENABLED_FOR_ALL_BOOKINGS')); ?>,
3291 + separator: true,
3292 + icon: function() {
3293 + return this.activeState ? '<?php echo VikBookingIcons::i('toggle-on', 'vbo-enabled-icon'); ?>' : '<?php echo VikBookingIcons::i('toggle-off'); ?>';
3294 + },
3295 + action: function(root, event) {
3296 + // create reference to button object
3297 + let that = this;
3298 +
3299 + // get new state
3300 + let newState = !this.activeState;
3301 +
3302 + // determine confirmation message
3303 + let confirm_enable = <?php echo json_encode(JText::translate('VBO_AUTO_PAY_COLLECT_ENABLE_CONF')); ?>;
3304 + let confirm_disable = <?php echo json_encode(JText::translate('VBO_AUTO_PAY_COLLECT_DISABLE_CONF')); ?>;
3305 +
3306 + if ((newState && confirm(confirm_enable)) || (!newState && confirm(confirm_disable))) {
3307 + // silently update configuration setting
3308 + VBOCore.doAjax(
3309 + "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=configuration.update'); ?>",
3310 + {
3311 + settings: {
3312 + auto_payment_collection: newState ? 1 : 0,
3313 + }
3314 + },
3315 + (success) => {
3316 + // toggle state
3317 + that.activeState = newState;
3318 + // update data attribute with the newly saved configuration value
3319 + let statusEl = document.querySelector('.vbo-eorder-newpayschedule-helper-cont[data-auto-pay-schedules]');
3320 + if (statusEl) {
3321 + statusEl.setAttribute('data-auto-pay-schedules', (newState ? 1 : 0));
3322 + }
3323 + },
3324 + (error) => {
3325 + console.error(error);
3326 + }
3327 + );
3328 + }
3329 + },
3330 + },
3331 + // add new payment schedule button
3332 + {
3333 + icon: '<?php echo VikBookingIcons::i('plus-circle'); ?>',
3334 + text: Joomla.JText._('VBO_NEW_PAYSCHEDULE'),
3335 + separator: true,
3336 + action: (root, config) => {
3337 + // build modal buttons
3338 + let footer_left = jQuery('<button></button>');
3339 + footer_left.addClass('btn');
3340 + footer_left.attr('type', 'button');
3341 + footer_left.text(Joomla.JText._('VBANNULLA'));
3342 + footer_left.on('click', function() {
3343 + // dismiss the modal
3344 + VBOCore.emitEvent('vbo-eorder-new-payschedule-dismiss');
3345 + });
3346 +
3347 + let footer_right = jQuery('<button></button>');
3348 + footer_right.addClass('btn btn-success');
3349 + footer_right.attr('type', 'button');
3350 + footer_right.text(Joomla.JText._('VBSAVE'));
3351 + footer_right.on('click', function() {
3352 + // disable button to prevent double submissions
3353 + let submit_btn = jQuery(this);
3354 + submit_btn.prop('disabled', true);
3355 + // make the request
3356 + VBOCore.doAjax(
3357 + "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=payschedules.save'); ?>",
3358 + {
3359 + bid: '<?php echo $row['id']; ?>',
3360 + amount: jQuery('#new_payschedule_amount').val(),
3361 + dt: jQuery('#new_payschedule_fordt').val(),
3362 + time: jQuery('#new_payschedule_fordtime').val(),
3363 + },
3364 + (new_pay_schedules) => {
3365 + // re-enable submit button
3366 + submit_btn.prop('disabled', false);
3367 + // dismiss the modal
3368 + VBOCore.emitEvent('vbo-eorder-new-payschedule-dismiss');
3369 + // populate the new schedule buttons
3370 + let new_pay_schedule_btns = [];
3371 + // push button to toggle automatic payment collection scheduling for all bookings
3372 + new_pay_schedule_btns.push(vbo_payschedule_btns[0]);
3373 + // push button to add a new schedule
3374 + new_pay_schedule_btns.push(vbo_payschedule_btns[1]);
3375 + // push all active schedules
3376 + new_pay_schedules.forEach((payschedule) => {
3377 + new_pay_schedule_btns.push(
3378 + vboBuildPayScheduleBtn(payschedule)
3379 + );
3380 + });
3381 + // update trigger button class
3382 + if (new_pay_schedules.length) {
3383 + jQuery('.vbo-context-menu-payschedules').removeClass('btn-primary').addClass('btn-success');
3384 + } else {
3385 + jQuery('.vbo-context-menu-payschedules').removeClass('btn-success').addClass('btn-primary');
3386 + }
3387 + // set new buttons in context menu
3388 + jQuery('.vbo-context-menu-payschedules').vboContextMenu('buttons', new_pay_schedule_btns);
3389 + },
3390 + (error) => {
3391 + // re-enable submit button
3392 + submit_btn.prop('disabled', false);
3393 + // display error message
3394 + alert(error.responseText);
3395 + }
3396 + );
3397 + });
3398 +
3399 + // display modal
3400 + let modal_body = VBOCore.displayModal({
3401 + suffix: 'vbo-new-pay-schedule',
3402 + extra_class: 'vbo-modal-rounded vbo-modal-dialog',
3403 + title: Joomla.JText._('VBO_NEW_PAYSCHEDULE'),
3404 + body: '',
3405 + body_prepend: true,
3406 + footer_left: footer_left,
3407 + footer_right: footer_right,
3408 + draggable: true,
3409 + dismiss_event: 'vbo-eorder-new-payschedule-dismiss',
3410 + onDismiss: () => {
3411 + jQuery('.vbo-eorder-newpayschedule-helper-cont').appendTo(
3412 + jQuery('.vbo-eorder-newpayschedule-helper-wrap')
3413 + );
3414 + },
3415 + });
3416 +
3417 + // check current automatic payment schedules status
3418 + let statusEl = document.querySelector('.vbo-eorder-newpayschedule-helper-cont[data-auto-pay-schedules]');
3419 + if (statusEl) {
3420 + let autoPayStatus = statusEl.getAttribute('data-auto-pay-schedules');
3421 + if (autoPayStatus == 1) {
3422 + // show help element
3423 + statusEl.querySelector('[data-auto-pay-schedules="help"]').style.display = '';
3424 + } else {
3425 + // hide help element
3426 + statusEl.querySelector('[data-auto-pay-schedules="help"]').style.display = 'none';
3427 + }
3428 + }
3429 +
3430 + // append modal body
3431 + jQuery('.vbo-eorder-newpayschedule-helper-cont').appendTo(modal_body);
3432 + },
3433 + }
3434 + ];
3435 +
3436 + /**
3437 + * Builds a button object for the context menu from the given payment schedule object.
3438 + */
3439 + function vboBuildPayScheduleBtn(payschedule) {
3440 + let icn_to_process = '<?php echo VikBookingIcons::i('clock'); ?>';
3441 + let icn_processed = '<?php echo VikBookingIcons::i('check-circle'); ?>';
3442 + let icn_error = '<?php echo VikBookingIcons::i('exclamation-triangle'); ?>';
3443 + let dt_unit = (payschedule.dt_diff.days || payschedule.dt_diff.weeks || payschedule.dt_diff.months || payschedule.dt_diff.years || 0);
3444 + let say_dt = !payschedule.dt_diff.past && dt_unit > 0 ? payschedule.dt_diff.relative : payschedule?.fordt;
3445 + if (!payschedule.dt_diff.past && (payschedule.dt_diff.sameday || payschedule.dt_diff.today)) {
3446 + say_dt = payschedule.dt_diff.relative + ' (' + payschedule.time_hm + ')';
3447 + } else if (!payschedule.dt_diff.past && payschedule.dt_diff.tomorrow) {
3448 + say_dt = payschedule.dt_diff.relative + ' (' + payschedule.time_hm + ')';
3449 + }
3450 +
3451 + return {
3452 + icon: ((payschedule.status || 0) > 0 ? (payschedule.status == 1 ? icn_processed : icn_error) : icn_to_process),
3453 + text: VBOCore.getCurrency().format(payschedule?.amount) + ' - ' + say_dt,
3454 + class: ((payschedule.status || 0) == 1 ? 'vbo-context-menu-entry-success' : ((payschedule.status || 0) == 2 ? 'vbo-context-menu-entry-warning' : 'vbo-context-menu-entry-danger')),
3455 + separator: false,
3456 + action: (root, config) => {
3457 + if (payschedule.status == 0 || !payschedule.logs) {
3458 + // confirm deletion without displaying anything
3459 + if (confirm(Joomla.JText._('VBDELCONFIRM'))) {
3460 + // make the request
3461 + VBOCore.doAjax(
3462 + "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=payschedules.delete'); ?>",
3463 + {
3464 + bid: payschedule.idorder,
3465 + schedule_id: payschedule.id,
3466 + },
3467 + (new_pay_schedules) => {
3468 + // populate the new schedule buttons
3469 + let new_pay_schedule_btns = [];
3470 + // push button to toggle automatic payment collection scheduling for all bookings
3471 + new_pay_schedule_btns.push(vbo_payschedule_btns[0]);
3472 + // push button to add a new schedule
3473 + new_pay_schedule_btns.push(vbo_payschedule_btns[1]);
3474 + // push all active schedules
3475 + new_pay_schedules.forEach((payschedule) => {
3476 + new_pay_schedule_btns.push(
3477 + vboBuildPayScheduleBtn(payschedule)
3478 + );
3479 + });
3480 + // update trigger button class
3481 + if (new_pay_schedules.length) {
3482 + jQuery('.vbo-context-menu-payschedules').removeClass('btn-primary').addClass('btn-success');
3483 + } else {
3484 + jQuery('.vbo-context-menu-payschedules').removeClass('btn-success').addClass('btn-primary');
3485 + }
3486 + // set new buttons in context menu
3487 + jQuery('.vbo-context-menu-payschedules').vboContextMenu('buttons', new_pay_schedule_btns);
3488 + },
3489 + (error) => {
3490 + // display error message
3491 + alert(error.responseText);
3492 + }
3493 + );
3494 + }
3495 + } else {
3496 + // display modal on click with the execution logs
3497 +
3498 + // build modal buttons
3499 + let footer_left = jQuery('<button></button>');
3500 + footer_left.addClass('btn');
3501 + footer_left.attr('type', 'button');
3502 + footer_left.text(Joomla.JText._('VBANNULLA'));
3503 + footer_left.on('click', function() {
3504 + // dismiss the modal
3505 + VBOCore.emitEvent('vbo-eorder-payschedule-logs-dismiss');
3506 + });
3507 +
3508 + let footer_right = jQuery('<button></button>');
3509 + footer_right.addClass('btn btn-danger');
3510 + footer_right.attr('type', 'button');
3511 + footer_right.text(Joomla.JText._('VBELIMINA'));
3512 + footer_right.on('click', function() {
3513 + // confirm record deletion
3514 + if (confirm(Joomla.JText._('VBDELCONFIRM'))) {
3515 + // make the request
3516 + VBOCore.doAjax(
3517 + "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=payschedules.delete'); ?>",
3518 + {
3519 + bid: payschedule.idorder,
3520 + schedule_id: payschedule.id,
3521 + },
3522 + (new_pay_schedules) => {
3523 + // dismiss the modal
3524 + VBOCore.emitEvent('vbo-eorder-payschedule-logs-dismiss');
3525 + // populate the new schedule buttons
3526 + let new_pay_schedule_btns = [];
3527 + // push button to toggle automatic payment collection scheduling for all bookings
3528 + new_pay_schedule_btns.push(vbo_payschedule_btns[0]);
3529 + // push button to add a new schedule
3530 + new_pay_schedule_btns.push(vbo_payschedule_btns[1]);
3531 + // push all active schedules
3532 + new_pay_schedules.forEach((payschedule) => {
3533 + new_pay_schedule_btns.push(
3534 + vboBuildPayScheduleBtn(payschedule)
3535 + );
3536 + });
3537 + // update trigger button class
3538 + if (new_pay_schedules.length) {
3539 + jQuery('.vbo-context-menu-payschedules').removeClass('btn-primary').addClass('btn-success');
3540 + } else {
3541 + jQuery('.vbo-context-menu-payschedules').removeClass('btn-success').addClass('btn-primary');
3542 + }
3543 + // set new buttons in context menu
3544 + jQuery('.vbo-context-menu-payschedules').vboContextMenu('buttons', new_pay_schedule_btns);
3545 + },
3546 + (error) => {
3547 + // display error message
3548 + alert(error.responseText);
3549 + }
3550 + );
3551 + }
3552 + });
3553 +
3554 + // display modal
3555 + let modal_body = VBOCore.displayModal({
3556 + suffix: 'vbo-pay-schedule-logs',
3557 + extra_class: 'vbo-modal-rounded vbo-modal-dialog',
3558 + title: payschedule.fordt,
3559 + body: '<pre>' + payschedule.logs + '</pre>',
3560 + footer_left: footer_left,
3561 + footer_right: footer_right,
3562 + draggable: true,
3563 + dismiss_event: 'vbo-eorder-payschedule-logs-dismiss',
3564 + });
3565 + }
3566 + },
3567 + };
3568 + }
3569 +
3570 + // build context menu
3571 + jQuery(function() {
3572 +
3573 + // append active payment schedule buttons
3574 + let active_payschedules = <?php echo json_encode($active_payschedules); ?>;
3575 + active_payschedules.forEach((payschedule) => {
3576 + vbo_payschedule_btns.push(
3577 + vboBuildPayScheduleBtn(payschedule)
3578 + );
3579 + });
3580 +
3581 + // render context menu
3582 + jQuery('.vbo-context-menu-payschedules').vboContextMenu({
3583 + placement: 'bottom-left',
3584 + buttons: vbo_payschedule_btns,
3585 + });
3586 +
3587 + });
3588 + </script>
3589 + <?php
3590 + }
3591 + // end automatic payment schedules
3592 + }
3593 + }
3594 + } elseif (empty($row['idorderota']) && !empty($row['paymentlog']) && $row['status'] == 'standby') {
3595 + ?>
3596 + <div class="vbo-eorder-emptyccdata">
3597 + <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>
3598 + </div>
3599 + <?php
3600 + }
3601 +
3602 + /**
3603 + * Attempt to display the reporting invalid credit card layout from VCM.
3604 + *
3605 + * @requires VCM >= 1.8.27
3606 + *
3607 + * @since 1.16.9 (J) - 1.6.9 (WP)
3608 + */
3609 + try {
3610 + // prepare the layout data array
3611 + $layout_data = [
3612 + 'caller' => 'vikbooking',
3613 + 'booking' => $row,
3614 + ];
3615 +
3616 + ?>
3617 + <div class="vbo-eorder-vcm-reporting-invalidcc">
3618 + <?php
3619 + // render the reporting-invalidcc layout
3620 + echo JLayoutHelper::render('reporting.invalidcc', $layout_data, null, [
3621 + 'component' => 'com_vikchannelmanager',
3622 + 'client' => 'admin',
3623 + ]);
3624 + ?>
3625 + </div>
3626 + <?php
3627 + } catch(Throwable $e) {
3628 + // do nothing
3629 + }
3630 +
3631 + ?>
3632 + </div>
3633 + <?php
3634 +
3635 + if (!$cc_acl_denied) {
3636 + ?>
3637 + <pre><?php echo htmlspecialchars($row['paymentlog']); ?></pre>
3638 + <?php
3639 + }
3640 + ?>
3641 + </div>
3642 +
3643 + <script type="text/javascript">
3644 + if (window.location.hash == '#paymentlog') {
3645 + setTimeout(function() {
3646 + jQuery(".vbo-bookingdet-tab[data-vbotab='vbo-tab-admin']").trigger('click');
3647 + vbToggleLog(document.getElementById('vbo-trig-paylogs'));
3648 + }, 500);
3649 + }
3650 + </script>
3651 + <?php
3652 + }
3653 + if (!$printreceipt && !is_null($messaging)) {
3654 + ?>
3655 + <div id="vbmessagingdiv" class="vbo-extra-panel" style="display: none;">
3656 + <?php echo $messaging->renderChat(); ?>
3657 + </div>
3658 + <script type="text/javascript">
3659 + jQuery(function() {
3660 + if (window.location.hash == '#messaging') {
3661 + setTimeout(function() {
3662 + jQuery(".vbo-bookingdet-tab[data-vbotab='vbo-tab-admin']").trigger('click');
3663 + vbToggleMessaging(document.getElementById('vbo-trig-messaging'));
3664 + }, 100);
3665 + }
3666 + });
3667 + </script>
3668 + <?php
3669 + }
3670 +
3671 + foreach ($adminPanelForms as $legend => $form)
3672 + {
3673 + $legendId = preg_replace("/[^a-zA-Z0-9_\-]+/", '', $legend);
3674 + ?>
3675 + <div class="vbo-extra-panel" id="vboextrapanel-<?php echo $legendId; ?>" style="display: none;">
3676 + <?php echo $form; ?>
3677 + </div>
3678 + <?php
3679 + }
3680 + ?>
3681 + </div>
3682 + </div>
3683 + </div>
3684 + </div>
3685 +
3686 + <input type="hidden" name="task" value="editorder">
3687 + <input type="hidden" name="vbo_active_tab" id="vbo_active_tab" value="">
3688 + <input type="hidden" name="whereup" value="<?php echo $row['id']; ?>">
3689 + <input type="hidden" name="cid[]" value="<?php echo $row['id']; ?>">
3690 + <input type="hidden" name="option" value="com_vikbooking">
3691 + <?php
3692 + $tmpl = VikRequest::getVar('tmpl');
3693 + if ($tmpl == 'component') {
3694 + echo '<input type="hidden" name="tmpl" value="component" />';
3695 + }
3696 + $pgoto = VikRequest::getString('goto', '', 'request');
3697 + if (in_array($pgoto, ['overv', 'ratesoverv'])) {
3698 + echo '<input type="hidden" name="goto" value="' . $pgoto . '" />';
3699 + }
3700 + ?>
3701 + </form>
3702 +</div>
3703 +<?php
3704 +foreach ($vbo_modals_html as $modalhtml) {
3705 + echo $modalhtml;
3706 +}
3707 +?>
3708 +<form action="index.php?option=com_vikbooking&amp;task=orders" method="post" id="vbo-gen-invoice">
3709 + <input type="hidden" name="option" value="com_vikbooking" />
3710 + <input type="hidden" name="task" value="orders" />
3711 + <input type="hidden" name="cid[]" value="<?php echo $row['id']; ?>" />
3712 + <input type="hidden" name="invnotes" id="invnotes-hid" value="" />
3713 +</form>
3714 +
3715 +<div class="vbo-editorder-sms-email-send-helper" style="display: none;">
3716 +
3717 + <div class="vbo-editorder-sms-send-wrap">
3718 + <form action="index.php?option=com_vikbooking" method="post" id="vbo-modal-form-sms">
3719 + <div class="vbo-admin-container vbo-admin-container-full vbo-admin-container-compact">
3720 + <div class="vbo-params-wrap">
3721 + <div class="vbo-params-container">
3722 +
3723 + <div class="vbo-param-container vbo-param-container-full">
3724 + <div class="vbo-param-label">
3725 + <label for="smscont"><?php echo JText::translate('VBSENDSMSCUSTCONT'); ?></label>
3726 + </div>
3727 + <div class="vbo-param-setting">
3728 + <textarea name="smscont" id="smscont" style="width: 99%; min-width: 99%; max-width: 99%; height: 120px;"></textarea>
3729 + </div>
3730 + </div>
3731 +
3732 + </div>
3733 + </div>
3734 + </div>
3735 + <input type="hidden" name="phone" id="smstophone" value="<?php echo $row['phone']; ?>" />
3736 + <input type="hidden" name="goto" value="<?php echo urlencode('index.php?option=com_vikbooking&task=editorder&cid[]='.$row['id']); ?>" />
3737 + <input type="hidden" name="task" value="sendcustomsms" />
3738 + </form>
3739 + </div>
3740 +
3741 + <div class="vbo-editorder-email-send-wrap">
3742 + <form action="index.php?option=com_vikbooking" method="post" enctype="multipart/form-data" id="vbo-modal-form-email">
3743 + <div class="vbo-admin-container vbo-admin-container-full vbo-admin-container-compact">
3744 + <div class="vbo-params-wrap">
3745 + <div class="vbo-params-container">
3746 +
3747 + <?php
3748 + $cur_emtpl = VBOFactory::getConfig()->getArray('customemailtpls', []);
3749 + if ($cur_emtpl) {
3750 + ?>
3751 + <div class="vbo-param-container">
3752 + <div class="vbo-param-setting">
3753 + <select id="emtpl-customemail" onchange="vboLoadEmailTpl(this.value);">
3754 + <option value=""><?php echo JText::translate('VBEMAILCUSTFROMTPL'); ?></option>
3755 + <?php
3756 + foreach ($cur_emtpl as $emk => $emv) {
3757 + ?>
3758 + <optgroup label="<?php echo $emv['emailsubj']; ?>">
3759 + <option value="<?php echo $emk; ?>"><?php echo JText::translate('VBEMAILCUSTFROMTPLUSE'); ?></option>
3760 + <option value="rm<?php echo $emk; ?>"><?php echo JText::translate('VBEMAILCUSTFROMTPLRM'); ?></option>
3761 + </optgroup>
3762 + <?php
3763 + }
3764 + ?>
3765 + </select>
3766 + </div>
3767 + </div>
3768 + <?php
3769 + }
3770 +
3771 + /**
3772 + * Load all conditional text special tags.
3773 + *
3774 + * @since 1.14 (J) - 1.4.0 (WP)
3775 + */
3776 + $extra_btns = [];
3777 + $condtext_tags = VikBooking::getConditionalRulesInstance()->getSpecialTags();
3778 + if ($condtext_tags) {
3779 + $condtext_tags = array_keys($condtext_tags);
3780 + foreach ($condtext_tags as $tag) {
3781 + array_push($extra_btns, '<button type="button" class="btn btn-secondary btn-small vbo-condtext-specialtag-btn" onclick="setSpecialTplTag(\'emailcont\', \'' . $tag . '\');">' . $tag . '</button>');
3782 + }
3783 + }
3784 + ?>
3785 + <div class="vbo-param-container vbo-param-container-full">
3786 + <div class="vbo-param-label">
3787 + <label for="emailsubj"><?php echo JText::translate('VBSENDEMAILCUSTSUBJ'); ?></label>
3788 + </div>
3789 + <div class="vbo-param-setting">
3790 + <input type="text" name="emailsubj" id="emailsubj" value="" size="30" />
3791 + </div>
3792 + </div>
3793 +
3794 + <div class="vbo-param-container vbo-param-container-full">
3795 + <div class="vbo-param-label">
3796 + <label for="emailcont"><?php echo JText::translate('VBSENDEMAILCUSTCONT'); ?></label>
3797 + </div>
3798 + <div class="vbo-param-setting">
3799 + <?php
3800 + $special_tags_base = [
3801 + '{customer_name}',
3802 + '{booking_id}',
3803 + '{checkin_date}',
3804 + '{checkout_date}',
3805 + '{num_nights}',
3806 + '{rooms_booked}',
3807 + '{rooms_names}',
3808 + '{tot_adults}',
3809 + '{tot_children}',
3810 + '{tot_guests}',
3811 + '{total}',
3812 + '{total_paid}',
3813 + '{remaining_balance}',
3814 + '{booking_link}',
3815 + ];
3816 +
3817 + $special_tags_base_html = '';
3818 + foreach ($special_tags_base as $sp_tag) {
3819 + $special_tags_base_html .= '<button type="button" class="btn btn-secondary btn-small" onclick="setSpecialTplTag(\'emailcont\', \'' . $sp_tag . '\');">' . $sp_tag . '</button>' . "\n";
3820 + }
3821 +
3822 + /**
3823 + * Use the rich text editor (visual editor) to build custom email messages.
3824 + *
3825 + * @since 1.15.0 (J) - 1.5.0 (WP)
3826 + */
3827 + $tarea_attr = [
3828 + 'id' => 'emailcont',
3829 + 'rows' => '7',
3830 + 'cols' => '170',
3831 + 'style' => 'width: 99%; min-width: 99%; max-width: 99%; height: 120px; margin-bottom: 1px;',
3832 + ];
3833 + $editor_opts = [
3834 + 'modes' => [
3835 + 'visual',
3836 + 'text',
3837 + ],
3838 + 'gen_ai' => [
3839 + 'booking' => $row,
3840 + 'customer' => $customer,
3841 + 'environment' => 'booking',
3842 + ],
3843 + ];
3844 + $editor_btns = $special_tags_base;
3845 + if ($condtext_tags) {
3846 + $editor_btns = array_merge($editor_btns, $condtext_tags);
3847 + }
3848 +
3849 + /**
3850 + * Trigger event to allow third-party plugins to add custom special tags.
3851 + *
3852 + * @since 1.16.10 (J) - 1.6.10 (WP)
3853 + */
3854 + $custom_btns = VBOFactory::getPlatform()->getDispatcher()->filter('onRenderCustomEmailSpecialTags', [$row, $editor_btns]);
3855 + foreach ($custom_btns as $custom_btn) {
3856 + // merge custom buttons
3857 + $editor_btns = array_merge($editor_btns, (array) $custom_btn);
3858 + }
3859 +
3860 + // make sure to filter empty buttons
3861 + $editor_btns = array_filter($editor_btns);
3862 +
3863 + // render visual editor
3864 + echo $vbo_app->renderVisualEditor('emailcont', '', $tarea_attr, $editor_opts, $editor_btns);
3865 + ?>
3866 + <div class="btn-group pull-left vbo-smstpl-bgroup vbo-custmail-bgroup vik-contentbuilder-textmode-sptags">
3867 + <?php echo $special_tags_base_html . "\n" . implode("\n", $extra_btns); ?>
3868 + </div>
3869 + </div>
3870 + </div>
3871 +
3872 + <div class="vbo-param-container vbo-param-container-full">
3873 + <div class="vbo-param-label">
3874 + <label for="emailattch"><?php echo JText::translate('VBSENDEMAILCUSTATTCH'); ?></label>
3875 + </div>
3876 + <div class="vbo-param-setting">
3877 + <input type="file" name="emailattch" id="emailattch" />
3878 + </div>
3879 + </div>
3880 +
3881 + <div class="vbo-param-container vbo-param-container-full">
3882 + <div class="vbo-param-label">
3883 + <label for="emailfrom"><?php echo JText::translate('VBSENDEMAILCUSTFROM'); ?></label>
3884 + </div>
3885 + <div class="vbo-param-setting">
3886 + <input type="text" name="emailfrom" id="emailfrom" value="<?php echo VikBooking::getSenderMail(); ?>" size="30" />
3887 + </div>
3888 + </div>
3889 +
3890 + </div>
3891 + </div>
3892 + </div>
3893 + <input type="hidden" name="bid" value="<?php echo $row['id']; ?>" />
3894 + <input type="hidden" name="email" id="emailto" value="<?php echo $row['custmail']; ?>" />
3895 + <input type="hidden" name="goto" value="<?php echo urlencode('index.php?option=com_vikbooking&task=editorder&cid[]='.$row['id']); ?>" />
3896 + <input type="hidden" name="task" value="sendcustomemail" />
3897 + </form>
3898 + </div>
3899 +
3900 + <div id="vbo-modal-footer-sms" style="display: none;">
3901 + <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>
3902 + </div>
3903 + <div id="vbo-modal-footer-email" style="display: none;">
3904 + <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>
3905 + </div>
3906 +</div>
3907 +
3908 +<div class="vbo-bookingdet-send-tplmessage-helper" style="display: none;">
3909 + <div class="vbo-bookingdet-send-tplmessage-wrap">
3910 + <div class="vbo-admin-container vbo-admin-container-full vbo-admin-container-compact">
3911 + <div class="vbo-params-wrap">
3912 + <div class="vbo-params-container">
3913 + <div class="vbo-params-block">
3914 + <?php
3915 + echo VBOParamsRendering::getInstance(
3916 + [
3917 + 'ma_identifier' => [
3918 + 'type' => 'elements',
3919 + 'label' => JText::translate('VBO_MESSAGE_TEMPLATE'),
3920 + 'asset_options' => [
3921 + 'placeholder' => JText::translate('VBO_MESSAGE_TEMPLATE'),
3922 + 'allowClear' => false,
3923 + ],
3924 + 'inline' => false,
3925 + 'wrapdivcls' => 'vbo-singleselect-inline-elems-wrap vbo-singleselect-inline-small-icons',
3926 + 'style_selection' => true,
3927 + 'attributes' => [
3928 + 'data-element' => 'message-template',
3929 + ],
3930 + 'elements' => array_map(function($maConfig) {
3931 + if (!empty($maConfig['channel_logo'])) {
3932 + $messTplName = sprintf('%s (%s)', $maConfig['name'], $maConfig['lang']);
3933 + } else {
3934 + $messTplName = sprintf('%s - %s (%s)', $maConfig['channel_name'], $maConfig['name'], $maConfig['lang']);
3935 + }
3936 + return array_filter([
3937 + 'id' => $maConfig['identifier'],
3938 + 'name' => $messTplName,
3939 + 'img_uri' => ($maConfig['channel_logo'] ?? '') ?: null,
3940 + ]);
3941 + }, $messagingAccountConfigurations),
3942 + ],
3943 + ],
3944 + []
3945 + )->setInputName('send_ma_tpl')->getHtml();
3946 + ?>
3947 + <div class="vbo-param-container">
3948 + <div class="vbo-param-label"><?php echo JText::translate('VBOPREVIEW'); ?></div>
3949 + <div class="vbo-param-setting">
3950 + <div class="vbo-ma-send-tplmessage-preview"></div>
3951 + </div>
3952 + </div>
3953 + </div>
3954 + </div>
3955 + </div>
3956 + </div>
3957 + </div>
3958 +</div>
3959 +
3960 +<script type="text/javascript">
3961 +var vbo_print_only = false;
3962 +if (typeof jQuery.fn.tooltip === 'function') {
3963 + jQuery(".hasTooltip").tooltip();
3964 +}
3965 +function vboDisplaySendSMS() {
3966 + var cur_phone = jQuery("#smstophone").val();
3967 + var phone_set = jQuery("#custphone").trigger('vboupdatephonenumber').val();
3968 + if (phone_set.length && phone_set != cur_phone) {
3969 + jQuery("#smstophone").val(phone_set);
3970 + }
3971 +
3972 + // define the modal cancel button
3973 + let cancel_btn = jQuery('<button></button>')
3974 + .attr('type', 'button')
3975 + .addClass('btn')
3976 + .text(Joomla.JText._('VBANNULLA'))
3977 + .on('click', function() {
3978 + VBOCore.emitEvent('vbo-editorder-send-sms-dismiss');
3979 + });
3980 +
3981 + // display modal for email/sms contents
3982 + let modal_body = VBOCore.displayModal({
3983 + suffix: 'editorder-send-sms',
3984 + extra_class: 'vbo-modal-large',
3985 + lock_scroll: true,
3986 + title: Joomla.JText._('VBSENDSMSACTION') + ': ' + (phone_set && phone_set != cur_phone ? phone_set : cur_phone),
3987 + footer_left: cancel_btn,
3988 + footer_right: jQuery('#vbo-modal-footer-sms').find('button').clone(),
3989 + loading_event: 'vbo-editorder-send-sms-loading',
3990 + dismiss_event: 'vbo-editorder-send-sms-dismiss',
3991 + onDismiss: () => {
3992 + jQuery('.vbo-editorder-sms-send-wrap').appendTo('.vbo-editorder-sms-email-send-helper');
3993 + },
3994 + });
3995 +
3996 + jQuery('.vbo-editorder-sms-send-wrap').appendTo(modal_body);
3997 +}
3998 +function vboDisplaySendEmail() {
3999 + var cur_email = jQuery("#emailto").val();
4000 + var email_set = jQuery("#custmail").val();
4001 + if (email_set.length && email_set != cur_email) {
4002 + jQuery("#emailto").val(email_set);
4003 + }
4004 +
4005 + // define the modal cancel button
4006 + let cancel_btn = jQuery('<button></button>')
4007 + .attr('type', 'button')
4008 + .addClass('btn')
4009 + .text(Joomla.JText._('VBANNULLA'))
4010 + .on('click', function() {
4011 + VBOCore.emitEvent('vbo-editorder-send-email-dismiss');
4012 + });
4013 +
4014 + // display modal for email/sms contents
4015 + let modal_body = VBOCore.displayModal({
4016 + suffix: 'editorder-send-email',
4017 + extra_class: 'vbo-modal-large',
4018 + lock_scroll: true,
4019 + title: Joomla.JText._('VBSENDEMAILACTION') + ': ' + (email_set && email_set != cur_email ? email_set : cur_email),
4020 + footer_left: cancel_btn,
4021 + footer_right: jQuery('#vbo-modal-footer-email').find('button').clone(),
4022 + loading_event: 'vbo-editorder-send-email-loading',
4023 + dismiss_event: 'vbo-editorder-send-email-dismiss',
4024 + onDismiss: () => {
4025 + jQuery('.vbo-editorder-email-send-wrap').appendTo('.vbo-editorder-sms-email-send-helper');
4026 + },
4027 + });
4028 +
4029 + jQuery('.vbo-editorder-email-send-wrap').appendTo(modal_body);
4030 +}
4031 +function vboKeyupEmail(event) {
4032 + if (event.key && event.key == 'Enter') {
4033 + event.preventDefault();
4034 + document.adminForm.submit();
4035 + return;
4036 + }
4037 + jQuery('.vbo-bookingdet-save-email').show();
4038 +}
4039 +function setSpecialTplTag(taid, tpltag) {
4040 + var tplobj = document.getElementById(taid);
4041 + if (tplobj != null) {
4042 + var start = tplobj.selectionStart;
4043 + var end = tplobj.selectionEnd;
4044 + tplobj.value = tplobj.value.substring(0, start) + tpltag + tplobj.value.substring(end);
4045 + tplobj.selectionStart = tplobj.selectionEnd = start + tpltag.length;
4046 + tplobj.focus();
4047 + }
4048 +}
4049 +jQuery(function() {
4050 + // register to the event emitted when a new payment is made through the virtual terminal widget
4051 + document.addEventListener('vbo_new_payment_transaction', (e) => {
4052 + if (!e || !e.detail || !e.detail.hasOwnProperty('tn') || !e.detail['tn']) {
4053 + // do nothing
4054 + return;
4055 + }
4056 + // reload the page to display the updated information
4057 + location.reload();
4058 + });
4059 + // register to the event emitted when a booking is modified through an admin widget
4060 + document.addEventListener('vbo_booking_modified', (e) => {
4061 + if (!e || !e.detail || !e.detail.hasOwnProperty('bid') || !e.detail['bid']) {
4062 + // do nothing
4063 + return;
4064 + }
4065 + // reload the page to display the new information about the booking just modified
4066 + location.reload();
4067 + });
4068 + // register click event for the button to see the quote details
4069 + document.querySelector('.vbo-quote-details-btn')?.addEventListener('click', (e) => {
4070 + VBOCore.handleDisplayWidgetNotification({widget_id: 'quotes'}, {bid: <?php echo $row['id']; ?>});
4071 + });
4072 + // remove overbooking flag
4073 + jQuery('.vbo-label-overbooking').on('click', function() {
4074 + if (confirm(Joomla.JText._('VBO_CONF_RM_OVERBOOKING_FLAG'))) {
4075 + VBOCore.doAjax(
4076 + "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=bookings.delete_type_flag'); ?>",
4077 + {
4078 + bid: '<?php echo $row['id']; ?>',
4079 + flag: 'overbooking',
4080 + },
4081 + (success) => {
4082 + // remove "overbooking" label
4083 + let parent_label = jQuery('.vbo-bookdet-container').find('.vbo-label-overbooking').parent('.label');
4084 + jQuery('.vbo-bookdet-container').find('.vbo-label-overbooking').remove();
4085 + parent_label.text(parent_label.text().replace(' / ', ''));
4086 + },
4087 + (error) => {
4088 + alert(error.responseText);
4089 + }
4090 + );
4091 + }
4092 + });
4093 + // sessionStorage for current tab
4094 + if (typeof sessionStorage !== 'undefined' && !window.location.hash && <?php echo $printreceipt ? 'false' : 'true'; ?>) {
4095 + var curtab = sessionStorage.getItem('vboEditOrderTab<?php echo $row['id']; ?>');
4096 +
4097 + setTimeout(() => {
4098 + let link = jQuery('.vbo-bookingdet-noteslogs-btn[data-id="' + curtab + '"] a');
4099 +
4100 + if (link.length) {
4101 + jQuery(".vbo-bookingdet-tab[data-vbotab='vbo-tab-admin']").trigger('click');
4102 + link.trigger('click');
4103 + }
4104 + }, 128);
4105 + }
4106 + if (window.location.hash == '#tab-admin') {
4107 + setTimeout(function() {
4108 + jQuery(".vbo-bookingdet-tab[data-vbotab='vbo-tab-admin']").trigger('click');
4109 + }, 100);
4110 + }
4111 + // Search customer - Start
4112 + var vbocustsdelay = (function() {
4113 + var timer = 0;
4114 + return function(callback, ms) {
4115 + clearTimeout(timer);
4116 + timer = setTimeout(callback, ms);
4117 + };
4118 + })();
4119 + function vboCustomerSearch(words) {
4120 + jQuery("#vbo-searchcust-res").hide().html("");
4121 + jQuery("#vbo-searchcust-loading").show();
4122 + var jqxhr = jQuery.ajax({
4123 + type: "POST",
4124 + url: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=searchcustomer'); ?>",
4125 + data: {
4126 + kw: words,
4127 + tmpl: "component"
4128 + }
4129 + }).done(function(cont) {
4130 + if (cont) {
4131 + var obj_res = typeof cont === 'string' ? JSON.parse(cont) : cont;
4132 + customers_search_vals = obj_res[0];
4133 + jQuery("#vbo-searchcust-res").html(obj_res[1]);
4134 + } else {
4135 + customers_search_vals = "";
4136 + jQuery("#vbo-searchcust-res").html("----");
4137 + }
4138 + jQuery("#vbo-searchcust-res").show();
4139 + jQuery("#vbo-searchcust-loading").hide();
4140 + }).fail(function() {
4141 + jQuery("#vbo-searchcust-loading").hide();
4142 + alert("Error Searching.");
4143 + });
4144 + }
4145 + jQuery("#vbo-searchcust").keyup(function(event) {
4146 + vbocustsdelay(function() {
4147 + var keywords = jQuery("#vbo-searchcust").val();
4148 + var chars = keywords.length;
4149 + if (chars > 1) {
4150 + if ((event.which > 96 && event.which < 123) || (event.which > 64 && event.which < 91) || event.which == 13) {
4151 + vboCustomerSearch(keywords);
4152 + }
4153 + } else {
4154 + if (jQuery("#vbo-searchcust-res").is(":visible")) {
4155 + jQuery("#vbo-searchcust-res").hide();
4156 + }
4157 + }
4158 + }, 600);
4159 + });
4160 + jQuery("body").on("click", ".vbo-custsearchres-entry", function() {
4161 + var custid = jQuery(this).attr("data-custid");
4162 + if (confirm('<?php echo addslashes(JText::translate('VBOASSIGNNEWCUSTCONF')); ?>')) {
4163 + jQuery('#newcustid').val(custid);
4164 + document.adminForm.submit();
4165 + return;
4166 + }
4167 + });
4168 + // Search customer - End
4169 + jQuery(".vbo-bookingdet-tab").click(function() {
4170 + var newtabrel = jQuery(this).attr('data-vbotab');
4171 + var oldtabrel = jQuery(".vbo-bookingdet-tab-active").attr('data-vbotab');
4172 + if (newtabrel == oldtabrel) {
4173 + return;
4174 + }
4175 + if (newtabrel == 'vbo-tab-details' && typeof sessionStorage !== 'undefined') {
4176 + sessionStorage.setItem('vboEditOrderTab<?php echo $row['id']; ?>', 'details');
4177 + }
4178 + jQuery(".vbo-bookingdet-tab").removeClass("vbo-bookingdet-tab-active");
4179 + jQuery(this).addClass("vbo-bookingdet-tab-active");
4180 + jQuery("#"+oldtabrel).hide();
4181 + jQuery("#"+newtabrel).fadeIn();
4182 + jQuery("#vbo_active_tab").val(newtabrel);
4183 + });
4184 + jQuery(".vbo-bookingdet-tab[data-vbotab='<?php echo $pactive_tab; ?>']").trigger('click');
4185 + // edit amount paid
4186 + jQuery('#vbo-amountpaid-edit').click(function() {
4187 + jQuery('#vbo-amountpaid-cont').hide();
4188 + jQuery('#vbo-amountpaid-modcont').show();
4189 + jQuery('input[name="newamountpaid"]').prop('disabled', false);
4190 + if (jQuery('input[name="newamountrefunded"]').length) {
4191 + jQuery('input[name="newamountrefunded"]').val('');
4192 + }
4193 + });
4194 + jQuery('#vbo-amountpaid-cancedit').click(function() {
4195 + jQuery('#vbo-amountpaid-modcont').hide();
4196 + jQuery('#vbo-amountpaid-cont').show();
4197 + });
4198 + // edit amount refunded
4199 + jQuery('#vbo-amountrefunded-edit').click(function() {
4200 + jQuery('#vbo-amountrefunded-cont').hide();
4201 + jQuery('#vbo-amountrefunded-modcont').show();
4202 + jQuery('input[name="newamountrefunded"]').prop('disabled', false);
4203 + if (jQuery('input[name="newamountpaid"]').length) {
4204 + jQuery('input[name="newamountpaid"]').val('');
4205 + }
4206 + });
4207 + jQuery('#vbo-amountrefunded-cancedit').click(function() {
4208 + jQuery('#vbo-amountrefunded-modcont').hide();
4209 + jQuery('#vbo-amountrefunded-cont').show();
4210 + });
4211 + // edit amount payable
4212 + jQuery('#vbo-amountpayable-edit').click(function() {
4213 + jQuery('#vbo-amountpayable-cont').hide();
4214 + jQuery('#vbo-amountpayable-modcont').show();
4215 + jQuery('input[name="newamountpayable"]').prop('disabled', false);
4216 + });
4217 + jQuery('#vbo-amountpayable-cancedit').click(function() {
4218 + jQuery('#vbo-amountpayable-modcont').hide();
4219 + jQuery('#vbo-amountpayable-cont').show();
4220 + });
4221 + // edit cancellation fee
4222 + jQuery('#vbo-cancfee-edit').click(function() {
4223 + jQuery('#vbo-cancfee-cont').hide();
4224 + jQuery('#vbo-cancfee-modcont').show();
4225 + jQuery('input[name="newcancfee"]').prop('disabled', false);
4226 + });
4227 + jQuery('#vbo-cancfee-cancedit').click(function() {
4228 + jQuery('#vbo-cancfee-modcont').hide();
4229 + jQuery('#vbo-cancfee-cont').show();
4230 + });
4231 + // chat listener
4232 + if (typeof VCMChat !== 'undefined') {
4233 + jQuery(window).on('chatsync', function(e) {
4234 + if (!jQuery("#vcm-chat-audio-notification").length) {
4235 + 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>");
4236 + }
4237 + try {
4238 + var promise = document.getElementById('vcm-audio-notification').play();
4239 + console.log(promise);
4240 + } catch (err) {
4241 + console.warn('Could not play sound', err);
4242 + }
4243 + });
4244 + }
4245 +
4246 + // zoom-able avatars
4247 + jQuery('.vbo-customer-info-box-avatar').each(function() {
4248 + var img = jQuery(this).find('img');
4249 + if (!img.length) {
4250 + return;
4251 + }
4252 + // register click listener
4253 + img.on('click', function(e) {
4254 + // stop events propagation
4255 + e.preventDefault();
4256 + e.stopPropagation();
4257 +
4258 + // check for caption
4259 + var caption = jQuery(this).attr('data-caption');
4260 +
4261 + // build modal content
4262 + var zoom_modal = jQuery('<div></div>').addClass('vbo-modal-overlay-block vbo-modal-overlay-zoom-image').css('display', 'block');
4263 + var zoom_dismiss = jQuery('<a></a>').addClass('vbo-modal-overlay-close');
4264 + zoom_dismiss.on('click', function() {
4265 + jQuery('.vbo-modal-overlay-zoom-image').fadeOut();
4266 + });
4267 + zoom_modal.append(zoom_dismiss);
4268 + var zoom_content = jQuery('<div></div>').addClass('vbo-modal-overlay-content vbo-modal-overlay-content-zoom-image');
4269 + var zoom_head = jQuery('<div></div>').addClass('vbo-modal-overlay-content-head');
4270 + var zoom_head_title = jQuery('<span></span>');
4271 + if (caption) {
4272 + zoom_head_title.text(caption);
4273 + }
4274 + var zoom_head_close = jQuery('<span></span>').addClass('vbo-modal-overlay-close-times').html('&times;');
4275 + zoom_head_close.on('click', function() {
4276 + jQuery('.vbo-modal-overlay-zoom-image').fadeOut();
4277 + });
4278 + zoom_head.append(zoom_head_title).append(zoom_head_close);
4279 + var zoom_body = jQuery('<div></div>').addClass('vbo-modal-overlay-content-body vbo-modal-overlay-content-body-scroll');
4280 + var zoom_image = jQuery('<div></div>').addClass('vbo-modal-zoom-image-wrap');
4281 + zoom_image.append(jQuery(this).clone());
4282 + zoom_body.append(zoom_image);
4283 + zoom_content.append(zoom_head).append(zoom_body);
4284 + zoom_modal.append(zoom_content);
4285 + // append modal to body
4286 + if (jQuery('.vbo-modal-overlay-zoom-image').length) {
4287 + jQuery('.vbo-modal-overlay-zoom-image').remove();
4288 + }
4289 + jQuery('body').append(zoom_modal);
4290 + });
4291 + });
4292 +
4293 + // emit the event to read all notifications in the current context
4294 + VBOCore.emitEvent('vbo-nc-read-notifications', {
4295 + criteria: {
4296 + group: '<?php echo !empty($row['idorderota']) && !empty($row['channel']) ? 'otas' : 'website'; ?>',
4297 + idorder: '<?php echo $row['id']; ?>',
4298 + }
4299 + });
4300 +
4301 + // register click event on the booking task(s)
4302 + document.querySelectorAll('.vbo-bookingdet-task-details[data-task-id]').forEach((task) => {
4303 + const taskId = task.getAttribute('data-task-id');
4304 + task.addEventListener('click', (e) => {
4305 + e.stopPropagation();
4306 + // define the modal cancel button
4307 + let cancel_btn = jQuery('<button></button>')
4308 + .attr('type', 'button')
4309 + .addClass('btn')
4310 + .text(Joomla.JText._('VBOCLOSE'))
4311 + .on('click', () => {
4312 + VBOCore.emitEvent('vbo-tm-edittask-dismiss');
4313 + });
4314 +
4315 + // define the modal save button
4316 + let save_btn = jQuery('<button></button>')
4317 + .attr('type', 'button')
4318 + .addClass('btn btn-success')
4319 + .text(Joomla.JText._('VBSAVE'))
4320 + .on('click', function() {
4321 + // disable button to prevent double submissions
4322 + let submit_btn = jQuery(this);
4323 + submit_btn.prop('disabled', true);
4324 +
4325 + // start loading animation
4326 + VBOCore.emitEvent('vbo-tm-edittask-loading');
4327 +
4328 + // get form data
4329 + const taskForm = new FormData(document.querySelector('#vbo-tm-task-manage-form'));
4330 +
4331 + // build query parameters for the request
4332 + let qpRequest = new URLSearchParams(taskForm);
4333 +
4334 + // make sure the request always includes the assignees query parameter, even if the list is empty
4335 + if (!qpRequest.has('data[assignees][]')) {
4336 + qpRequest.append('data[assignees][]', []);
4337 + }
4338 +
4339 + // make sure the request always includes the tags query parameter, even if the list is empty
4340 + if (!qpRequest.has('data[tags][]')) {
4341 + qpRequest.append('data[tags][]', []);
4342 + }
4343 +
4344 + // make the request
4345 + VBOCore.doAjax(
4346 + "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=taskmanager.updateTask'); ?>",
4347 + qpRequest.toString(),
4348 + (resp) => {
4349 + // dismiss the modal on success
4350 + VBOCore.emitEvent('vbo-tm-edittask-dismiss');
4351 +
4352 + // reload the page
4353 + location.reload();
4354 + },
4355 + (error) => {
4356 + // display error message
4357 + alert(error.responseText);
4358 +
4359 + // re-enable submit button
4360 + submit_btn.prop('disabled', false);
4361 +
4362 + // stop loading
4363 + VBOCore.emitEvent('vbo-tm-edittask-loading');
4364 + }
4365 + );
4366 + });
4367 +
4368 + // display modal
4369 + let modalBody = VBOCore.displayModal({
4370 + suffix: 'tm_edittask_modal',
4371 + title: <?php echo json_encode(JText::translate('VBO_TASK')); ?> + ' #' + taskId,
4372 + extra_class: 'vbo-modal-rounded vbo-modal-taller vbo-modal-large',
4373 + body_prepend: true,
4374 + lock_scroll: true,
4375 + escape_dismiss: false,
4376 + footer_left: cancel_btn,
4377 + footer_right: save_btn,
4378 + loading_event: 'vbo-tm-edittask-loading',
4379 + dismiss_event: 'vbo-tm-edittask-dismiss',
4380 + });
4381 +
4382 + // start loading animation
4383 + VBOCore.emitEvent('vbo-tm-edittask-loading');
4384 +
4385 + // make the request
4386 + VBOCore.doAjax(
4387 + "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=taskmanager.renderLayout'); ?>",
4388 + {
4389 + type: 'tasks.managetask',
4390 + data: {
4391 + task_id: taskId,
4392 + form_id: 'vbo-tm-task-manage-form',
4393 + },
4394 + },
4395 + (resp) => {
4396 + // stop loading
4397 + VBOCore.emitEvent('vbo-tm-edittask-loading');
4398 +
4399 + try {
4400 + // decode the response (if needed), and append the content to the modal body
4401 + let obj_res = typeof resp === 'string' ? JSON.parse(resp) : resp;
4402 + modalBody.append(obj_res['html']);
4403 + } catch (err) {
4404 + console.error('Error decoding the response', err, resp);
4405 + }
4406 + },
4407 + (error) => {
4408 + // display error message
4409 + alert(error.responseText);
4410 +
4411 + // stop loading
4412 + VBOCore.emitEvent('vbo-tm-edittask-loading');
4413 + }
4414 + );
4415 + });
4416 + });
4417 +
4418 + // register click event to copy the OTA booking ID
4419 + const otaBidEl = document.querySelector('.vbo-reservation-copy-otabid');
4420 + if (otaBidEl) {
4421 + otaBidEl.addEventListener('click', () => {
4422 + let copyEl = document.querySelector('textarea.vbo-textarea-copyable[data-copy="otabid"]');
4423 + VBOCore.copyToClipboard(copyEl).then((success) => {
4424 + otaBidEl.setAttribute('data-tooltiptext', <?php echo json_encode(JText::translate('VBO_COPIED') . '!'); ?>);
4425 + }).catch((err) => {
4426 + // do nothing
4427 + });
4428 + });
4429 + }
4430 +
4431 + // register events for sending a message template through a messaging account configuration
4432 + const messagingAccountsData = <?php echo json_encode($messagingAccountConfigurations); ?>;
4433 + const sendTplMessBtn = document.querySelector('.vbo-bookingdet-send-tplmessage-btn');
4434 + const sendTplMessContWrap = document.querySelector('.vbo-bookingdet-send-tplmessage-wrap');
4435 + jQuery(sendTplMessContWrap).find('select[data-element="message-template"]').on('change', function() {
4436 + let maIdentifier = this.value;
4437 + let previewEl = sendTplMessContWrap.querySelector('.vbo-ma-send-tplmessage-preview');
4438 + previewEl.innerHTML = '';
4439 + if (maIdentifier) {
4440 + messagingAccountsData.forEach((maData) => {
4441 + if (maData?.identifier == maIdentifier) {
4442 + // update preview content
4443 + previewEl.innerHTML = maData?.preview_html || '';
4444 + }
4445 + });
4446 + }
4447 + });
4448 + if (sendTplMessBtn) {
4449 + sendTplMessBtn.addEventListener('click', () => {
4450 + let cancelBtn = document.createElement('button');
4451 + cancelBtn.setAttribute('type', 'button');
4452 + cancelBtn.classList.add('btn');
4453 + cancelBtn.textContent = <?php echo json_encode(JText::translate('VBANNULLA')); ?>;
4454 + cancelBtn.addEventListener('click', () => {
4455 + VBOCore.emitEvent('vbo-send-tplmessage-dismiss');
4456 + });
4457 +
4458 + let confirmBtn = document.createElement('button');
4459 + confirmBtn.setAttribute('type', 'button');
4460 + confirmBtn.classList.add('btn', 'btn-primary');
4461 + confirmBtn.innerHTML = '<?php VikBookingIcons::e('paper-plane'); ?> ' + <?php echo json_encode(JText::translate('VBO_SEND_MESSAGE')); ?>;
4462 + confirmBtn.addEventListener('click', () => {
4463 + // get message template identifier data
4464 + let tplIdentifier = sendTplMessContWrap.querySelector('select[data-element="message-template"]')?.value;
4465 + if (!tplIdentifier) {
4466 + alert('Invalid message template');
4467 + return;
4468 + }
4469 +
4470 + // obtain selected template details
4471 + let tplIdentifierParts = tplIdentifier.split(':');
4472 +
4473 + // start loading
4474 + VBOCore.emitEvent('vbo-send-tplmessage-loading');
4475 + confirmBtn.disabled = true;
4476 +
4477 + // make the request
4478 + VBOCore.doAjax(
4479 + "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=messaging.sendMessageTemplate'); ?>",
4480 + {
4481 + account_id: tplIdentifierParts[0],
4482 + phone_id: tplIdentifierParts[1],
4483 + config_id: tplIdentifierParts[2],
4484 + booking_id: <?php echo $this->row['id']; ?>,
4485 + },
4486 + (resp) => {
4487 + // dismiss modal on success
4488 + VBOCore.emitEvent('vbo-send-tplmessage-dismiss');
4489 +
4490 + // display success message
4491 + VBOToast.enqueue(new VBOToastMessage({
4492 + body: <?php echo json_encode(JText::translate('VBSENDEMAILOK')); ?>,
4493 + icon: '<?php echo VikBookingIcons::i('check-circle'); ?>',
4494 + status: VBOToast.SUCCESS_STATUS,
4495 + action: () => {
4496 + VBOToast.dispose(true);
4497 + },
4498 + }));
4499 +
4500 + // reload the page (just for the new history event)
4501 + location.reload();
4502 + },
4503 + (error) => {
4504 + // display error message
4505 + alert(error.responseText);
4506 +
4507 + // stop loading
4508 + VBOCore.emitEvent('vbo-send-tplmessage-loading');
4509 + confirmBtn.disabled = false;
4510 + }
4511 + );
4512 + });
4513 +
4514 + let modalBody = VBOCore.displayModal({
4515 + suffix: 'vbo-send-tplmessage',
4516 + extra_class: 'vbo-modal-rounded',
4517 + title: <?php echo json_encode(JText::translate('VBO_SEND_MESSAGE')); ?>,
4518 + footer_left: cancelBtn,
4519 + footer_right: confirmBtn,
4520 + draggable: true,
4521 + lock_scroll: true,
4522 + dismiss_event: 'vbo-send-tplmessage-dismiss',
4523 + loading_event: 'vbo-send-tplmessage-loading',
4524 + onDismiss: () => {
4525 + document.querySelector('.vbo-bookingdet-send-tplmessage-helper').append(
4526 + sendTplMessContWrap
4527 + );
4528 + },
4529 + });
4530 +
4531 + (modalBody[0] || modalBody).append(sendTplMessContWrap);
4532 + });
4533 + }
4534 +
4535 +});
4536 +var cur_emtpl = <?php echo json_encode($cur_emtpl); ?>;
4537 +function vboLoadEmailTpl(tplind) {
4538 + if (!(tplind.length > 0)) {
4539 + jQuery('#emailsubj').val('');
4540 + jQuery('#emailcont').val('').trigger('change');
4541 + return true;
4542 + }
4543 + if (tplind.substr(0, 2) == 'rm') {
4544 + if (confirm(Joomla.JText._('VBDELCONFIRM'))) {
4545 + document.location.href = 'index.php?option=com_vikbooking&task=rmcustomemailtpl&cid[]=<?php echo $row['id']; ?>&tplind='+tplind.substr(2);
4546 + }
4547 + return false;
4548 + }
4549 + if (!cur_emtpl.hasOwnProperty(tplind)) {
4550 + jQuery('#emailsubj').val('');
4551 + jQuery('#emailcont').val('').trigger('change');
4552 + return true;
4553 + }
4554 + jQuery('#emailsubj').val(cur_emtpl[tplind]['emailsubj']);
4555 + jQuery('#emailcont').val(cur_emtpl[tplind]['emailcont']).trigger('change');
4556 + jQuery('#emailfrom').val(cur_emtpl[tplind]['emailfrom']);
4557 + return true;
4558 +}
4559 +<?php
4560 +$pcustomemail = VikRequest::getInt('customemail', '', 'request');
4561 +if ($pcustomemail > 0) {
4562 + ?>
4563 + vboDisplaySendEmail();
4564 + <?php
4565 +}
4566 +if ($printreceipt) {
4567 + ?>
4568 +jQuery(function() {
4569 + jQuery('button, .vbo-bookingdet-innertop').hide();
4570 + jQuery('body').find('a').each(function(k, v) {
4571 + jQuery(this).replaceWith(jQuery(this).html());
4572 + });
4573 + jQuery('body').find("input[type='text']").each(function(k, v) {
4574 + jQuery(this).replaceWith(jQuery(this).val());
4575 + });
4576 +});
4577 +function vboMakePrintOnly() {
4578 + vbo_print_only = true;
4579 + jQuery(".vbo-receipt-numdate-block").remove();
4580 + jQuery("#vbo-receipt-print-btn-name").text("<?php echo addslashes(JText::translate('VBOPRINT')); ?>");
4581 +}
4582 +function vboLaunchPrintReceipt() {
4583 + var rcnotes = jQuery('#vbo-receipt-notes').val();
4584 + var rnewnum = jQuery('#vbo-receipt-num-inp').val();
4585 + if (rcnotes.length) {
4586 + if (rcnotes.indexOf('<') < 0) {
4587 + rcnotes = rcnotes.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1<br />$2');
4588 + }
4589 + jQuery('#vbo-receipt-notes-val').html(rcnotes);
4590 + } else {
4591 + jQuery('.vbo-receipt-notes-container').remove();
4592 + }
4593 + if (vbo_print_only === true) {
4594 + window.print();
4595 + return;
4596 + }
4597 + jQuery.ajax({
4598 + type: "POST",
4599 + url: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=updatereceiptnum'); ?>",
4600 + data: {
4601 + newnum: rnewnum,
4602 + newnotes: rcnotes,
4603 + oid: "<?php echo $row['id']; ?>"
4604 + }
4605 + }).done(function(res) {
4606 + window.print();
4607 + }).fail(function() {
4608 + alert('Could not update the next receipt number.')
4609 + window.print();
4610 + });
4611 +}
4612 + <?php
4613 +}
4614 +?>
4615 +</script>