Add form for analytics forecasting #409

This commit is contained in:
Kendrick Chan 2020-05-23 23:07:00 +08:00
parent 760f823794
commit 06d3aa3b27
5 changed files with 172 additions and 16 deletions

View file

@ -186,7 +186,7 @@ main_menu:
acl: analytics.menu
label: Analytics
icon: flaticon-graphic
- id: analytics_forecast
- id: analytics_forecast_form
acl: analytics.forecast
label: Forecasting
parent: analytics

View file

@ -1,6 +1,11 @@
#geofence
# analytics
analytics_forecast:
analytics_forecast_form:
path: /analytics/forecast
controller: App\Controller\AnalyticsController::forecast
controller: App\Controller\AnalyticsController::forecastForm
methods: [GET]
analytics_forecast_submit:
path: /analytics/forecast
controller: App\Controller\AnalyticsController::forecastSubmit
methods: [POST]

View file

@ -26,21 +26,53 @@ class AnalyticsController extends Controller
* @Menu(selected="analytics_forecast")
* @IsGranted("analytics.forecast")
*/
public function forecast(EntityManagerInterface $em)
public function forecastForm(EntityManagerInterface $em)
{
$hub_list = [ 6, 4, 36, 7, 8, 126, 127, 18, 12, 9, 60, 10, 21, 135 ];
$hub_ids = [ 6, 4, 36, 7, 8, 126, 127, 18, 12, 9, 60, 10, 21, 135 ];
$hub_data = [];
foreach ($hub_list as $hub_id)
$all_hubs = $em->getRepository(Hub::class)->findAll();
$hub_list = [];
foreach ($all_hubs as $hub)
{
$hub_data[$hub_id] = $this->generateHubData($em, $hub_id, 5000, new DateTime());
$hub_list[$hub->getID()] = $hub->getName() . ' - ' . $hub->getBranch();
}
$params = [
'hub_list' => $hub_list,
'default_hubs' => $hub_ids,
];
return $this->render('analytics/forecast_form.html.twig', $params);
}
/**
* @Menu(selected="analytics_forecast")
* @IsGranted("analytics.forecast")
*/
public function forecastSubmit(EntityManagerInterface $em, Request $req)
{
$hub_list = $req->request->get('hub_ids', []);
$distances = $req->request->get('distances', []);
$today = DateTime::createFromFormat('d M Y', $req->request->get('date'));
error_log(print_r($hub_list, true));
// $hub_list = [ 6, 4, 36, 7, 8, 126, 127, 18, 12, 9, 60, 10, 21, 135 ];
$hub_data = [];
foreach ($hub_list as $key => $hub_id)
{
$dist = $distances[$key];
$hub_data[$hub_id] = $this->generateHubData($em, $hub_id, $dist, $today);
}
$params = [
'date' => $today,
'hub_list' => $hub_data,
];
return $this->render('analytics/forecast.html.twig', $params);
return $this->render('analytics/forecast_submit.html.twig', $params);
}
protected function generateHubData($em, $hub_id, $distance_limit, DateTime $today)
@ -58,6 +90,9 @@ class AnalyticsController extends Controller
// initialize counters
$c_weekday = [];
$c_day = [];
// counter to check instances of hourly weekdays, so we can get average
$c_week_count = [];
// loop through job orders
foreach ($jos as $jo)
@ -68,6 +103,7 @@ class AnalyticsController extends Controller
$day = $date->format('d');
$weekday = $date->format('l');
$hour = $date->format('H');
$week = $date->format('W');
// year day
if (!isset($c_day[$year][$month][$day]))
@ -76,8 +112,19 @@ class AnalyticsController extends Controller
// weekday
if (!isset($c_weekday[$year][$month][$weekday][$hour]))
$c_weekday[$year][$month][$weekday][$hour] = 0;
$c_weekday[$year][$month][$weekday][$hour]++;
{
$c_weekday[$year][$month][$weekday][$hour]['total'] = 0;
$c_weekday[$year][$month][$weekday][$hour]['count'] = 0;
}
$c_weekday[$year][$month][$weekday][$hour]['total']++;
if (!isset($c_week_count[$year][$month][$week][$weekday][$hour]))
{
// error_log('week detected - ' . $week);
$c_week_count[$year][$month][$week][$weekday][$hour] = 1;
$c_weekday[$year][$month][$weekday][$hour]['count']++;
}
}
// error_log(print_r($c_weekday, true));
@ -180,7 +227,13 @@ class AnalyticsController extends Controller
// get hour data
if (isset($year_data[$month][$weekday][$hour]))
$data[$id]['y' . $year] = $year_data[$month][$weekday][$hour];
{
$year_id = 'y' . $year;
$data[$id][$year_id] = $year_data[$month][$weekday][$hour]['total'];
$data[$id][$year_id . '_count'] = $year_data[$month][$weekday][$hour]['count'];
$data[$id][$year_id . '_average'] = ceil($year_data[$month][$weekday][$hour]['total'] / $year_data[$month][$weekday][$hour]['count']);
}
}
}

View file

@ -0,0 +1,96 @@
{% extends 'base.html.twig' %}
{% block body %}
<!-- BEGIN: Subheader -->
<div class="m-subheader">
<div class="d-flex align-items-center">
<div class="mr-auto">
<h3 class="m-subheader__title">Analytics - Forecasting</h3>
</div>
</div>
</div>
<!-- END: Subheader -->
<div class="m-content">
<!--Begin::Section-->
<div class="row">
<div class="col-xl-12">
<div class="m-portlet m-portlet--mobile">
<div class="m-portlet__head">
<div class="m-portlet__head-caption">
<div class="m-portlet__head-title">
<span class="m-portlet__head-icon">
<i class="fa fa-building"></i>
</span>
<h3 class="m-portlet__head-text">
Forecasting Variables
</h3>
</div>
</div>
</div>
<form id="row-form" class="m-form m-form--fit m-form--label-align-right m-form--group-seperator-dashed" method="post" action="{{ url('analytics_forecast_submit') }}">
<div class="m-portlet__body">
<div class="form-group m-form__group row no-border">
<div class="col-lg-6">
<label data-field="date">Date</label>
<div class="input-group date dp">
<input type="text" name="date" id="date" class="form-control m-input" value="{{ "now"|date('d M Y') }}" readonly placeholder="Select a date" >
<span class="input-group-addon">
<i class="la la-calendar glyphicon-th"></i>
</span>
</div>
<div class="form-control-feedback hide" data-field="date"></div>
</div>
</div>
{% for hub_id in default_hubs %}
<div class="row no-border" style="padding-left: 30px; padding-right: 30px; padding-bottom: 10px;">
<div class="col-lg-6">
<select name="hub_ids[]" class="form-control m-input">
{% for key, label in hub_list %}
<option value="{{ key }}" {{ hub_id == key ? ' selected' : ''}}>{{ label }}</option>
{% endfor %}
</select>
<div class="form-control-feedback hide" data-field="name"></div>
</div>
<div class="col-lg-3">
<input type="text" name="distances[]" class="form-control m-input" value="5000">
<div class="form-control-feedback hide" data-field="branch"></div>
</div>
</div>
{% endfor %}
</div>
<div class="m-portlet__foot m-portlet__foot--fit">
<div class="m-form__actions m-form__actions--solid m-form__actions--right">
<div class="row">
<div class="col-lg-12">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
$(function() {
// datepicker
$(".dp").datepicker({
format: "dd M yyyy",
todayHighlight: true,
autoclose: true,
pickerPosition: 'top-left',
bootcssVer: 3,
clearBtn: true
});
});
</script>
{% endblock %}

View file

@ -5,7 +5,7 @@
<div class="m-subheader">
<div class="d-flex align-items-center">
<div class="mr-auto">
<h3 class="m-subheader__title">Analytics Forecasting</h3>
<h3 class="m-subheader__title">Analytics Forecasting - {{ date | date('M - l') }}</h3>
</div>
</div>
</div>
@ -58,6 +58,7 @@ categoryAxis.title.text = "Date";
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.title.text = "Orders";
valueAxis.maxPrecision = 0;
// year day
var s2018 = chart.series.push(new am4charts.LineSeries());
@ -92,19 +93,20 @@ xAxis.dataFields.category = "hour";
xAxis.title.text = "Hour";
var yAxis = chart2.yAxes.push(new am4charts.ValueAxis());
yAxis.title.text = "Orders";
yAxis.maxPrecision = 0;
var l2018 = chart2.series.push(new am4charts.LineSeries());
l2018.name = "2018";
l2018.stroke = am4core.color("#0000FF");
l2018.strokeWidth = 2;
l2018.dataFields.valueY = "y2018";
l2018.dataFields.valueY = "y2018_average";
l2018.dataFields.categoryX = "hour";
var l2019 = chart2.series.push(new am4charts.LineSeries());
l2019.name = "2019";
l2019.stroke = am4core.color("#FF0000");
l2019.strokeWidth = 3;
l2019.dataFields.valueY = "y2019";
l2019.dataFields.valueY = "y2019_average";
l2019.dataFields.categoryX = "hour";
{% endfor %}