PluginProbe
VikBooking Hotel Booking Engine & PMS / trunk
VikBooking Hotel Booking Engine & PMS vtrunk
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 1.7.3 All 36 releases
vikbooking / admin / helpers / report / bookings.php

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

819 lines 28.8 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 options/extras revenue
437 $extrasRevenue = max(0,
438 (float) $registry->getProperty('total', 0) -
439 $bookingRevenue -
440 ((float) $stats['_bid_stats'][$bookingId]['taxes'] ?? 0) -
441 ((float) $stats['_bid_stats'][$bookingId]['damage_deposits'] ?? 0) -
442 ((float) $stats['_bid_stats'][$bookingId]['cmms'] ?? 0)
443 );
444
445 // push report row for the current reservation
446 $this->rows[] = [
447 // booking ID
448 [
449 'key' => 'bid',
450 'callback' => function ($val) {
451 return '<a href="index.php?option=com_vikbooking&task=editorder&cid[]='.$val.'" target="_blank"><i class="'.VikBookingIcons::i('external-link').'"></i> '.$val.'</a>';
452 },
453 'no_export_callback' => 1,
454 'value' => $registry->getID(),
455 ],
456 // date
457 [
458 'key' => 'day',
459 'callback' => function ($val) use ($df, $datesep) {
460 return date(str_replace("/", $datesep, $df), $val);
461 },
462 'value' => $registry->getProperty('ts', 0),
463 ],
464 // guest
465 [
466 'key' => 'guest',
467 'value' => $customer_nominative,
468 ],
469 // channel
470 [
471 'key' => 'channel',
472 'attr' => [
473 'class="center"',
474 ],
475 'callback' => function ($val) use ($booking_avatar_src) {
476 if ($val && $booking_avatar_src) {
477 $channelparts = explode('_', $val);
478 return ($channelparts[1] ?? '') ?: $val;
479 }
480 return JText::translate('VBORDFROMSITE');
481 },
482 'value' => $bookingChannel,
483 ],
484 // rooms booked
485 [
486 'key' => 'roomsnum',
487 'attr' => [
488 'class="center"',
489 ],
490 'value' => $registry->getProperty('roomsnum', 1),
491 ],
492 // nights booked
493 [
494 'key' => 'nights',
495 'attr' => [
496 'class="center"',
497 ],
498 'value' => $registry->getProperty('days', 1),
499 ],
500 // taxes
501 [
502 'key' => 'taxes',
503 'attr' => [
504 'class="center"',
505 ],
506 'callback' => function ($val) use ($currency_symb) {
507 return VikBooking::formatCurrencyNumber(
508 VikBooking::numberFormat($val),
509 $currency_symb
510 );
511 },
512 'value' => $stats['_bid_stats'][$bookingId]['tot_vat'] ?? 0,
513 ],
514 // city taxes
515 [
516 'key' => 'city_taxes',
517 'attr' => [
518 'class="center"',
519 ],
520 'callback' => function ($val) use ($currency_symb) {
521 return VikBooking::formatCurrencyNumber(
522 VikBooking::numberFormat($val),
523 $currency_symb
524 );
525 },
526 'value' => $stats['_bid_stats'][$bookingId]['city_taxes'] ?? 0,
527 ],
528 // fees
529 [
530 'key' => 'fees',
531 'attr' => [
532 'class="center"',
533 ],
534 'callback' => function ($val) use ($currency_symb) {
535 return VikBooking::formatCurrencyNumber(
536 VikBooking::numberFormat($val),
537 $currency_symb
538 );
539 },
540 'value' => $registry->getProperty('tot_fees', 0),
541 ],
542 // commissions
543 [
544 'key' => 'cmms',
545 'attr' => [
546 'class="center"',
547 ],
548 'callback' => function ($val) use ($currency_symb) {
549 return VikBooking::formatCurrencyNumber(
550 VikBooking::numberFormat($val),
551 $currency_symb
552 );
553 },
554 'value' => $stats['_bid_stats'][$bookingId]['cmms'] ?? 0,
555 ],
556 // damage deposit
557 [
558 'key' => 'damage_dep',
559 'attr' => [
560 'class="center"',
561 ],
562 'callback' => function ($val) use ($currency_symb) {
563 return VikBooking::formatCurrencyNumber(
564 VikBooking::numberFormat($val),
565 $currency_symb
566 );
567 },
568 'value' => $stats['_bid_stats'][$bookingId]['damage_deposits'] ?? 0,
569 ],
570 // options/extras
571 [
572 'key' => 'extras',
573 'attr' => [
574 'class="center"',
575 ],
576 'callback' => function ($val) use ($currency_symb) {
577 return VikBooking::formatCurrencyNumber(
578 VikBooking::numberFormat($val),
579 $currency_symb
580 );
581 },
582 'value' => $extrasRevenue,
583 ],
584 // revenue
585 [
586 'key' => 'revenue',
587 'attr' => [
588 'class="center"',
589 ],
590 'callback' => function ($val) use ($currency_symb) {
591 return VikBooking::formatCurrencyNumber(
592 VikBooking::numberFormat($val),
593 $currency_symb
594 );
595 },
596 'value' => $bookingRevenue,
597 ],
598 // grand total
599 [
600 'key' => 'total',
601 'attr' => [
602 'class="center"',
603 ],
604 'callback' => function ($val) use ($currency_symb) {
605 return VikBooking::formatCurrencyNumber(
606 VikBooking::numberFormat($val),
607 $currency_symb
608 );
609 },
610 'value' => $registry->getProperty('total', 0),
611 ],
612 // amount paid
613 [
614 'key' => 'totalpaid',
615 'attr' => [
616 'class="center"',
617 ],
618 'callback' => function ($val) use ($currency_symb) {
619 return VikBooking::formatCurrencyNumber(
620 VikBooking::numberFormat($val),
621 $currency_symb
622 );
623 },
624 'value' => $registry->getProperty('totpaid', 0),
625 ],
626 ];
627
628 // increase options/extras counter
629 $extrasCounter += $extrasRevenue;
630
631 // increase grand total counter
632 $grandTotalCounter += $registry->getProperty('total', 0);
633
634 // increase total paid counter
635 $totalPaidCounter += $registry->getProperty('totpaid', 0);
636 }
637
638 // sort rows
639 $this->sortRows($pkrsort, $pkrorder);
640
641 // push footer row with the calculated financial stats
642 $this->footerRow[] = [
643 // booking ID
644 [
645 'attr' => [
646 'class="vbo-report-total"',
647 ],
648 'value' => '<h3>' . JText::translate('VBOREPORTSTOTALROW') . '</h3>',
649 ],
650 // date
651 [
652 'value' => '',
653 ],
654 // guest
655 [
656 'value' => '',
657 ],
658 // channel
659 [
660 'value' => '',
661 ],
662 // rooms booked
663 [
664 'attr' => [
665 'class="center"',
666 ],
667 'value' => $stats['rooms_booked'] ?? 0,
668 ],
669 // nights booked
670 [
671 'attr' => [
672 'class="center"',
673 ],
674 'value' => $stats['nights_booked'] ?? 0,
675 ],
676 // taxes
677 [
678 'attr' => [
679 'class="center"',
680 ],
681 'callback' => function ($val) use ($currency_symb) {
682 return VikBooking::formatCurrencyNumber(
683 VikBooking::numberFormat($val),
684 $currency_symb
685 );
686 },
687 'value' => $stats['tot_vat'] ?? 0,
688 ],
689 // city taxes
690 [
691 'attr' => [
692 'class="center"',
693 ],
694 'callback' => function ($val) use ($currency_symb) {
695 return VikBooking::formatCurrencyNumber(
696 VikBooking::numberFormat($val),
697 $currency_symb
698 );
699 },
700 'value' => $stats['city_taxes'] ?? 0,
701 ],
702 // fees
703 [
704 'attr' => [
705 'class="center"',
706 ],
707 'callback' => function ($val) use ($currency_symb) {
708 return VikBooking::formatCurrencyNumber(
709 VikBooking::numberFormat($val),
710 $currency_symb
711 );
712 },
713 'value' => 0,
714 ],
715 // commissions
716 [
717 'attr' => [
718 'class="center"',
719 ],
720 'callback' => function ($val) use ($currency_symb) {
721 return VikBooking::formatCurrencyNumber(
722 VikBooking::numberFormat($val),
723 $currency_symb
724 );
725 },
726 'value' => $stats['ota_cmms'] ?? 0,
727 ],
728 // damage deposit
729 [
730 'attr' => [
731 'class="center"',
732 ],
733 'callback' => function ($val) use ($currency_symb) {
734 return VikBooking::formatCurrencyNumber(
735 VikBooking::numberFormat($val),
736 $currency_symb
737 );
738 },
739 'value' => $stats['damage_deposits'] ?? 0,
740 ],
741 // options/extras
742 [
743 'attr' => [
744 'class="center"',
745 ],
746 'callback' => function ($val) use ($currency_symb) {
747 return VikBooking::formatCurrencyNumber(
748 VikBooking::numberFormat($val),
749 $currency_symb
750 );
751 },
752 'value' => $extrasCounter,
753 ],
754 // room revenue
755 [
756 'attr' => [
757 'class="center"',
758 ],
759 'callback' => function ($val) use ($currency_symb) {
760 return VikBooking::formatCurrencyNumber(
761 VikBooking::numberFormat($val),
762 $currency_symb
763 );
764 },
765 'value' => $stats['revenue'] ?? 0,
766 ],
767 // grand total
768 [
769 'attr' => [
770 'class="center"',
771 ],
772 'callback' => function ($val) use ($currency_symb) {
773 return VikBooking::formatCurrencyNumber(
774 VikBooking::numberFormat($val),
775 $currency_symb
776 );
777 },
778 'value' => $grandTotalCounter,
779 ],
780 // amount paid
781 [
782 'attr' => [
783 'class="center"',
784 ],
785 'callback' => function ($val) use ($currency_symb) {
786 return VikBooking::formatCurrencyNumber(
787 VikBooking::numberFormat($val),
788 $currency_symb
789 );
790 },
791 'value' => $totalPaidCounter,
792 ],
793 ];
794
795 // Debug
796 if ($this->debug) {
797 $this->setWarning('path to report file = '.urlencode(dirname(__FILE__)).'<br/>');
798 $this->setWarning('$stats:<pre>'.print_r($stats, true).'</pre><br/>');
799 }
800
801 return true;
802 }
803
804 /**
805 * Registers the name to give to the CSV file being exported.
806 *
807 * @return void
808 */
809 private function registerExportCSVFileName()
810 {
811 $app = JFactory::getApplication();
812
813 $pfromdate = $app->input->getString('fromdate', '');
814 $ptodate = $app->input->getString('todate', '');
815
816 $this->setExportCSVFileName($this->reportName . '-' . str_replace('/', '_', $pfromdate) . '-' . str_replace('/', '_', $ptodate) . '.csv');
817 }
818 }
819