Add form for analytics forecasting #409
This commit is contained in:
parent
760f823794
commit
06d3aa3b27
5 changed files with 172 additions and 16 deletions
|
|
@ -186,7 +186,7 @@ main_menu:
|
||||||
acl: analytics.menu
|
acl: analytics.menu
|
||||||
label: Analytics
|
label: Analytics
|
||||||
icon: flaticon-graphic
|
icon: flaticon-graphic
|
||||||
- id: analytics_forecast
|
- id: analytics_forecast_form
|
||||||
acl: analytics.forecast
|
acl: analytics.forecast
|
||||||
label: Forecasting
|
label: Forecasting
|
||||||
parent: analytics
|
parent: analytics
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
#geofence
|
# analytics
|
||||||
|
|
||||||
analytics_forecast:
|
analytics_forecast_form:
|
||||||
path: /analytics/forecast
|
path: /analytics/forecast
|
||||||
controller: App\Controller\AnalyticsController::forecast
|
controller: App\Controller\AnalyticsController::forecastForm
|
||||||
methods: [GET]
|
methods: [GET]
|
||||||
|
|
||||||
|
analytics_forecast_submit:
|
||||||
|
path: /analytics/forecast
|
||||||
|
controller: App\Controller\AnalyticsController::forecastSubmit
|
||||||
|
methods: [POST]
|
||||||
|
|
|
||||||
|
|
@ -26,21 +26,53 @@ class AnalyticsController extends Controller
|
||||||
* @Menu(selected="analytics_forecast")
|
* @Menu(selected="analytics_forecast")
|
||||||
* @IsGranted("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 = [];
|
$all_hubs = $em->getRepository(Hub::class)->findAll();
|
||||||
foreach ($hub_list as $hub_id)
|
|
||||||
|
$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 = [
|
$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,
|
'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)
|
protected function generateHubData($em, $hub_id, $distance_limit, DateTime $today)
|
||||||
|
|
@ -59,6 +91,9 @@ class AnalyticsController extends Controller
|
||||||
$c_weekday = [];
|
$c_weekday = [];
|
||||||
$c_day = [];
|
$c_day = [];
|
||||||
|
|
||||||
|
// counter to check instances of hourly weekdays, so we can get average
|
||||||
|
$c_week_count = [];
|
||||||
|
|
||||||
// loop through job orders
|
// loop through job orders
|
||||||
foreach ($jos as $jo)
|
foreach ($jos as $jo)
|
||||||
{
|
{
|
||||||
|
|
@ -68,6 +103,7 @@ class AnalyticsController extends Controller
|
||||||
$day = $date->format('d');
|
$day = $date->format('d');
|
||||||
$weekday = $date->format('l');
|
$weekday = $date->format('l');
|
||||||
$hour = $date->format('H');
|
$hour = $date->format('H');
|
||||||
|
$week = $date->format('W');
|
||||||
|
|
||||||
// year day
|
// year day
|
||||||
if (!isset($c_day[$year][$month][$day]))
|
if (!isset($c_day[$year][$month][$day]))
|
||||||
|
|
@ -76,8 +112,19 @@ class AnalyticsController extends Controller
|
||||||
|
|
||||||
// weekday
|
// weekday
|
||||||
if (!isset($c_weekday[$year][$month][$weekday][$hour]))
|
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));
|
// error_log(print_r($c_weekday, true));
|
||||||
|
|
@ -180,7 +227,13 @@ class AnalyticsController extends Controller
|
||||||
|
|
||||||
// get hour data
|
// get hour data
|
||||||
if (isset($year_data[$month][$weekday][$hour]))
|
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']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
96
templates/analytics/forecast_form.html.twig
Normal file
96
templates/analytics/forecast_form.html.twig
Normal 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 %}
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<div class="m-subheader">
|
<div class="m-subheader">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<div class="mr-auto">
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -58,6 +58,7 @@ categoryAxis.title.text = "Date";
|
||||||
|
|
||||||
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
|
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
|
||||||
valueAxis.title.text = "Orders";
|
valueAxis.title.text = "Orders";
|
||||||
|
valueAxis.maxPrecision = 0;
|
||||||
|
|
||||||
// year day
|
// year day
|
||||||
var s2018 = chart.series.push(new am4charts.LineSeries());
|
var s2018 = chart.series.push(new am4charts.LineSeries());
|
||||||
|
|
@ -92,19 +93,20 @@ xAxis.dataFields.category = "hour";
|
||||||
xAxis.title.text = "Hour";
|
xAxis.title.text = "Hour";
|
||||||
var yAxis = chart2.yAxes.push(new am4charts.ValueAxis());
|
var yAxis = chart2.yAxes.push(new am4charts.ValueAxis());
|
||||||
yAxis.title.text = "Orders";
|
yAxis.title.text = "Orders";
|
||||||
|
yAxis.maxPrecision = 0;
|
||||||
|
|
||||||
var l2018 = chart2.series.push(new am4charts.LineSeries());
|
var l2018 = chart2.series.push(new am4charts.LineSeries());
|
||||||
l2018.name = "2018";
|
l2018.name = "2018";
|
||||||
l2018.stroke = am4core.color("#0000FF");
|
l2018.stroke = am4core.color("#0000FF");
|
||||||
l2018.strokeWidth = 2;
|
l2018.strokeWidth = 2;
|
||||||
l2018.dataFields.valueY = "y2018";
|
l2018.dataFields.valueY = "y2018_average";
|
||||||
l2018.dataFields.categoryX = "hour";
|
l2018.dataFields.categoryX = "hour";
|
||||||
|
|
||||||
var l2019 = chart2.series.push(new am4charts.LineSeries());
|
var l2019 = chart2.series.push(new am4charts.LineSeries());
|
||||||
l2019.name = "2019";
|
l2019.name = "2019";
|
||||||
l2019.stroke = am4core.color("#FF0000");
|
l2019.stroke = am4core.color("#FF0000");
|
||||||
l2019.strokeWidth = 3;
|
l2019.strokeWidth = 3;
|
||||||
l2019.dataFields.valueY = "y2019";
|
l2019.dataFields.valueY = "y2019_average";
|
||||||
l2019.dataFields.categoryX = "hour";
|
l2019.dataFields.categoryX = "hour";
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
Loading…
Reference in a new issue