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
|
||||
label: Analytics
|
||||
icon: flaticon-graphic
|
||||
- id: analytics_forecast
|
||||
- id: analytics_forecast_form
|
||||
acl: analytics.forecast
|
||||
label: Forecasting
|
||||
parent: analytics
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -59,6 +91,9 @@ class AnalyticsController extends Controller
|
|||
$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']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
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="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 %}
|
||||
Loading…
Reference in a new issue