File "transactions_report.php"
Full Path: /home/romayxjt/public_html/wp-content/plugins/vikbooking/admin/helpers/report/transactions_report.php
File size: 13.19 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* @package VikBooking
* @subpackage com_vikbooking
* @author Alessio Gaggii - e4j - Extensionsforjoomla.com
* @copyright Copyright (C) 2018 e4j - Extensionsforjoomla.com. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
* @link https://vikwp.com
*/
defined('ABSPATH') or die('No script kiddies please!');
/**
* Transactions child Class of VikBookingReport
*/
class VikBookingReportTransactionsReport extends VikBookingReport
{
/**
* Property 'defaultKeySort' is used by the View that renders the report.
*/
public $defaultKeySort = 'tot';
/**
* Property 'defaultKeyOrder' is used by the View that renders the report.
*/
public $defaultKeyOrder = 'DESC';
/**
* Property 'exportAllowed' is used by the View to display the export button.
*/
public $exportAllowed = 1;
/**
* Debug mode is activated by passing the value 'e4j_debug' > 0
*/
private $debug;
/**
* Class constructor should define the name of the report and
* other vars. Call the parent constructor to define the DB object.
*/
public function __construct()
{
$this->reportFile = basename(__FILE__, '.php');
$this->reportName = JText::translate('VBOREPORT'.strtoupper(str_replace('_', '', $this->reportFile)));
$this->reportFilters = array();
$this->cols = array();
$this->rows = array();
$this->footerRow = array();
$this->debug = (VikRequest::getInt('e4j_debug', 0, 'request') > 0);
$this->registerExportCSVFileName();
parent::__construct();
}
/**
* Returns the name of this report.
*
* @return string
*/
public function getName()
{
return $this->reportName;
}
/**
* Returns the name of this file without .php.
*
* @return string
*/
public function getFileName()
{
return $this->reportFile;
}
/**
* Returns the filters of this report.
*
* @return array
*/
public function getFilters()
{
if (count($this->reportFilters)) {
//do not run this method twice, as it could load JS and CSS files.
return $this->reportFilters;
}
//get VBO Application Object
$vbo_app = VikBooking::getVboApplication();
//load the jQuery UI Datepicker
$this->loadDatePicker();
//From Date Filter
$filter_opt = array(
'label' => '<label for="fromdate">'.JText::translate('VBOREPORTSDATEFROM').'</label>',
'html' => '<input type="text" id="fromdate" name="fromdate" value="" class="vbo-report-datepicker vbo-report-datepicker-from" />',
'type' => 'calendar',
'name' => 'fromdate'
);
array_push($this->reportFilters, $filter_opt);
//To Date Filter
$filter_opt = array(
'label' => '<label for="todate">'.JText::translate('VBOREPORTSDATETO').'</label>',
'html' => '<input type="text" id="todate" name="todate" value="" class="vbo-report-datepicker vbo-report-datepicker-to" />',
'type' => 'calendar',
'name' => 'todate'
);
array_push($this->reportFilters, $filter_opt);
//Room ID filter
$pidroom = VikRequest::getInt('idroom', '', 'request');
$all_rooms = $this->getRooms();
$rooms = array();
foreach ($all_rooms as $room) {
$rooms[$room['id']] = $room['name'];
}
if (count($rooms)) {
$rooms_sel_html = $vbo_app->getNiceSelect($rooms, $pidroom, 'idroom', JText::translate('VBOSTATSALLROOMS'), JText::translate('VBOSTATSALLROOMS'), '', '', 'idroom');
$filter_opt = array(
'label' => '<label for="idroom">'.JText::translate('VBOREPORTSROOMFILT').'</label>',
'html' => $rooms_sel_html,
'type' => 'select',
'name' => 'idroom'
);
array_push($this->reportFilters, $filter_opt);
}
// get minimum check-in and maximum check-out for dates filters
$df = $this->getDateFormat();
$mincheckin = 0;
$maxcheckout = 0;
$q = "SELECT MIN(`checkin`) AS `mincheckin`, MAX(`checkout`) AS `maxcheckout` FROM `#__vikbooking_orders` WHERE `status`='confirmed' AND `closure`=0;";
$this->dbo->setQuery($q);
$this->dbo->execute();
if ($this->dbo->getNumRows()) {
$data = $this->dbo->loadAssoc();
if (!empty($data['mincheckin']) && !empty($data['maxcheckout'])) {
$mincheckin = $data['mincheckin'];
$maxcheckout = $data['maxcheckout'];
}
}
//
//jQuery code for the datepicker calendars and select2
$pfromdate = VikRequest::getString('fromdate', '', 'request');
$ptodate = VikRequest::getString('todate', '', 'request');
$js = 'jQuery(function() {
jQuery(".vbo-report-datepicker:input").datepicker({
'.(!empty($mincheckin) ? 'minDate: "'.date($df, $mincheckin).'", ' : '').'
'.(!empty($maxcheckout) ? 'maxDate: "'.date($df, $maxcheckout).'", ' : '').'
dateFormat: "'.$this->getDateFormat('jui').'",
onSelect: vboReportCheckDates
});
'.(!empty($pfromdate) ? 'jQuery(".vbo-report-datepicker-from").datepicker("setDate", "'.$pfromdate.'");' : '').'
'.(!empty($ptodate) ? 'jQuery(".vbo-report-datepicker-to").datepicker("setDate", "'.$ptodate.'");' : '').'
});
function vboReportCheckDates(selectedDate, inst) {
if (selectedDate === null || inst === null) {
return;
}
var cur_from_date = jQuery(this).val();
if (jQuery(this).hasClass("vbo-report-datepicker-from") && cur_from_date.length) {
var nowstart = jQuery(this).datepicker("getDate");
var nowstartdate = new Date(nowstart.getTime());
jQuery(".vbo-report-datepicker-to").datepicker("option", {minDate: nowstartdate});
}
}';
$this->setScript($js);
return $this->reportFilters;
}
/**
* Loads the report data from the DB.
* Returns true in case of success, false otherwise.
* Sets the columns and rows for the report to be displayed.
*
* @return boolean
*/
public function getReportData()
{
if (strlen($this->getError())) {
//Export functions may set errors rather than exiting the process, and the View may continue the execution to attempt to render the report.
return false;
}
//Input fields and other vars
$pfromdate = VikRequest::getString('fromdate', '', 'request');
$ptodate = VikRequest::getString('todate', '', 'request');
$pidroom = VikRequest::getInt('idroom', '', 'request');
$pkrsort = VikRequest::getString('krsort', $this->defaultKeySort, 'request');
$pkrsort = empty($pkrsort) ? $this->defaultKeySort : $pkrsort;
$pkrorder = VikRequest::getString('krorder', $this->defaultKeyOrder, 'request');
$pkrorder = empty($pkrorder) ? $this->defaultKeyOrder : $pkrorder;
$pkrorder = $pkrorder == 'DESC' ? 'DESC' : 'ASC';
$currency_symb = VikBooking::getCurrencySymb();
$df = $this->getDateFormat();
$datesep = VikBooking::getDateSeparator();
if (empty($ptodate)) {
$ptodate = $pfromdate;
}
//Get dates timestamps
$from_ts = VikBooking::getDateTimestamp($pfromdate, 0, 0);
$to_ts = VikBooking::getDateTimestamp($ptodate, 23, 59, 59);
if (empty($pfromdate) || empty($from_ts) || empty($to_ts)) {
$this->setError(JText::translate('VBOREPORTSERRNODATES'));
return false;
}
/**
* We do not make a left join onto the orders roooms table
* or we may obtain multiple records with the query. Since we cannot
* group by booking ID as we need all history logs of type PU,
* we try to make a sub-query to concatenate all room IDs.
*/
// Query to obtain the records
$bookings = array();
$q = "SELECT `o`.`id`,`o`.`ts`,`o`.`days`,`o`.`checkin`,`o`.`checkout`,`o`.`totpaid`,`o`.`idpayment`,`o`.`roomsnum`,`o`.`total`,`o`.`idorderota`,`o`.`channel`,`o`.`country`,`o`.`tot_taxes`,".
"`o`.`tot_city_taxes`,`o`.`tot_fees`,`o`.`cmms`,`h`.`dt`,`h`.`data`, (SELECT GROUP_CONCAT(`or`.`idroom` SEPARATOR ';') FROM `#__vikbooking_ordersrooms` AS `or` WHERE `or`.`idorder`=`o`.`id`) AS `idrooms` ".
"FROM `#__vikbooking_orders` AS `o` LEFT JOIN `#__vikbooking_orderhistory` AS `h` ON `h`.`idorder`=`o`.`id` AND `h`.`type`='PU' ".
"WHERE `o`.`status`='confirmed' AND `o`.`closure`=0 AND `o`.`totpaid` > 0 ".
"AND ((`o`.`ts`>=".$from_ts." AND `o`.`ts`<=".$to_ts.") OR (`h`.`data` IS NOT NULL AND `h`.`dt`>=".$this->dbo->quote(date('Y-m-d H:i:s', $from_ts))." AND `h`.`dt`<=".$this->dbo->quote(date('Y-m-d H:i:s', $to_ts)).")) ".
"ORDER BY `o`.`ts` ASC, `h`.`dt` DESC;";
$this->dbo->setQuery($q);
$this->dbo->execute();
if ($this->dbo->getNumRows()) {
$bookings = $this->dbo->loadAssocList();
// apply room ID filter that was not used via SQL
if (!empty($pidroom)) {
foreach ($bookings as $k => $gbook) {
$roomids = explode(';', $gbook['idrooms']);
if (!in_array($pidroom, $roomids)) {
unset($bookings[$k]);
}
}
}
}
if (!count($bookings)) {
$this->setError(JText::translate('VBOREPORTSERRNORESERV'));
return false;
}
// Debug
// $this->setWarning('<pre>'.print_r($bookings, true).'</pre><br/>');
//
//define the columns of the report
$this->cols = array(
//date
array(
'key' => 'paymeth',
'sortable' => 1,
'label' => JText::translate('VBPAYMENTMETHOD')
),
//rooms sold
array(
'key' => 'tot',
'attr' => array(
'class="center"'
),
'sortable' => 1,
'label' => JText::translate('VBLIBSIX')
),
//bookings affected
array(
'key' => 'ids',
'attr' => array(
'class="center"'
),
'sortable' => 0,
'ignore_export' => 0,
'label' => JText::translate('VBMENUTHREE')
),
);
$paystats = array();
$allbids = array();
// loop over the bookings to build the payment stats
foreach ($bookings as &$gbook) {
if (!in_array($gbook['id'], $allbids)) {
array_push($allbids, $gbook['id']);
}
$payname = null;
if (!empty($gbook['data'])) {
$paydata = json_decode($gbook['data']);
$payname = is_object($paydata) && isset($paydata->payment_method) ? $paydata->payment_method : $payname;
// update totpaid if history data available
if (is_object($paydata) && isset($paydata->amount_paid) && $paydata->amount_paid > 0) {
$gbook['totpaid'] = (float)$paydata->amount_paid;
}
} elseif (!empty($gbook['idpayment'])) {
if (strpos($gbook['idpayment'], '=') !== false) {
$parts = explode('=', $gbook['idpayment']);
$payname = $parts[1];
} else {
$payname = $gbook['idpayment'];
}
} elseif (!empty($gbook['channel']) && !empty($gbook['idorderota'])) {
$parts = explode('_', $gbook['channel']);
unset($parts[0]);
$payname = implode('_', $parts);
}
if (is_null($payname)) {
// unknown
$payname = JText::translate('VBOREPORTTOPCUNKNC');
}
// update reference
$gbook['payment_method'] = $payname;
// update stats for this payment method
if (!isset($paystats[$payname])) {
$paystats[$payname] = array(
'totpaid' => 0,
'bids' => array()
);
}
// increase total paid and push booking ID
$paystats[$payname]['totpaid'] += $gbook['totpaid'];
if (!in_array($gbook['id'], $paystats[$payname]['bids'])) {
array_push($paystats[$payname]['bids'], $gbook['id']);
}
}
// loop over the stats to build the rows
foreach ($paystats as $payname => $stats) {
//push fields in the rows array as a new row
array_push($this->rows, array(
array(
'key' => 'paymeth',
'value' => $payname
),
array(
'key' => 'tot',
'attr' => array(
'class="center"'
),
'callback' => function ($val) use ($currency_symb) {
return $currency_symb.' '.VikBooking::numberFormat($val);
},
'export_callback' => function ($val) use ($currency_symb) {
return $currency_symb.' '.VikBooking::numberFormat($val);
},
'value' => $stats['totpaid']
),
array(
'key' => 'ids',
'attr' => array(
'class="center"'
),
'callback' => function ($val) {
$str = '';
foreach ($val as $bid) {
$str .= '<span style="display: inline-block; margin: 0 2px;"><a href="index.php?option=com_vikbooking&task=editorder&cid[]='.$bid.'" target="_blank"><i class="'.VikBookingIcons::i('external-link').'"></i> '.$bid.'</a></span>';
}
return $str;
},
'ignore_export' => 1,
'value' => $stats['bids']
),
));
}
// sort rows
$this->sortRows($pkrsort, $pkrorder);
// loop over the rows to build the footer row with the totals
$foot_tot_collected = 0;
foreach ($this->rows as $row) {
$foot_tot_collected += $row[1]['value'];
}
// push footer row
array_push($this->footerRow, array(
array(
'attr' => array(
'class="vbo-report-total"'
),
'value' => '<h3>'.JText::translate('VBOREPORTSTOTALROW').'</h3>'
),
array(
'attr' => array(
'class="center"'
),
'callback' => function ($val) use ($currency_symb) {
return $currency_symb.' '.VikBooking::numberFormat($val);
},
'value' => $foot_tot_collected
),
array(
'attr' => array(
'class="center"'
),
'value' => count($allbids)
),
));
//Debug
if ($this->debug) {
$this->setWarning('path to report file = '.urlencode(dirname(__FILE__)).'<br/>');
$this->setWarning('$bookings:<pre>'.print_r($bookings, true).'</pre><br/>');
}
//
return true;
}
/**
* Registers the name to give to the CSV file being exported.
*
* @return void
*
* @since 1.16.1 (J) - 1.6.1 (WP)
*/
private function registerExportCSVFileName()
{
$pfromdate = VikRequest::getString('fromdate', '', 'request');
$ptodate = VikRequest::getString('todate', '', 'request');
$this->setExportCSVFileName($this->reportName . '-' . str_replace('/', '_', $pfromdate) . '-' . str_replace('/', '_', $ptodate) . '.csv');
}
}