first commit
This commit is contained in:
@@ -0,0 +1,432 @@
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
use Phpml\Regression\LeastSquares;
|
||||
|
||||
class Report extends Admin_Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->load->model('report_model');
|
||||
}
|
||||
|
||||
public function chart()
|
||||
{
|
||||
ini_set('memory_limit', '256M');
|
||||
|
||||
$params = $this->input->get();
|
||||
$data = [];
|
||||
$errors = [];
|
||||
$chartData1 = [];
|
||||
$chartData2 = [];
|
||||
|
||||
$data['transport_providers_dropdown'] = [
|
||||
['id' => 1, 'name' => 'Uber', 'color' => 'rgb(45, 230, 92)'],
|
||||
['id' => 2, 'name' => 'Lyft', 'color' => 'rgb(255, 0, 255)'],
|
||||
['id' => 3, 'name' => 'Grab' , 'color' => 'rgb(54, 162, 235)'],
|
||||
['id' => 4, 'name' => 'ComfortDelGro', 'color' => 'rgb(0, 255, 255)'],
|
||||
['id' => 5, 'name' => 'GOJEK', 'color' => 'rgb(255, 191, 0)'],
|
||||
];
|
||||
|
||||
if (!empty($params)) {
|
||||
// get data for period of time 1
|
||||
$period1_input = [
|
||||
'start_date' => $params['start_date_1'] ?? '',
|
||||
'end_date' => $params['end_date_1'] ?? '',
|
||||
'transport_providers' => $params['transport_providers'] ?? '',
|
||||
];
|
||||
|
||||
// get data for period of time 2
|
||||
$period2_input = [
|
||||
'start_date' => $params['start_date_2'] ?? '',
|
||||
'end_date' => $params['end_date_2'] ?? '',
|
||||
'transport_providers' => $params['transport_providers'] ?? '',
|
||||
];
|
||||
|
||||
// chart1 and chart2 are same data (just different how to plot chart) => load first to have good performance
|
||||
$loadDataFromDatabase1 = $response = $this->report_model->getPriceComparisonTrend($period1_input); // for period of time 1
|
||||
$loadDataFromDatabase2 = $response = $this->report_model->getPriceComparisonTrend($period2_input); // for period of time 2
|
||||
|
||||
$chartDataResponse1 = $this->getChartData1($loadDataFromDatabase1, $loadDataFromDatabase2, $data['transport_providers_dropdown']);
|
||||
$chartDataResponse2 = $this->getChartData2($loadDataFromDatabase1, $loadDataFromDatabase2, $data['transport_providers_dropdown']);
|
||||
|
||||
if (!$chartDataResponse1['success'] || !$chartDataResponse2['success']) {
|
||||
if (!empty($chartDataResponse1['message'])) {
|
||||
$errors[] = $chartDataResponse1['message'];
|
||||
}
|
||||
|
||||
if (!empty($chartDataResponse2['message'])) {
|
||||
$errors[] = $chartDataResponse2['message'];
|
||||
}
|
||||
} else {
|
||||
$chartData1 = $chartDataResponse1['data'];
|
||||
$chartData2 = $chartDataResponse2['data'];
|
||||
}
|
||||
}
|
||||
|
||||
$data['chartData1'] = json_encode($chartData1);
|
||||
$data['chartData2'] = json_encode($chartData2);
|
||||
$data['filterData'] = $params;
|
||||
$data['errors'] = $errors;
|
||||
$this->renderAdminPage('report/view_price_comparison_trend', $data);
|
||||
}
|
||||
|
||||
public function getChartData2(array $loadDataFromDatabase1, array $loadDataFromDatabase2, array $transport_providers_map)
|
||||
{
|
||||
$errors = [];
|
||||
$datasets = [];
|
||||
$general_index_date_map = [];
|
||||
|
||||
$datasets_1 = $this->generateChartDataset(
|
||||
$loadDataFromDatabase1,
|
||||
$transport_providers_map,
|
||||
$general_index_date_map,
|
||||
'Period1'
|
||||
);
|
||||
$datasets_2 = $this->generateChartDataset(
|
||||
$loadDataFromDatabase2,
|
||||
$transport_providers_map,
|
||||
$general_index_date_map,
|
||||
'Period2'
|
||||
);
|
||||
|
||||
if (!$datasets_1['success'] || !$datasets_2['success']) {
|
||||
if (!empty($datasets_1['message'])) {
|
||||
$errors[] = $datasets_1['message'];
|
||||
}
|
||||
|
||||
if (!empty($datasets_2['message'])) {
|
||||
$errors[] = $datasets_2['message'];
|
||||
}
|
||||
} else {
|
||||
$datasets = array_merge($datasets_1['data'], $datasets_2['data']);
|
||||
}
|
||||
|
||||
if (!empty($errors)) {
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => $errors[0]
|
||||
];
|
||||
}
|
||||
|
||||
$chartData = [
|
||||
'datasets' => $datasets,
|
||||
'general_index_date_map' => $general_index_date_map ?? [],
|
||||
];
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'data' => $chartData
|
||||
];
|
||||
}
|
||||
|
||||
public function getChartData1(array $loadDataFromDatabase1, array $loadDataFromDatabase2, array $transport_providers_map)
|
||||
{
|
||||
$errors = [];
|
||||
$datasets = [];
|
||||
$index_date_map_1 = [];
|
||||
$index_date_map_2 = [];
|
||||
|
||||
$datasets_1 = $this->generateChartDataset(
|
||||
$loadDataFromDatabase1,
|
||||
$transport_providers_map,
|
||||
$index_date_map_1,
|
||||
'Period1',
|
||||
true
|
||||
);
|
||||
$datasets_2 = $this->generateChartDataset(
|
||||
$loadDataFromDatabase2,
|
||||
$transport_providers_map,
|
||||
$index_date_map_2,
|
||||
'Period2',
|
||||
true
|
||||
);
|
||||
|
||||
if (!$datasets_1['success'] || !$datasets_2['success']) {
|
||||
if (!empty($datasets_1['message'])) {
|
||||
$errors[] = $datasets_1['message'];
|
||||
}
|
||||
|
||||
if (!empty($datasets_2['message'])) {
|
||||
$errors[] = $datasets_2['message'];
|
||||
}
|
||||
} else {
|
||||
$datasets = array_merge($datasets_1['data'], $datasets_2['data']);
|
||||
}
|
||||
|
||||
if (!empty($errors)) {
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => $errors[0]
|
||||
];
|
||||
}
|
||||
|
||||
$chartData = [
|
||||
'datasets' => $datasets,
|
||||
'index_date_map_1' => $index_date_map_1 ?? [],
|
||||
'index_date_map_2' => $index_date_map_2 ?? [],
|
||||
];
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'data' => $chartData
|
||||
];
|
||||
}
|
||||
|
||||
protected function generateChartDataset(
|
||||
array $loadDataFromDatabase,
|
||||
array $transport_providers_map,
|
||||
array &$index_date_map,
|
||||
string $period_name,
|
||||
bool $is_mutiple_x_axis = false) : array
|
||||
{
|
||||
if (!$loadDataFromDatabase['success']) {
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => $loadDataFromDatabase['message']
|
||||
];
|
||||
}
|
||||
|
||||
$datasets = [];
|
||||
$dataset = [];
|
||||
$i = count($index_date_map);
|
||||
|
||||
foreach ($loadDataFromDatabase['data'] as $key => $item) {
|
||||
if (!array_key_exists($item['travel_date'], $index_date_map))
|
||||
{
|
||||
$index_date_map[$item['travel_date']] = $i;
|
||||
$i++;
|
||||
}
|
||||
|
||||
$dataset[$item['transport_provider_id']][] = [
|
||||
'x' => $index_date_map[$item['travel_date']],
|
||||
'count' => (int) $item['count'],
|
||||
'y' => $item['cost']
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($dataset as $transport_provider_id => $chart_data ) {
|
||||
$found_key = array_search($transport_provider_id, array_column($transport_providers_map, 'id'));
|
||||
if ($found_key === FALSE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$label = $transport_providers_map[$found_key]['name'];
|
||||
$color = $transport_providers_map[$found_key]['color'];
|
||||
|
||||
// add scatter (data point)
|
||||
$dataset_item = [
|
||||
'type' => 'scatter',
|
||||
'showLine' => false,
|
||||
'label' => $label . " (${period_name})",
|
||||
|
||||
// only get [x, y] points to plot chart
|
||||
'data' => array_map(function($el) {
|
||||
return ['x' => $el['x'], 'y' => $el['y']];
|
||||
}, $chart_data),
|
||||
'backgroundColor' => $color
|
||||
];
|
||||
|
||||
// add trend line based on scatter
|
||||
$trendLineData = $this->calculateTrendLine($chart_data);
|
||||
$trend_line_dataset = [
|
||||
'type' => 'line',
|
||||
'showLine'=> true,
|
||||
'fill' => false,
|
||||
'pointRadius' => 0,
|
||||
'cubicInterpolationMode' => 'monotone',
|
||||
'label' => $label . " - Trend line (${period_name})",
|
||||
'data' => $trendLineData,
|
||||
'backgroundColor' => $color,
|
||||
'borderColor'=> $color,
|
||||
];
|
||||
|
||||
if ($is_mutiple_x_axis) {
|
||||
$dataset_item['xAxisID'] = 'x-' . $period_name;
|
||||
$trend_line_dataset['xAxisID'] = 'x-' . $period_name;
|
||||
}
|
||||
|
||||
$datasets[] = $dataset_item;
|
||||
$datasets[] = $trend_line_dataset;
|
||||
}
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'data' => $datasets
|
||||
];
|
||||
}
|
||||
|
||||
protected function calculateTrendLine(array $data)
|
||||
{
|
||||
// e.g.
|
||||
// $samples = [[73676, 1996], [77006, 1998], [10565, 2000], [146088, 1995]];
|
||||
// $targets = [2000, 2750, 15500, 960];
|
||||
|
||||
$samples = array_map(function($el) {
|
||||
return [$el['x'], $el['count']];
|
||||
}, $data);
|
||||
|
||||
$targets = array_map(function($el) {
|
||||
return $el['y'];
|
||||
}, $data);
|
||||
|
||||
|
||||
$regression = new LeastSquares();
|
||||
$regression->train($samples, $targets);
|
||||
|
||||
$coefficients = $regression->getCoefficients();
|
||||
$intercept = $regression->getIntercept();
|
||||
|
||||
$result = [];
|
||||
foreach ($samples as $el) {
|
||||
$y = $intercept + $el[0] * $coefficients[0] + 1 * $coefficients[1];
|
||||
$result[] = ['x' => $el[0], 'y' => $y];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function surgePricingVaraition()
|
||||
{
|
||||
global $savvyext;
|
||||
$this->load->helper('surge_pricing_varaition');
|
||||
$regression1 = new LeastSquares();
|
||||
|
||||
$t = 3;
|
||||
$date1 = "2020-01-01";
|
||||
$date2 = "2020-05-10";
|
||||
$area1 = 14;
|
||||
$area2 = 11;
|
||||
$areas = [
|
||||
10 => 'Central - Tanglin',
|
||||
11 => 'Central - Newton',
|
||||
17 => 'Far East - Changi',
|
||||
14 => 'Central East - Eunos'
|
||||
];
|
||||
|
||||
$t = isset($_GET['t'])?((int)$_GET['t']):$t;
|
||||
$date1 = isset($_GET['date1'])?date("Y-m-d",strtotime($_GET['date1'])):$date1;
|
||||
$date2 = isset($_GET['date2'])?date("Y-m-d",strtotime($_GET['date2'])):$date2;
|
||||
$area1 = isset($_GET['area1'])?((int)$_GET['area1']):$area1;
|
||||
$area2 = isset($_GET['area2'])?((int)$_GET['area2']):$area2;
|
||||
|
||||
if (3 > $t || $t > 5) $t = 3;
|
||||
if (!array_key_exists($area1,$areas)) $area1 = 14;
|
||||
if (!array_key_exists($area2,$areas)) $area2 = 11;
|
||||
|
||||
$providers = [3 => "Grab", 5 => "Gojek", 4 => "ComfortDelGro"];
|
||||
|
||||
$c = '#ff5555';
|
||||
list($data1,$label1,$poly1) = $this->report_model->area_to_area($area1, $area2, $date1, $date2, $t, $c);
|
||||
$res1 = $this->surgePricingTrendLine($regression1, $data1);
|
||||
$pub1 = $res1[0];
|
||||
|
||||
$c = '#5555ff';
|
||||
list($data2,$label2,$poly2) = $this->report_model->area_to_area($area2, $area1, $date1, $date2, $t, $c);
|
||||
$res2 = $this->surgePricingTrendLine($regression1, $data2);
|
||||
$pub2 = $res2[0];
|
||||
|
||||
$data = array_merge($data1, $data2);
|
||||
|
||||
$data = [
|
||||
't' => $t,
|
||||
'date1' => $date1,
|
||||
'date2' => $date2,
|
||||
'area1' => $area1,
|
||||
'area2' => $area2,
|
||||
'areas' => $areas,
|
||||
'providers' => $providers,
|
||||
'data' => $data,
|
||||
'data1' => $data1,
|
||||
'data2' => $data2,
|
||||
'label1' => $label1,
|
||||
'label2' => $label2,
|
||||
'poly1' => $poly1,
|
||||
'poly2' => $poly2,
|
||||
'res1' => $res1,
|
||||
'res2' => $res2,
|
||||
'pub1' => $pub1,
|
||||
'pub2' => $pub2,
|
||||
'google_api_key' => $savvyext->cfgReadChar( 'google.api_key' )
|
||||
];
|
||||
|
||||
$this->renderAdminPage('report/view_surge_pricing_varaition', $data);
|
||||
}
|
||||
|
||||
/***
|
||||
* Email & Bank Connection Log
|
||||
*/
|
||||
public function emailAndBankConnectionReport()
|
||||
{
|
||||
$this->load->model('combo_model');
|
||||
$data_report = $this->report_model->getEmailAndBankConnectionReportSummary();
|
||||
$data = [
|
||||
'page_title' => 'Email & Bank Connection Report',
|
||||
'data_report' => $data_report,
|
||||
'country_filter' => $this->combo_model->getCountriesHasAccount('country_filter', ''),
|
||||
];
|
||||
$this->renderAdminPage('report/view_email_and_bank_connection_report', $data);
|
||||
}
|
||||
|
||||
public function emailAndBankConnectionReportDatatables()
|
||||
{
|
||||
$data = $this->report_model->getEmailBankConnectionReportDatatables($this->input->post(), 'search');
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($data);
|
||||
}
|
||||
|
||||
public function emailAndBankConnectionReportCSV()
|
||||
{
|
||||
$this->load->library('session');
|
||||
$postData = $this->session->userdata("EBCRR_PARAM");
|
||||
if ($postData) {
|
||||
$this->report_model->getEmailBankConnectionReportDatatables($postData, 'export_csv');
|
||||
} else {
|
||||
echo 'Please try again!';
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
public function getBankAccountDetailJson()
|
||||
{
|
||||
$member_id = $this->input->get('member_id');
|
||||
$data = $this->report_model->getBankAccountDetail($member_id);
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($data);
|
||||
}
|
||||
|
||||
public function surgePricingTrendLine($regression1, $data)
|
||||
{
|
||||
$i = 0;
|
||||
$pub1 = array();
|
||||
$xs1 = [];
|
||||
$ys1 = [];
|
||||
$ys2 = [];
|
||||
foreach ($data as $f) {
|
||||
$t = $f['time'];
|
||||
$pub1[$t] = array($t,$f['cost']);
|
||||
$xs1[] = [$t];
|
||||
$ys1[] = $f['cost'];
|
||||
$i++;
|
||||
}
|
||||
if ($i>0) {
|
||||
$regression1->train($xs1,$ys1);
|
||||
}
|
||||
foreach ($pub1 as $key=>$f) {
|
||||
$y = $regression1->predict( [$f[0]] );
|
||||
$f[2] = $y;
|
||||
$pub1[$key] = $f;
|
||||
}
|
||||
return [$pub1,$xs1,$ys2];
|
||||
}
|
||||
|
||||
protected function renderAdminPage($page_name, $data)
|
||||
{
|
||||
$this->load->view('admin/view_admin_header', $data);
|
||||
$this->load->view($page_name, $data);
|
||||
$this->load->view('admin/view_admin_footer', $data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user