PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.8.16
VikBooking Hotel Booking Engine & PMS v1.8.16
1.8.16 1.8.15 1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 All 37 releases
vikbooking / admin / helpers / report / bookings.php

bookings.php in VikBooking Hotel Booking Engine & PMS 1.8.16, at admin/helpers/report/bookings.php

822 lines 28.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikBooking
4 * @subpackage com_vikbooking
5 * @author Alessio Gaggii - E4J srl
6 * @copyright Copyright (C) 2026 E4J srl. 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 /**
14 * Bookings report.
15 *
16 * @since 1.18.13 (J) - 1.8.13 (WP)
17 */
18 class VikBookingReportBookings extends VikBookingReport
19 {
20 /**
21 * Property 'defaultKeySort' is used by the View that renders the report.
22 */
23 public $defaultKeySort = 'day';
24
25 /**
26 * Property 'defaultKeyOrder' is used by the View that renders the report.
27 */
28 public $defaultKeyOrder = 'ASC';
29
30 /**
31 * Property 'exportAllowed' is used by the View to display the export button.
32 */
33 public $exportAllowed = 1;
34
35 /**
36 * Debug mode is activated by passing the value 'e4j_debug' > 0
37 */
38 private $debug;
39
40 /**
41 * Class constructor should define the name of the report and
42 * other vars. Call the parent constructor to define the DB object.
43 */
44 public function __construct()
45 {
46 $this->reportFile = basename(__FILE__, '.php');
47 $this->reportName = JText::translate('VBMENUTHREE');
48 $this->reportFilters = [];
49
50 $this->cols = [];
51 $this->rows = [];
52 $this->footerRow = [];
53
54 $this->debug = JFactory::getApplication()->input->getBool('e4j_debug', false);
55
56 $this->registerExportCSVFileName();
57
58 parent::__construct();
59 }
60
61 /**
62 * Returns the name of this report.
63 *
64 * @return string
65 */
66 public function getName()
67 {
68 return $this->reportName;
69 }
70
71 /**
72 * Returns the name of this file without .php.
73 *
74 * @return string
75 */
76 public function getFileName()
77 {
78 return $this->reportFile;
79 }
80
81 /**
82 * Returns the filters of this report.
83 *
84 * @return array
85 */
86 public function getFilters()
87 {
88 if ($this->reportFilters) {
89 // do not run this method twice, as it could load JS and CSS files.
90 return $this->reportFilters;
91 }
92
93 $app = JFactory::getApplication();
94
95 // get VBO Application Object
96 $vbo_app = VikBooking::getVboApplication();
97
98 // load the jQuery UI Datepicker
99 $this->loadDatePicker();
100
101 // From Date Filter
102 $filter_opt = array(
103 'label' => '<label for="fromdate">'.JText::translate('VBOREPORTSDATEFROM').'</label>',
104 'html' => '<input type="text" id="fromdate" name="fromdate" value="" class="vbo-report-datepicker vbo-report-datepicker-from" />',
105 'type' => 'calendar',
106 'name' => 'fromdate'
107 );
108 array_push($this->reportFilters, $filter_opt);
109
110 // To Date Filter
111 $filter_opt = array(
112 'label' => '<label for="todate">'.JText::translate('VBOREPORTSDATETO').'</label>',
113 'html' => '<input type="text" id="todate" name="todate" value="" class="vbo-report-datepicker vbo-report-datepicker-to" />',
114 'type' => 'calendar',
115 'name' => 'todate'
116 );
117 array_push($this->reportFilters, $filter_opt);
118
119 // Dates Type filter
120 $pdatetype = $app->input->getString('dates_type', 'checkin');
121 $filter_opt = array(
122 'label' => '<label for="dates_type">'.JText::translate('VBPSHOWSEASONSTHREE').'</label>',
123 'html' => '<select id="dates_type" name="dates_type">' .
124 '<option value="checkin"' . ($pdatetype === 'checkin' ? ' selected="selected"' : '') . '>' . JText::translate('VBPICKUPAT') . '</option>' .
125 '<option value="booking"' . ($pdatetype === 'booking' ? ' selected="selected"' : '') . '>' . JText::translate('VBPEDITBUSYTWO') . '</option>' .
126 '<option value="stay"' . ($pdatetype === 'stay' ? ' selected="selected"' : '') . '>' . JText::translate('VBO_CONDTEXT_RULE_STAYDATES') . '</option>' .
127 '</select>',
128 'type' => 'select',
129 'name' => 'dates_type'
130 );
131 array_push($this->reportFilters, $filter_opt);
132
133 // Listings Filter
134 $filter_opt = array(
135 'label' => '<label for="listingsfilt">' . JText::translate('VBO_LISTINGS') . '</label>',
136 'html' => '<span class="vbo-toolbar-multiselect-wrap">' . $vbo_app->renderElementsDropDown([
137 'id' => 'listingsfilt',
138 'elements' => 'listings',
139 'placeholder' => JText::translate('VBO_LISTINGS'),
140 'allow_clear' => 1,
141 'attributes' => [
142 'name' => 'listings[]',
143 'multiple' => 'multiple',
144 ],
145 'selected_values' => (array) JFactory::getApplication()->input->get('listings', [], 'array'),
146 ]) . '</span>',
147 'type' => 'select',
148 'multiple' => true,
149 'name' => 'listings',
150 );
151 array_push($this->reportFilters, $filter_opt);
152
153 // get minimum check-in and maximum check-out for dates filters
154 $df = $this->getDateFormat();
155 $mincheckin = 0;
156 $maxcheckout = 0;
157 $q = "SELECT MIN(`checkin`) AS `mincheckin`, MAX(`checkout`) AS `maxcheckout` FROM `#__vikbooking_orders` WHERE `status`='confirmed' AND `closure`=0;";
158 $this->dbo->setQuery($q);
159 $data = $this->dbo->loadAssoc();
160 if (!empty($data['mincheckin']) && !empty($data['maxcheckout'])) {
161 $mincheckin = $data['mincheckin'];
162 $maxcheckout = $data['maxcheckout'];
163 }
164
165 // calendars setup
166 $pfromdate = $app->input->getString('fromdate', '');
167 $ptodate = $app->input->getString('todate', '');
168 $js = 'jQuery(function() {
169 jQuery(".vbo-report-datepicker:input").datepicker({
170 '.(!empty($mincheckin) ? 'minDate: "'.date($df, $mincheckin).'", ' : '').'
171 '.(!empty($maxcheckout) ? 'maxDate: "'.date($df, $maxcheckout).'", ' : '').'
172 '.(!empty($mincheckin) && !empty($maxcheckout) ? 'yearRange: "'.(date('Y', $mincheckin)).':'.date('Y', $maxcheckout).'", changeMonth: true, changeYear: true, ' : '').'
173 dateFormat: "'.$this->getDateFormat('jui').'",
174 onSelect: vboReportCheckDates
175 });
176 '.(!empty($pfromdate) ? 'jQuery(".vbo-report-datepicker-from").datepicker("setDate", "'.$pfromdate.'");' : '').'
177 '.(!empty($ptodate) ? 'jQuery(".vbo-report-datepicker-to").datepicker("setDate", "'.$ptodate.'");' : '').'
178 });
179 function vboReportCheckDates(selectedDate, inst) {
180 if (selectedDate === null || inst === null) {
181 return;
182 }
183 var cur_from_date = jQuery(this).val();
184 if (jQuery(this).hasClass("vbo-report-datepicker-from") && cur_from_date.length) {
185 var nowstart = jQuery(this).datepicker("getDate");
186 var nowstartdate = new Date(nowstart.getTime());
187 jQuery(".vbo-report-datepicker-to").datepicker("option", {minDate: nowstartdate});
188 }
189 }';
190 $this->setScript($js);
191
192 return $this->reportFilters;
193 }
194
195 /**
196 * Loads the report data from the DB.
197 * Returns true in case of success, false otherwise.
198 * Sets the columns and rows for the report to be displayed.
199 *
200 * @return bool
201 */
202 public function getReportData()
203 {
204 if ($this->getError()) {
205 // export functions may set errors rather than exiting the process, and the View may continue the execution to attempt to render the report.
206 return false;
207 }
208
209 if ($this->rows) {
210 // method must have run already
211 return true;
212 }
213
214 $app = JFactory::getApplication();
215
216 // get the possibly injected report options
217 $options = $this->getReportOptions();
218
219 // injected options will replace request variables, if any
220 $opt_fromdate = $options->get('fromdate', '');
221 $opt_todate = $options->get('todate', '');
222 $opt_dt_type = $options->get('dates_type', '');
223
224 // input fields and other vars
225 $pfromdate = $opt_fromdate ?: $app->input->getString('fromdate', '');
226 $ptodate = $opt_todate ?: $app->input->getString('todate', '');
227 $pdatetype = $opt_dt_type ?: $app->input->getString('dates_type', '') ?: 'checkin';
228
229 $pkrsort = $app->input->getString('krsort', $this->defaultKeySort);
230 $pkrsort = empty($pkrsort) ? $this->defaultKeySort : $pkrsort;
231 $pkrorder = $app->input->getString('krorder', $this->defaultKeyOrder);
232 $pkrorder = empty($pkrorder) ? $this->defaultKeyOrder : $pkrorder;
233 $pkrorder = $pkrorder == 'DESC' ? 'DESC' : 'ASC';
234 $plistings = ((array) $app->input->get('listings', [], 'array')) ?: ((array) $options->get('listings', []));
235 $plistings = array_filter(array_map('intval', $plistings));
236
237 $currency_symb = VikBooking::getCurrencySymb();
238 $df = $this->getDateFormat();
239 $datesep = VikBooking::getDateSeparator();
240 if (empty($ptodate)) {
241 $ptodate = $pfromdate;
242 }
243
244 // get date timestamps
245 $from_ts = VikBooking::getDateTimestamp($pfromdate, 0, 0);
246 $to_ts = VikBooking::getDateTimestamp($ptodate, 23, 59, 59);
247 if (empty($pfromdate) || empty($from_ts) || empty($to_ts) || $from_ts > $to_ts) {
248 $this->setError(JText::translate('VBOREPORTSERRNODATES'));
249 return false;
250 }
251
252 // preferred date format
253 $df = $this->getDateFormat();
254 $datesep = VikBooking::getDateSeparator();
255
256 // determine stats calculation type
257 $calc_type = 'checkin';
258 if ($pdatetype === 'booking') {
259 $calc_type = 'booking_dates';
260 } elseif ($pdatetype === 'stay') {
261 $calc_type = 'stay_dates';
262 }
263
264 // access the finance helper object
265 $finance = VBOTaxonomyFinance::getInstance();
266
267 // force calculation options
268 $finance->setOptions([
269 'booking_level' => true,
270 ]);
271
272 // get the financial stats for the requested dates
273 try {
274 $stats = $finance->getStats(date('Y-m-d', $from_ts), date('Y-m-d', $to_ts), $plistings, $calc_type);
275 } catch (Exception $e) {
276 $this->setError($e->getMessage());
277 return false;
278 }
279
280 // define the columns of the report
281 $this->cols = [
282 // booking ID
283 [
284 'key' => 'bid',
285 'sortable' => 1,
286 'label' => JText::translate('VBDASHUPRESONE'),
287 ],
288 // date
289 [
290 'key' => 'day',
291 'sortable' => 1,
292 'label' => JText::translate('VBOREPORTREVENUEDAY'),
293 ],
294 // guest
295 [
296 'key' => 'guest',
297 'label' => JText::translate('VBO_GUEST'),
298 ],
299 // channel
300 [
301 'key' => 'channel',
302 'attr' => [
303 'class="center"',
304 ],
305 'label' => JText::translate('VBOCHANNEL'),
306 ],
307 // rooms booked
308 [
309 'key' => 'roomsnum',
310 'attr' => [
311 'class="center"',
312 ],
313 'sortable' => 1,
314 'label' => JText::translate('VBLIBTEN'),
315 ],
316 // nights booked
317 [
318 'key' => 'nights',
319 'attr' => [
320 'class="center"',
321 ],
322 'sortable' => 1,
323 'label' => JText::translate('VBDAYS'),
324 ],
325 // taxes
326 [
327 'key' => 'taxes',
328 'attr' => [
329 'class="center"',
330 ],
331 'sortable' => 1,
332 'label' => JText::translate('VBCALCRATESTAX'),
333 ],
334 // city taxes
335 [
336 'key' => 'city_taxes',
337 'attr' => [
338 'class="center"',
339 ],
340 'sortable' => 1,
341 'label' => JText::translate('VBCALCRATESCITYTAX'),
342 ],
343 // fees
344 [
345 'key' => 'fees',
346 'attr' => [
347 'class="center"',
348 ],
349 'sortable' => 1,
350 'label' => JText::translate('VBCALCRATESFEES'),
351 ],
352 // commissions
353 [
354 'key' => 'cmms',
355 'attr' => [
356 'class="center"',
357 ],
358 'sortable' => 1,
359 'label' => JText::translate('VBTOTALCOMMISSIONS'),
360 ],
361 // damage deposit
362 [
363 'key' => 'damage_dep',
364 'attr' => [
365 'class="center"',
366 ],
367 'sortable' => 1,
368 'label' => JText::translate('VBO_DAMAGE_DEPOSIT'),
369 ],
370 // options/extras
371 [
372 'key' => 'extras',
373 'attr' => [
374 'class="center"',
375 ],
376 'sortable' => 1,
377 'label' => JText::translate('VBOREPORTOPTIONSEXTRAS'),
378 ],
379 // room revenue
380 [
381 'key' => 'revenue',
382 'attr' => [
383 'class="center"',
384 ],
385 'sortable' => 1,
386 'label' => JText::translate('VBO_ROOM_REVENUE'),
387 ],
388 // grand total
389 [
390 'key' => 'total',
391 'attr' => [
392 'class="center"',
393 ],
394 'sortable' => 1,
395 'label' => JText::translate('VBOREPORTSTOTALROW'),
396 ],
397 // amount paid
398 [
399 'key' => 'totalpaid',
400 'attr' => [
401 'class="center"',
402 ],
403 'sortable' => 1,
404 'label' => JText::translate('VBPEDITBUSYTOTPAID'),
405 ],
406 ];
407
408 // options/extras counter
409 $extrasCounter = 0;
410
411 // grand total counter
412 $grandTotalCounter = 0;
413
414 // total paid counter
415 $totalPaidCounter = 0;
416
417 // iterate all bookings involved to build the report rows
418 foreach (($stats['bids'] ?? []) as $bookingId) {
419 try {
420 $registry = VBOBookingRegistry::getInstance(['id' => $bookingId]);
421 } catch (Exception $e) {
422 // ignore broken reservation and go next
423 continue;
424 }
425
426 // obtain booking-customer data
427 list($customer_nominative, $booking_avatar_src, $booking_avatar_alt) = $registry->getBookingCustomerData();
428
429 // extract booking details
430 $bookingChannel = $registry->getProperty('channel');
431 $bookingChannel = $registry->getProperty('idorderota') ? $bookingChannel : '';
432
433 // get booking revenue
434 $bookingRevenue = (float) $stats['_bid_stats'][$bookingId]['revenue'] ?? 0;
435
436 // get room-level revenue
437 $roomLevelRevenue = (float) $stats['_bid_stats'][$bookingId]['room_level_revenue'] ?? 0;
438
439 // get options/extras revenue
440 $extrasRevenue = max(0,
441 (float) $registry->getProperty('total', 0) -
442 $roomLevelRevenue -
443 ((float) $stats['_bid_stats'][$bookingId]['taxes'] ?? 0) -
444 ((float) $stats['_bid_stats'][$bookingId]['damage_deposits'] ?? 0) -
445 ((float) $stats['_bid_stats'][$bookingId]['cmms'] ?? 0)
446 );
447
448 // push report row for the current reservation
449 $this->rows[] = [
450 // booking ID
451 [
452 'key' => 'bid',
453 'callback' => function ($val) {
454 return '<a href="index.php?option=com_vikbooking&task=editorder&cid[]='.$val.'" target="_blank"><i class="'.VikBookingIcons::i('external-link').'"></i> '.$val.'</a>';
455 },
456 'no_export_callback' => 1,
457 'value' => $registry->getID(),
458 ],
459 // date
460 [
461 'key' => 'day',
462 'callback' => function ($val) use ($df, $datesep) {
463 return date(str_replace("/", $datesep, $df), $val);
464 },
465 'value' => $registry->getProperty('ts', 0),
466 ],
467 // guest
468 [
469 'key' => 'guest',
470 'value' => $customer_nominative,
471 ],
472 // channel
473 [
474 'key' => 'channel',
475 'attr' => [
476 'class="center"',
477 ],
478 'callback' => function ($val) use ($booking_avatar_src) {
479 if ($val && $booking_avatar_src) {
480 $channelparts = explode('_', $val);
481 return ($channelparts[1] ?? '') ?: $val;
482 }
483 return JText::translate('VBORDFROMSITE');
484 },
485 'value' => $bookingChannel,
486 ],
487 // rooms booked
488 [
489 'key' => 'roomsnum',
490 'attr' => [
491 'class="center"',
492 ],
493 'value' => $registry->getProperty('roomsnum', 1),
494 ],
495 // nights booked
496 [
497 'key' => 'nights',
498 'attr' => [
499 'class="center"',
500 ],
501 'value' => $registry->getProperty('days', 1),
502 ],
503 // taxes
504 [
505 'key' => 'taxes',
506 'attr' => [
507 'class="center"',
508 ],
509 'callback' => function ($val) use ($currency_symb) {
510 return VikBooking::formatCurrencyNumber(
511 VikBooking::numberFormat($val),
512 $currency_symb
513 );
514 },
515 'value' => $stats['_bid_stats'][$bookingId]['tot_vat'] ?? 0,
516 ],
517 // city taxes
518 [
519 'key' => 'city_taxes',
520 'attr' => [
521 'class="center"',
522 ],
523 'callback' => function ($val) use ($currency_symb) {
524 return VikBooking::formatCurrencyNumber(
525 VikBooking::numberFormat($val),
526 $currency_symb
527 );
528 },
529 'value' => $stats['_bid_stats'][$bookingId]['city_taxes'] ?? 0,
530 ],
531 // fees
532 [
533 'key' => 'fees',
534 'attr' => [
535 'class="center"',
536 ],
537 'callback' => function ($val) use ($currency_symb) {
538 return VikBooking::formatCurrencyNumber(
539 VikBooking::numberFormat($val),
540 $currency_symb
541 );
542 },
543 'value' => $registry->getProperty('tot_fees', 0),
544 ],
545 // commissions
546 [
547 'key' => 'cmms',
548 'attr' => [
549 'class="center"',
550 ],
551 'callback' => function ($val) use ($currency_symb) {
552 return VikBooking::formatCurrencyNumber(
553 VikBooking::numberFormat($val),
554 $currency_symb
555 );
556 },
557 'value' => $stats['_bid_stats'][$bookingId]['cmms'] ?? 0,
558 ],
559 // damage deposit
560 [
561 'key' => 'damage_dep',
562 'attr' => [
563 'class="center"',
564 ],
565 'callback' => function ($val) use ($currency_symb) {
566 return VikBooking::formatCurrencyNumber(
567 VikBooking::numberFormat($val),
568 $currency_symb
569 );
570 },
571 'value' => $stats['_bid_stats'][$bookingId]['damage_deposits'] ?? 0,
572 ],
573 // options/extras
574 [
575 'key' => 'extras',
576 'attr' => [
577 'class="center"',
578 ],
579 'callback' => function ($val) use ($currency_symb) {
580 return VikBooking::formatCurrencyNumber(
581 VikBooking::numberFormat($val),
582 $currency_symb
583 );
584 },
585 'value' => $extrasRevenue,
586 ],
587 // revenue
588 [
589 'key' => 'revenue',
590 'attr' => [
591 'class="center"',
592 ],
593 'callback' => function ($val) use ($currency_symb) {
594 return VikBooking::formatCurrencyNumber(
595 VikBooking::numberFormat($val),
596 $currency_symb
597 );
598 },
599 'value' => $bookingRevenue,
600 ],
601 // grand total
602 [
603 'key' => 'total',
604 'attr' => [
605 'class="center"',
606 ],
607 'callback' => function ($val) use ($currency_symb) {
608 return VikBooking::formatCurrencyNumber(
609 VikBooking::numberFormat($val),
610 $currency_symb
611 );
612 },
613 'value' => $registry->getProperty('total', 0),
614 ],
615 // amount paid
616 [
617 'key' => 'totalpaid',
618 'attr' => [
619 'class="center"',
620 ],
621 'callback' => function ($val) use ($currency_symb) {
622 return VikBooking::formatCurrencyNumber(
623 VikBooking::numberFormat($val),
624 $currency_symb
625 );
626 },
627 'value' => $registry->getProperty('totpaid', 0),
628 ],
629 ];
630
631 // increase options/extras counter
632 $extrasCounter += $extrasRevenue;
633
634 // increase grand total counter
635 $grandTotalCounter += $registry->getProperty('total', 0);
636
637 // increase total paid counter
638 $totalPaidCounter += $registry->getProperty('totpaid', 0);
639 }
640
641 // sort rows
642 $this->sortRows($pkrsort, $pkrorder);
643
644 // push footer row with the calculated financial stats
645 $this->footerRow[] = [
646 // booking ID
647 [
648 'attr' => [
649 'class="vbo-report-total"',
650 ],
651 'value' => '<h3>' . JText::translate('VBOREPORTSTOTALROW') . '</h3>',
652 ],
653 // date
654 [
655 'value' => '',
656 ],
657 // guest
658 [
659 'value' => '',
660 ],
661 // channel
662 [
663 'value' => '',
664 ],
665 // rooms booked
666 [
667 'attr' => [
668 'class="center"',
669 ],
670 'value' => $stats['rooms_booked'] ?? 0,
671 ],
672 // nights booked
673 [
674 'attr' => [
675 'class="center"',
676 ],
677 'value' => $stats['nights_booked'] ?? 0,
678 ],
679 // taxes
680 [
681 'attr' => [
682 'class="center"',
683 ],
684 'callback' => function ($val) use ($currency_symb) {
685 return VikBooking::formatCurrencyNumber(
686 VikBooking::numberFormat($val),
687 $currency_symb
688 );
689 },
690 'value' => $stats['tot_vat'] ?? 0,
691 ],
692 // city taxes
693 [
694 'attr' => [
695 'class="center"',
696 ],
697 'callback' => function ($val) use ($currency_symb) {
698 return VikBooking::formatCurrencyNumber(
699 VikBooking::numberFormat($val),
700 $currency_symb
701 );
702 },
703 'value' => $stats['city_taxes'] ?? 0,
704 ],
705 // fees
706 [
707 'attr' => [
708 'class="center"',
709 ],
710 'callback' => function ($val) use ($currency_symb) {
711 return VikBooking::formatCurrencyNumber(
712 VikBooking::numberFormat($val),
713 $currency_symb
714 );
715 },
716 'value' => 0,
717 ],
718 // commissions
719 [
720 'attr' => [
721 'class="center"',
722 ],
723 'callback' => function ($val) use ($currency_symb) {
724 return VikBooking::formatCurrencyNumber(
725 VikBooking::numberFormat($val),
726 $currency_symb
727 );
728 },
729 'value' => $stats['ota_cmms'] ?? 0,
730 ],
731 // damage deposit
732 [
733 'attr' => [
734 'class="center"',
735 ],
736 'callback' => function ($val) use ($currency_symb) {
737 return VikBooking::formatCurrencyNumber(
738 VikBooking::numberFormat($val),
739 $currency_symb
740 );
741 },
742 'value' => $stats['damage_deposits'] ?? 0,
743 ],
744 // options/extras
745 [
746 'attr' => [
747 'class="center"',
748 ],
749 'callback' => function ($val) use ($currency_symb) {
750 return VikBooking::formatCurrencyNumber(
751 VikBooking::numberFormat($val),
752 $currency_symb
753 );
754 },
755 'value' => $extrasCounter,
756 ],
757 // room revenue
758 [
759 'attr' => [
760 'class="center"',
761 ],
762 'callback' => function ($val) use ($currency_symb) {
763 return VikBooking::formatCurrencyNumber(
764 VikBooking::numberFormat($val),
765 $currency_symb
766 );
767 },
768 'value' => $stats['revenue'] ?? 0,
769 ],
770 // grand total
771 [
772 'attr' => [
773 'class="center"',
774 ],
775 'callback' => function ($val) use ($currency_symb) {
776 return VikBooking::formatCurrencyNumber(
777 VikBooking::numberFormat($val),
778 $currency_symb
779 );
780 },
781 'value' => $grandTotalCounter,
782 ],
783 // amount paid
784 [
785 'attr' => [
786 'class="center"',
787 ],
788 'callback' => function ($val) use ($currency_symb) {
789 return VikBooking::formatCurrencyNumber(
790 VikBooking::numberFormat($val),
791 $currency_symb
792 );
793 },
794 'value' => $totalPaidCounter,
795 ],
796 ];
797
798 // Debug
799 if ($this->debug) {
800 $this->setWarning('path to report file = '.urlencode(dirname(__FILE__)).'<br/>');
801 $this->setWarning('$stats:<pre>'.print_r($stats, true).'</pre><br/>');
802 }
803
804 return true;
805 }
806
807 /**
808 * Registers the name to give to the CSV file being exported.
809 *
810 * @return void
811 */
812 private function registerExportCSVFileName()
813 {
814 $app = JFactory::getApplication();
815
816 $pfromdate = $app->input->getString('fromdate', '');
817 $ptodate = $app->input->getString('todate', '');
818
819 $this->setExportCSVFileName($this->reportName . '-' . str_replace('/', '_', $pfromdate) . '-' . str_replace('/', '_', $ptodate) . '.csv');
820 }
821 }
822