PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.21
VikAppointments Services Booking Calendar v1.2.21
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / admin / views / reservations / tmpl / default.php
vikappointments / admin / views / reservations / tmpl Last commit date
default.php 4 days ago index.html 4 days ago
default.php
1150 lines
1 <?php
2 /**
3 * @package VikAppointments
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 JHtml::fetch('bootstrap.tooltip', '.hasTooltip');
15 JHtml::fetch('formbehavior.chosen');
16 JHtml::fetch('vaphtml.status.contextmenu', 'appointments', '.status-hndl');
17
18 $rows = $this->rows;
19
20 $filters = $this->filters;
21
22 $vik = VAPApplication::getInstance();
23
24 $user = JFactory::getUser();
25
26 $config = VAPFactory::getConfig();
27 $currency = VAPFactory::getCurrency();
28
29 $canEdit = $user->authorise('core.edit', 'com_vikappointments');
30 $canEditState = $user->authorise('core.edit.state', 'com_vikappointments');
31
32 $is_searching = $this->hasFilters();
33 $is_disabled = $filters['res_id'] > 0 ? 'disabled="disabled"' : '';
34
35 /**
36 * Trigger event to display custom HTML.
37 * In case it is needed to include any additional fields,
38 * it is possible to create a plugin and attach it to an event
39 * called "onDisplayViewReservationsList". The event method receives the
40 * view instance as argument.
41 *
42 * @since 1.6.6
43 */
44 $forms = $this->onDisplayListView($is_searching);
45
46 /**
47 * Prepares CodeMirror editor scripts for being used
48 * via Javascript/AJAX.
49 *
50 * @wponly
51 */
52 $vik->prepareEditor('codemirror');
53
54 // get listable columns
55 $listable_fields = VikAppointments::getListableFields();
56 // get custom fields that should be displayed in the list
57 $listable_cf = VikAppointments::getListableFields($custom = true);
58
59 // get default user timezone
60 $default_tz = JFactory::getUser()->getTimezone();
61
62 $multi_orders_cols = 0;
63
64 ?>
65
66 <form action="index.php?option=com_vikappointments" method="post" name="adminForm" id="adminForm">
67
68 <div class="btn-toolbar" style="height: 32px;">
69
70 <div class="btn-group pull-left input-append">
71 <input type="text" name="keysearch" id="vapkeysearch" class="vapkeysearch" size="32" <?php echo $is_disabled; ?>
72 value="<?php echo $this->escape($filters['keysearch']); ?>" placeholder="<?php echo $this->escape(JText::translate('JSEARCH_FILTER_SUBMIT')); ?>" />
73
74 <button type="submit" class="btn">
75 <i class="fas fa-search"></i>
76 </button>
77 </div>
78
79 <!-- Define role to detect the supported hook -->
80 <!-- {"rule":"customizer","event":"onDisplayViewReservationsList","type":"search","key":"search"} -->
81
82 <?php
83 if ($filters['res_id'] == 0)
84 {
85 // plugins can use the "search" key to introduce custom
86 // filters within the search bar
87 if (isset($forms['search']))
88 {
89 echo $forms['search'];
90 }
91 }
92 ?>
93
94 <div class="btn-group pull-left">
95 <button type="button" class="btn<?php echo ($is_searching ? ' btn-primary' : ''); ?><?php echo ($filters['res_id'] ? ' disabled' : ''); ?>"
96 <?php echo $is_disabled; ?> onclick="vapToggleSearchToolsButton(this);">
97 <?php echo JText::translate('JSEARCH_TOOLS'); ?>&nbsp;<i class="fas fa-caret-<?php echo ($is_searching ? 'up' : 'down'); ?>" id="vap-tools-caret"></i>
98 </button>
99 </div>
100
101 <div class="btn-group pull-left">
102 <button type="button" class="btn" onclick="clearFilters();">
103 <?php echo JText::translate($filters['res_id'] ? 'JTOOLBAR_BACK' : 'JSEARCH_FILTER_CLEAR'); ?>
104 </button>
105 </div>
106
107 <?php
108 if ($filters['res_id'] && count($rows))
109 {
110 ?>
111 <div class="btn-group pull-right">
112 <a href="<?php echo $vik->addUrlCsrf('index.php?option=com_vikappointments&task=reservation.notify&cid[]=' . $filters['res_id'], $xhtml = true); ?>" class="btn btn-primary">
113 <i class="fas fa-paper-plane"></i>&nbsp;
114 <?php echo JText::translate('VAPMANAGERESERVATION31'); ?>
115 </a>
116 </div>
117 <?php
118 }
119
120 if (($filters['res_id'] || count($rows) == 1) && $rows && strlen((string) $rows[0]['cc_data']))
121 {
122 ?>
123 <div class="btn-group pull-right">
124 <button type="button" class="btn btn-primary" onclick="vapOpenJModal('ccdetails', null, true); return false;">
125 <i class="fas fa-credit-card"></i>&nbsp;
126 <?php echo JText::translate('VAPSEECCDETAILS'); ?>
127 </button>
128 </div>
129 <?php
130 }
131 ?>
132
133 </div>
134
135 <?php
136 /**
137 * Display search tools only in case we are not focusing a single order.
138 *
139 * @since 1.6.3
140 */
141 if ($filters['res_id'] == 0)
142 {
143 ?>
144 <div class="btn-toolbar" id="vap-search-tools" style="height: 32px;<?php echo ($is_searching ? '' : 'display: none;'); ?>">
145
146 <?php
147 $options = JHtml::fetch('vaphtml.admin.statuscodes', $group = 'appointments', $blank = true);
148 // add closure status to the list
149 $options[] = JHtml::fetch('select.option', 'CLOSURE', 'VAPSTATUSCLOSURE');
150 ?>
151 <div class="btn-group pull-left">
152 <select name="status" id="vap-status-sel" class="<?php echo (!empty($filters['status']) ? 'active' : ''); ?>" onchange="document.adminForm.submit();">
153 <?php echo JHtml::fetch('select.options', $options, 'value', 'text', $filters['status'], true); ?>
154 </select>
155 </div>
156
157 <?php
158 $options = JHtml::fetch('vaphtml.admin.payments', $type = 'appointments', $blank = true);
159
160 /**
161 * Display payments filter only in case of non-empty list.
162 * Must be greater than 1 because the list includes an empty option.
163 *
164 * @since 1.6.3
165 */
166 if (count($options) > 1)
167 {
168 ?>
169 <div class="btn-group pull-left">
170 <select name="id_payment" id="vap-payment-sel" class="<?php echo (!empty($filters['id_payment']) ? 'active' : ''); ?>" onchange="document.adminForm.submit();">
171 <?php echo JHtml::fetch('select.options', $options, 'value', 'text', $filters['id_payment'], true); ?>
172 </select>
173 </div>
174 <?php
175 }
176 ?>
177
178 <?php
179 $options = JHtml::fetch('vaphtml.admin.locations', $id = null, $blank = true);
180
181 /**
182 * Display locations filter only in case of non-empty list.
183 * Must be greater than 1 because the list includes an empty option.
184 *
185 * @since 1.7
186 */
187 if (count($options) > 1)
188 {
189 ?>
190 <div class="btn-group pull-left">
191 <select name="id_location" id="vap-location-sel" class="<?php echo (!empty($filters['id_location']) ? 'active' : ''); ?>" onchange="document.adminForm.submit();">
192 <?php echo JHtml::fetch('select.options', $options, 'value', 'text', $filters['id_location'], true); ?>
193 </select>
194 </div>
195 <?php
196 }
197 ?>
198
199 <!-- Define role to detect the supported hook -->
200 <!-- {"rule":"customizer","event":"onDisplayViewReservationsList","type":"search","key":"filters"} -->
201
202 <?php
203 // plugins can use the "filters" key to introduce custom
204 // filters within the search tools
205 if (isset($forms['filters']))
206 {
207 echo $forms['filters'];
208 }
209 ?>
210
211 <div class="btn-group pull-left">
212 <?php echo $vik->calendar($filters['datestart'], 'datestart', 'vapdatestart', null, array('onChange' => 'document.adminForm.submit();')); ?>
213 </div>
214
215 <?php
216 if (!VAPDateHelper::isNull($filters['datestart']))
217 {
218 ?>
219 <div class="btn-group pull-left">
220 <?php echo $vik->calendar($filters['dateend'], 'dateend', 'vapdateend', null, array('onChange' => 'document.adminForm.submit();')); ?>
221 </div>
222 <?php
223 }
224 ?>
225
226 </div>
227 <?php
228 }
229
230 if (count($rows) == 0)
231 {
232 echo $vik->alert(JText::translate('JGLOBAL_NO_MATCHING_RESULTS'));
233 }
234 else
235 {
236 /**
237 * Trigger event to display custom columns.
238 *
239 * @since 1.7
240 */
241 $columns = $this->onDisplayTableColumns();
242 ?>
243
244 <!-- Define role to detect the supported hook -->
245 <!-- {"rule":"customizer","event":"onDisplayReservationsTableTH","type":"th"} -->
246
247 <!-- Define role to detect the supported hook -->
248 <!-- {"rule":"customizer","event":"onDisplayReservationsTableTD","type":"td"} -->
249
250 <table cellpadding="4" cellspacing="0" border="0" width="100%" class="<?php echo $vik->getAdminTableClass(); ?>">
251 <?php echo $vik->openTableHead(); ?>
252 <tr>
253
254 <th width="1%">
255 <?php echo $vik->getAdminToggle(count($rows)); ?>
256 </th>
257
258 <?php
259 if (in_array('id', $listable_fields))
260 {
261 ?>
262 <th class="<?php echo $vik->getAdminThClass('left nowrap hidden-phone'); ?>" width="1%" style="text-align: left;">
263 <?php echo JHtml::fetch('vaphtml.admin.sort', 'VAPMANAGERESERVATION0', 'r.id', $this->orderDir, $this->ordering); ?>
264 </th>
265 <?php
266 }
267
268 if (in_array('sid', $listable_fields))
269 {
270 ?>
271 <th class="<?php echo $vik->getAdminThClass('left hidden-phone'); ?>" width="10%" style="text-align: left;">
272 <?php echo JHtml::fetch('vaphtml.admin.sort', 'VAPMANAGERESERVATION2', 'r.createdon', $this->orderDir, $this->ordering); ?>
273 </th>
274 <?php
275 }
276
277 if (in_array('checkin_ts', $listable_fields))
278 {
279 $multi_orders_cols++;
280 ?>
281 <th class="<?php echo $vik->getAdminThClass('left'); ?>" width="10%" style="text-align: left;">
282 <?php echo JHtml::fetch('vaphtml.admin.sort', 'VAPMANAGERESERVATION26', 'r.checkin_ts', $this->orderDir, $this->ordering); ?>
283 </th>
284 <?php
285 }
286
287 if (in_array('employee', $listable_fields))
288 {
289 $multi_orders_cols++;
290 ?>
291 <th class="<?php echo $vik->getAdminThClass('left'); ?>" width="10%" style="text-align: left;">
292 <?php echo JHtml::fetch('vaphtml.admin.sort', 'VAPMANAGERESERVATION3', 'e.nickname', $this->orderDir, $this->ordering); ?>
293 </th>
294 <?php
295 }
296
297 if (in_array('service', $listable_fields))
298 {
299 $multi_orders_cols++;
300 ?>
301 <th class="<?php echo $vik->getAdminThClass('left'); ?>" width="10%" style="text-align: left;">
302 <?php echo JHtml::fetch('vaphtml.admin.sort', 'VAPMANAGERESERVATION4', 's.name', $this->orderDir, $this->ordering); ?>
303 </th>
304 <?php
305 }
306
307 if (in_array('info', $listable_fields))
308 {
309 ?>
310 <th class="<?php echo $vik->getAdminThClass(); ?>" width="5%" style="text-align: center;">
311 <?php echo JText::translate('VAPMANAGERESERVATION20');?>
312 </th>
313 <?php
314 }
315
316 if (in_array('nominative', $listable_fields))
317 {
318 ?>
319 <th class="<?php echo $vik->getAdminThClass('left'); ?>" width="10%" style="text-align: left;">
320 <?php echo JHtml::fetch('vaphtml.admin.sort', 'VAPMANAGERESERVATION38', 'r.purchaser_nominative', $this->orderDir, $this->ordering); ?>
321 </th>
322 <?php
323 }
324
325 if (in_array('phone', $listable_fields))
326 {
327 ?>
328 <th class="<?php echo $vik->getAdminThClass('left hidden-phone'); ?>" width="8%" style="text-align: left;">
329 <?php echo JText::translate('VAPMANAGECUSTOMER4'); ?>
330 </th>
331 <?php
332 }
333
334 /**
335 * Display here the custom fields that should be shown
336 * within the head of the table.
337 */
338 foreach ($this->customFields as $field)
339 {
340 if (in_array($field['name'], $listable_cf))
341 {
342 ?>
343 <th class="<?php echo $vik->getAdminThClass('hidden-phone'); ?>" width="10%" style="text-align: center;">
344 <?php echo $field['langname']; ?>
345 </th>
346 <?php
347 }
348 }
349
350 /**
351 * Display here the custom columns fetched by third-party plugins.
352 *
353 * @since 1.7
354 */
355 foreach ($columns as $k => $col)
356 {
357 ?>
358 <th data-id="<?php echo $this->escape($k); ?>" class="<?php echo $vik->getAdminThClass('left hidden-phone'); ?>">
359 <?php echo $col->th; ?>
360 </th>
361 <?php
362 }
363
364 if (in_array('total', $listable_fields))
365 {
366 ?>
367 <th class="<?php echo $vik->getAdminThClass('left hidden-phone'); ?>" width="8%" style="text-align: left;">
368 <?php echo JHtml::fetch('vaphtml.admin.sort', 'VAPMANAGERESERVATION9', 'r.total_cost', $this->orderDir, $this->ordering); ?>
369 </th>
370 <?php
371 }
372
373 if (in_array('payment', $listable_fields))
374 {
375 ?>
376 <th class="<?php echo $vik->getAdminThClass('left hidden-phone'); ?>" width="10%" style="text-align: left;">
377 <?php echo JText::translate('VAPMANAGERESERVATION13');?>
378 </th>
379 <?php
380 }
381
382 if (in_array('coupon', $listable_fields))
383 {
384 ?>
385 <th class="<?php echo $vik->getAdminThClass('hidden-phone'); ?>" width="5%" style="text-align: center;">
386 <?php echo JText::translate('VAPMANAGERESERVATION21');?>
387 </th>
388 <?php
389 }
390
391 if (in_array('invoice', $listable_fields))
392 {
393 ?>
394 <th class="<?php echo $vik->getAdminThClass('hidden-phone'); ?>" width="5%" style="text-align: center;">
395 <?php echo JText::translate('VAPMANAGERESERVATION35');?>
396 </th>
397 <?php
398 }
399
400 if (in_array('status', $listable_fields))
401 {
402 ?>
403 <th class="<?php echo $vik->getAdminThClass('left hidden-phone'); ?>" width="10%" style="text-align: left;">
404 <?php echo JHtml::fetch('vaphtml.admin.sort', 'VAPMANAGERESERVATION12', 'r.status', $this->orderDir, $this->ordering); ?>
405 </th>
406 <?php
407 }
408 ?>
409
410 </tr>
411 <?php echo $vik->closeTableHead(); ?>
412
413 <?php
414 for ($i = 0, $n = count($rows); $i < $n; $i++)
415 {
416 $row = $rows[$i];
417
418 // create check-in dates based on the employee timezone
419 $checkin = JFactory::getDate($row['checkin_ts']);
420 $checkout = JFactory::getDate(VikAppointments::getCheckout($row['checkin_ts'], $row['duration']));
421
422 if ($row['timezone'] && $row['timezone'] != $default_tz->getName())
423 {
424 $tz = new DateTimeZone($row['timezone']);
425
426 $checkin->setTimezone($tz);
427 $checkout->setTimezone($tz);
428
429 // display times adjusted to the employee timezone
430 $tz_str = str_replace('_', ' ', $row['timezone']) . "<br />"
431 . $checkin->format(JText::translate('DATE_FORMAT_LC2'), $local = true) . "<br />"
432 . $checkout->format(JText::translate('DATE_FORMAT_LC2'), $local = true);
433 }
434 else
435 {
436 $tz_str = '';
437 }
438
439 // adjust times to local offset (of the current logged-in user)
440 $checkin->setTimezone($default_tz);
441 $checkout->setTimezone($default_tz);
442
443 $edit_link = 'index.php?option=com_vikappointments&amp;task=reservation.edit&amp;cid[]=' . $row['id'];
444
445 if ($row['id_parent'] == -1 && $filters['res_id'] <= 0)
446 {
447 $edit_link = 'index.php?option=com_vikappointments&amp;view=reservations&amp;res_id=' . $row['id'];
448 }
449
450 $oid_tooltip = "";
451
452 if ($row['createdon'] != -1)
453 {
454 if ($row['createdby'] > 0)
455 {
456 $created_by = $row['author'];
457 }
458 else
459 {
460 $created_by = JText::translate('VAPRESLISTGUEST');
461 }
462
463 $created_on = JHtml::fetch('date', $row['createdon'], JText::translate('DATE_FORMAT_LC1') . ' ' . $config->get('timeformat'));
464
465 $oid_tooltip = JText::sprintf('VAPRESLISTCREATEDTIP', $created_on, $created_by);
466 }
467
468 if ($row['closure'])
469 {
470 $row['status'] = 'CLOSURE';
471 }
472
473 // decode stored CF data
474 $cf_json = (array) json_decode((string) $row['custom_f'], true);
475
476 /**
477 * Translate custom fields values stored in the database.
478 *
479 * @since 1.6.4
480 */
481 $cf_json = VAPCustomFieldsLoader::translateObject($cf_json, $this->customFields);
482 ?>
483 <tr class="row<?php echo ($i % 2); ?>">
484
485 <td>
486 <input type="checkbox" id="cb<?php echo $i;?>" name="cid[]" value="<?php echo $row['id']; ?>" onClick="<?php echo $vik->checkboxOnClick(); ?>">
487 </td>
488
489 <?php
490 if (in_array('id', $listable_fields))
491 {
492 ?>
493 <td class="hidden-phone nowrap">
494 <span class="hasTooltip" title="<?php echo $oid_tooltip; ?>">
495 <?php echo $row['id']; ?>
496 </span>
497 </td>
498 <?php
499 }
500
501 if (in_array('sid', $listable_fields))
502 {
503 ?>
504 <td class="hidden-phone">
505 <?php
506 if ($row['closure'] == 0)
507 {
508 ?>
509 <div>
510 <?php
511 if ($canEdit)
512 {
513 ?>
514 <a href="<?php echo $edit_link; ?>">
515 <?php echo $row['sid']; ?>
516 </a>
517 <?php
518 }
519 else
520 {
521 echo $row['sid'];
522 }
523 ?>
524 </div>
525 <?php
526 }
527
528 if (!VAPDateHelper::isNull($row['createdon']))
529 {
530 ?>
531 <div class="td-secondary">
532 <?php echo JHtml::fetch('date', JFactory::getDate($row['createdon']), JText::translate('DATE_FORMAT_LC3') . ' ' . $config->get('timeformat')); ?>
533 </div>
534 <?php
535 }
536 ?>
537 </td>
538 <?php
539 }
540
541 // make sure we don't have a multi-order parent
542 if ($row['id_parent'] != -1 || $row['closure'])
543 {
544 if (in_array('checkin_ts', $listable_fields))
545 {
546 ?>
547 <td class="nowrap">
548 <div class="td-primary">
549 <?php
550 // make checkin date clickable to access the details of the reservation
551 // in case the "Order Key" column is turned off
552 if ($canEdit && !in_array('sid', $listable_fields))
553 {
554 ?>
555 <a href="<?php echo $edit_link; ?>">
556 <?php echo $checkin->format(JText::translate('DATE_FORMAT_LC3'), $local = true); ?>
557 </a>
558 <?php
559 }
560 else
561 {
562 echo $checkin->format(JText::translate('DATE_FORMAT_LC3'), $local = true);
563 }
564
565 if ($tz_str)
566 {
567 ?>
568 <div class="td-pull-right">
569 <i class="fas fa-globe-americas hasTooltip" title="<?php echo $this->escape($tz_str); ?>"></i>
570 </div>
571 <?php
572 }
573 ?>
574 </div>
575
576 <div class="td-secondary">
577 <span class="checkin-time">
578 <i class="fas fa-sign-in-alt"></i>
579 <?php echo $checkin->format($config->get('timeformat'), $local = true); ?>
580 </span>
581
582 <?php
583 if (in_array('checkout', $listable_fields))
584 {
585 ?>
586 <span class="checkin-time" style="margin-left: 4px;">
587 <i class="fas fa-sign-out-alt"></i>
588 <?php echo $checkout->format($config->get('timeformat'), $local = true); ?>
589 </span>
590 <?php
591 }
592 ?>
593 </div>
594
595 <?php
596 if (in_array('status', $listable_fields))
597 {
598 ?>
599 <div class="mobile-only">
600 <?php
601 if ($row['closure'] == 0)
602 {
603 echo JHtml::fetch('vaphtml.status.display', $row['status'], 'badge');
604 }
605 else
606 {
607 ?>
608 <span class="badge badge-important"><?php echo JText::translate('VAPSTATUSCLOSURE'); ?></span>
609 <?php
610 }
611 ?>
612 </div>
613 <?php
614 }
615 ?>
616 </td>
617 <?php
618 }
619
620 if (in_array('employee', $listable_fields))
621 {
622 ?>
623 <td>
624 <div class="td-primary">
625 <?php echo $row['employee_name']; ?>
626 </div>
627 </td>
628 <?php
629 }
630
631 if (in_array('service', $listable_fields))
632 {
633 ?>
634 <td>
635 <div class="td-primary">
636 <?php echo $row['service_name']; ?>
637 </div>
638
639 <div class="td-secondary">
640 <span class="td-pull-left">
641 <i class="fas fa-stopwatch"></i>
642 <?php echo VikAppointments::formatMinutesToTime($row['duration']); ?>
643 </span>
644
645 <?php
646 // do not show in case of a single participant
647 if (in_array('people', $listable_fields) && $row['people'] > 1)
648 {
649 ?>
650 <span class="td-pull-right">
651 <?php echo $row['people']; ?>
652 <i class="fas fa-male"></i><i class="fas fa-male" style="margin-left: 1px;"></i>
653 </span>
654 <?php
655 }
656 ?>
657 </div>
658 </td>
659 <?php
660 }
661 }
662 else if ($multi_orders_cols > 0)
663 {
664 ?>
665 <td colspan="<?php echo $multi_orders_cols; ?>" style="text-align: center;">
666 <a href="<?php echo $edit_link; ?>">
667 <span class="vaporderparentbox">
668 <?php
669 if ($filters['res_id'] != $row['id'])
670 {
671 ?>
672 <i class="fas fa-layer-group"></i>&nbsp;
673 <?php
674 echo JText::translate('VAPMANAGERESERVATION29');
675 }
676 else
677 {
678 ?>
679 <i class="fas fa-pen-square"></i>&nbsp;
680 <?php
681 echo JText::translate('VAPEDIT');
682 }
683 ?>
684 </span>
685 </a>
686 </td>
687 <?php
688 }
689
690 if (in_array('info', $listable_fields))
691 {
692 ?>
693 <td style="text-align: center;">
694 <?php
695 if ($row['id_parent'] > 0)
696 {
697 ?>
698 <a href="javascript:void(0)" onclick="openOrderModal(<?php echo $row['id']; ?>);">
699 <i class="fas fa-ticket-alt big"></i>
700 </a>
701 <?php
702 }
703 else if ($row['closure'] == 0)
704 {
705 if ($filters['res_id'] != $row['id'])
706 {
707 ?>
708 <a href="index.php?option=com_vikappointments&amp;view=reservations&amp;res_id=<?php echo $row['id']; ?>">
709 <i class="fas fa-ticket-alt big"></i>
710 </a>
711 <?php
712 }
713 else
714 {
715 // we are already filtering for this multi-order
716 ?>
717 <a class="disabled">
718 <i class="fas fa-ticket-alt big"></i>
719 </a>
720 <?php
721 }
722 }
723 else
724 {
725 ?>
726 <i class="fas fa-ban big no"></i>
727 <?php
728 }
729 ?>
730 </td>
731 <?php
732 }
733
734 if (in_array('nominative', $listable_fields))
735 {
736 ?>
737 <td>
738 <?php
739 // use primary for mail in case the nominative is empty
740 $mail_class = 'td-primary';
741
742 if ($row['purchaser_nominative'])
743 {
744 // nominative not empty, use secondary class for mail
745 $mail_class = 'td-secondary';
746 ?>
747 <div class="td-primary">
748 <?php
749 if ($row['id_user'] > 0)
750 {
751 ?>
752 <a href="javascript:void(0)" onclick="openCustomerModal(<?php echo $row['id_user']; ?>);">
753 <?php echo $row['purchaser_nominative']; ?>
754 </a>
755 <?php
756 }
757 else
758 {
759 echo $row['purchaser_nominative'];
760 }
761 ?>
762 </div>
763 <?php
764 }
765
766 if (in_array('mail', $listable_fields))
767 {
768 ?>
769 <div class="<?php echo $mail_class; ?>">
770 <?php echo $row['purchaser_mail']; ?>
771 </div>
772 <?php
773 }
774 ?>
775 </td>
776 <?php
777 }
778
779 if (in_array('phone', $listable_fields))
780 {
781 ?>
782 <td class="hidden-phone">
783 <?php echo $row['purchaser_phone']; ?>
784 </td>
785 <?php
786 }
787
788 /**
789 * Display here the custom fields that should be shown
790 * within the body of the table.
791 */
792 foreach ($this->customFields as $field)
793 {
794 if (in_array($field['name'], $listable_cf))
795 {
796 ?>
797 <td style="text-align: center;" class="hidden-phone">
798 <?php
799 /**
800 * Translate field name in order to support
801 * those fields that still use the old
802 * translation method.
803 *
804 * @since 1.6.5
805 */
806 // $field['name'] = JText::translate($field['name']);
807
808 if (isset($cf_json[$field['name']]))
809 {
810 echo $cf_json[$field['name']];
811 }
812 ?>
813 </td>
814 <?php
815 }
816 }
817
818 /**
819 * Display here the custom columns fetched by third-party plugins.
820 *
821 * @since 1.7
822 */
823 foreach ($columns as $k => $col)
824 {
825 ?>
826 <td data-id="<?php echo $this->escape($k); ?>" class="hidden-phone">
827 <?php echo isset($col->td[$i]) ? $col->td[$i] : ''; ?>
828 </td>
829 <?php
830 }
831
832 if (in_array('total', $listable_fields))
833 {
834 ?>
835 <td class="nowrap hidden-phone">
836 <?php
837 if ($row['closure'] == 0)
838 {
839 ?>
840 <div class="td-primary">
841 <?php echo $currency->format($row['total_cost']); ?>
842 </div>
843
844 <div class="td-secondary">
845 <?php
846 // Check whether the order is flagged as "paid".
847 // Rely also on "paid" column for BC.
848 $is_paid = $row['paid'] || JHtml::fetch('vaphtml.status.ispaid', 'appointments', $row['status']);
849
850 if ($row['total_cost'] > $row['tot_paid'] && !$is_paid)
851 {
852 // display remaining balance
853 echo JText::translate('VAPORDERDUE') . ': ' . $currency->format($row['total_cost'] - $row['tot_paid']);
854 }
855 else if ($row['tot_paid'] > 0)
856 {
857 // display amount paid
858 echo JText::translate('VAPORDERPAID') . ': ' . $currency->format($row['tot_paid']);
859 }
860 ?>
861 </div>
862 <?php
863 }
864 ?>
865 </td>
866 <?php
867 }
868
869 if (in_array('payment', $listable_fields))
870 {
871 ?>
872 <td class="hidden-phone">
873 <?php echo $row['payment_name']; ?>
874 </td>
875 <?php
876 }
877
878 if (in_array('coupon', $listable_fields))
879 {
880 ?>
881 <td style="text-align: center;" class="hidden-phone">
882 <?php
883 if ($row['coupon_str'])
884 {
885 list($coupon_code, $coupon_percentot, $coupon_amount) = explode(';;', $row['coupon_str']);
886 ?>
887 <span class="badge badge-warning hasTooltip" title="<?php echo $coupon_code; ?>">
888 <?php
889 if ($coupon_percentot == 1)
890 {
891 echo $coupon_amount . '%';
892 }
893 else
894 {
895 echo $currency->format($coupon_amount);
896 }
897 ?>
898 </span>
899 <?php
900 }
901 ?>
902 </td>
903 <?php
904 }
905
906 if (in_array('invoice', $listable_fields))
907 {
908 ?>
909 <td style="text-align: center;" class="hidden-phone">
910 <?php
911 if ($row['invoice'])
912 {
913 ?>
914 <a href="<?php echo $row['invoice']->uri; ?>" target="_blank">
915 <i class="fas fa-file-pdf" style="font-size: 24px;"></i>
916 </a>
917 <?php
918 }
919 ?>
920 </td>
921 <?php
922 }
923
924 if (in_array('status', $listable_fields))
925 {
926 ?>
927 <td class="hidden-phone">
928 <?php
929 if ($row['closure'] == 0)
930 {
931 $id_parent = $row['id_parent'] > 0 && $row['id_parent'] != $row['id'] ? $row['id_parent'] : 0;
932 ?>
933 <span class="status-hndl" style="cursor:pointer;" data-id="<?php echo $row['id']; ?>" data-status="<?php echo $row['status']; ?>" data-id-parent="<?php echo $id_parent; ?>">
934 <?php echo JHtml::fetch('vaphtml.status.display', $row['status']); ?>
935 </span>
936 <?php
937 }
938 else
939 {
940 ?>
941 <span class="vapreservationstatusclosure">
942 <?php echo JText::translate('VAPSTATUSCLOSURE'); ?>
943 </span>
944 <?php
945 }
946 ?>
947 </td>
948 <?php
949 }
950 ?>
951 </tr>
952 <?php
953 }
954 ?>
955 </table>
956 <?php
957 }
958 ?>
959
960 <!-- invoice submit fields -->
961 <input type="hidden" name="notifycust" value="0" />
962 <input type="hidden" name="group" value="appointments" />
963
964 <input type="hidden" name="boxchecked" value="0" />
965 <input type="hidden" name="task" value="" />
966 <input type="hidden" name="view" value="reservations" />
967
968 <input type="hidden" name="filter_order" value="<?php echo $this->ordering; ?>" />
969 <input type="hidden" name="filter_order_Dir" value="<?php echo $this->orderDir; ?>" />
970
971 <?php echo JHtml::fetch('form.token'); ?>
972 <?php echo $this->navbut; ?>
973 </form>
974
975 <?php
976 if (count($rows) == 1)
977 {
978 // credit card modal
979 echo JHtml::fetch(
980 'bootstrap.renderModal',
981 'jmodal-ccdetails',
982 array(
983 'title' => JText::translate('VAPSEECCDETAILS'),
984 'closeButton' => true,
985 'keyboard' => false,
986 'bodyHeight' => 60,
987 'modalWidth' => 60,
988 'url' => 'index.php?option=com_vikappointments&view=ccdetails&tmpl=component&cid[]=' . $rows[0]['id'],
989 )
990 );
991 }
992
993 // reservation modal
994 echo JHtml::fetch(
995 'bootstrap.renderModal',
996 'jmodal-respinfo',
997 array(
998 'title' => JText::translate('VAPMANAGERESERVATIONTITLE1'),
999 'closeButton' => true,
1000 'keyboard' => false,
1001 'bodyHeight' => 80,
1002 'url' => '',
1003 )
1004 );
1005
1006 // customer modal
1007 echo JHtml::fetch(
1008 'bootstrap.renderModal',
1009 'jmodal-custinfo',
1010 array(
1011 'title' => JText::translate('VAPMANAGECUSTOMER21'),
1012 'closeButton' => true,
1013 'keyboard' => false,
1014 'bodyHeight' => 80,
1015 'url' => '',
1016 'footer' => '<button type="button" class="btn pull-left" id="custinfo-filter-btn">
1017 <i class="fas fa-filter"></i>&nbsp;' . JText::translate('VAP_FILTER_APPOINTMENTS') . '
1018 </button>
1019 <a href="index.php?option=com_vikappointments&task=customer.edit&cid[]=0" class="btn btn-success pull-right" id="custinfo-edit-btn">' . JText::translate('VAPEDIT') . '</a>',
1020 )
1021 );
1022 ?>
1023
1024 <!-- INVOICE DIALOG -->
1025 <div id="dialog-invoice" style="display: none;">
1026 <h3 style="margin-top: 0;"><?php echo JText::translate('VAPINVOICEDIALOG'); ?></h3>
1027
1028 <p><?php echo JText::translate('VAPGENERATEINVOICESTXT'); ?></p>
1029
1030 <div>
1031 <?php
1032 $elem_yes = $vik->initRadioElement('', '', false, 'onClick="notifyCustValueChanged(1);"');
1033 $elem_no = $vik->initRadioElement('', '', true, 'onClick="notifyCustValueChanged(0);"');
1034
1035 echo $vik->openControl(JText::translate('VAPMANAGEINVOICE9'));
1036 echo $vik->radioYesNo('notifycust_radio', $elem_yes, $elem_no, false);
1037 echo $vik->closeControl();
1038 ?>
1039 </div>
1040 </div>
1041
1042 <?php
1043 JText::script('VAPMANAGEINVOICE6');
1044 JText::script('VAPCANCEL');
1045 ?>
1046
1047 <script>
1048
1049 var invoiceDialog = null;
1050
1051 jQuery(function($) {
1052 VikRenderer.chosen('.btn-toolbar');
1053 VikRenderer.chosen('#jmodal-invoice');
1054
1055 // trigger status code changed event
1056 $(window).on('statuscode.changed', (event, data) => {
1057 // update children item too
1058 $('.status-hndl[data-id-parent="' + data.id_order + '"]').html(data.html);
1059 });
1060
1061 $('#custinfo-filter-btn').on('click', function() {
1062 // filter the appointments by user
1063 $('#vapkeysearch').val('id_user:' + $(this).attr('data-id')).prop('disabled', false);
1064 // reset filter by reservation (if any)
1065 $('#adminForm').append('<input type="hidden" name="res_id" value="0" />');
1066
1067 document.adminForm.submit();
1068 });
1069
1070 // create invoice dialog
1071 invoiceDialog = new VikConfirmDialog('#dialog-invoice', 'vik-invoice-confirm');
1072
1073 // add confirm button
1074 invoiceDialog.addButton(Joomla.JText._('VAPMANAGEINVOICE6'), (task, event) => {
1075 // submit the form
1076 Joomla.submitform(task, document.adminForm);
1077 });
1078
1079 // add cancel button
1080 invoiceDialog.addButton(Joomla.JText._('VAPCANCEL'));
1081 });
1082
1083 function clearFilters() {
1084 jQuery('#vapkeysearch').val('');
1085 jQuery('#vapdatestart').val('');
1086 jQuery('#vapdateend').val('');
1087 jQuery('#vap-status-sel').updateChosen('');
1088 jQuery('#vap-payment-sel').updateChosen('');
1089 jQuery('#vap-location-sel').updateChosen('');
1090
1091 jQuery('#adminForm').append('<input type="hidden" name="res_id" value="0" />');
1092
1093 document.adminForm.submit();
1094 }
1095
1096 function notifyCustValueChanged(is) {
1097 jQuery('#adminForm input[name="notifycust"]').val(is);
1098 }
1099
1100 // modal
1101
1102 function openOrderModal(id) {
1103 let url = 'index.php?option=com_vikappointments&tmpl=component&view=orderinfo&cid[]=' + id;
1104
1105 vapOpenJModal('respinfo', url, true);
1106 }
1107
1108 function openCustomerModal(id) {
1109 // update filter button with customer ID
1110 jQuery('#custinfo-filter-btn').attr('data-id', id);
1111
1112 // update href to access the management page of the customer
1113 let href = jQuery('#custinfo-edit-btn').attr('href');
1114 jQuery('#custinfo-edit-btn').attr('href', href.replace(/cid\[\]=[\d]*$/, 'cid[]=' + id));
1115
1116 let url = 'index.php?option=com_vikappointments&tmpl=component&view=customerinfo&cid[]=' + id;
1117
1118 vapOpenJModal('custinfo', url, true);
1119 }
1120
1121 function vapOpenJModal(id, url, jqmodal) {
1122 <?php echo $vik->bootOpenModalJS(); ?>
1123 }
1124
1125 Joomla.submitbutton = function(task) {
1126 if (task == 'invoice.generate') {
1127 // show invoice dialog
1128 invoiceDialog.show(task);
1129 } else if (task == 'generateInvoices') {
1130 vapOpenJModal('invoice', null, true);
1131 } else {
1132 if (task == 'printorders') {
1133 // prepare form to be submitted on a blank browser tab
1134 jQuery('#adminForm').attr('target', '_blank');
1135 }
1136
1137 if (task == 'findreservation' || task == 'printorders' || task == 'makerecurrence') {
1138 // populate view instead of task
1139 document.adminForm.view.value = task;
1140 task = '';
1141 }
1142
1143 Joomla.submitform(task, document.adminForm);
1144
1145 jQuery('#adminForm').attr('target', '');
1146 }
1147 }
1148
1149 </script>
1150