Merge branch '409-add-analytics-for-forecasting' into 'master'
Resolve "Add analytics for forecasting" Closes #409 See merge request jankstudio/resq!486
This commit is contained in:
commit
2be291c2ac
2 changed files with 130 additions and 46 deletions
|
|
@ -128,6 +128,17 @@ class AnalyticsController extends Controller
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init aggregate information
|
||||||
|
$agg_data = [];
|
||||||
|
for ($i = 0; $i < 7; $i++)
|
||||||
|
{
|
||||||
|
$agg_data[] = [
|
||||||
|
'label' => $this->weekdays[$i],
|
||||||
|
'total_jos' => 0,
|
||||||
|
'total_riders' => 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
// reprocess weekday data to account for overlap
|
// reprocess weekday data to account for overlap
|
||||||
foreach ($hub_data as $hub_id => $one_hub)
|
foreach ($hub_data as $hub_id => $one_hub)
|
||||||
{
|
{
|
||||||
|
|
@ -140,19 +151,37 @@ class AnalyticsController extends Controller
|
||||||
// error_log(print_r($scheduler_data, true));
|
// error_log(print_r($scheduler_data, true));
|
||||||
unset($chart_all_weekdays['scheduler_data']);
|
unset($chart_all_weekdays['scheduler_data']);
|
||||||
|
|
||||||
// run scheduler
|
|
||||||
// send 2018 + month data
|
|
||||||
$sched_res = $this->runScheduler($scheduler_data['2018'][$month]);
|
|
||||||
|
|
||||||
// tally total JOs for the month
|
|
||||||
$total_jos = 0;
|
$total_jos = 0;
|
||||||
foreach ($scheduler_data['2018'][$month] as $sday_data)
|
|
||||||
|
// run scheduler
|
||||||
|
// check if 2018 data is available
|
||||||
|
if (isset($scheduler_data['2018'][$month]))
|
||||||
{
|
{
|
||||||
foreach ($sday_data as $shour_data)
|
// send 2018 + month data
|
||||||
{
|
$sched_res = $this->runScheduler($scheduler_data['2018'][$month]);
|
||||||
$total_jos += $shour_data;
|
|
||||||
}
|
// tally total JOs for the month
|
||||||
|
foreach ($scheduler_data['2018'][$month] as $sday_data)
|
||||||
|
foreach ($sday_data as $shour_data)
|
||||||
|
$total_jos += $shour_data;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sched_res = [
|
||||||
|
'weekday_shifts' => $this->initDayData(),
|
||||||
|
'total_riders' => 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// agggregate weekday data
|
||||||
|
$i = 0;
|
||||||
|
foreach ($sched_res['weekday_shifts'] as $day_data)
|
||||||
|
{
|
||||||
|
$agg_data[$i]['total_jos'] += $day_data['total_jos'];
|
||||||
|
$agg_data[$i]['total_riders'] += $day_data['total_riders'];
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$hub_data[$hub_id]['data_weekday'] = $chart_weekday;
|
$hub_data[$hub_id]['data_weekday'] = $chart_weekday;
|
||||||
$hub_data[$hub_id]['data_all_weekdays'] = $chart_all_weekdays;
|
$hub_data[$hub_id]['data_all_weekdays'] = $chart_all_weekdays;
|
||||||
|
|
@ -168,16 +197,36 @@ class AnalyticsController extends Controller
|
||||||
// get job orders not covered by hubs
|
// get job orders not covered by hubs
|
||||||
$not_covered = $this->generateNotCoveredData($em, $hub_coverage, $today);
|
$not_covered = $this->generateNotCoveredData($em, $hub_coverage, $today);
|
||||||
|
|
||||||
|
// error_log(print_r($agg_data, true));
|
||||||
|
|
||||||
$params = [
|
$params = [
|
||||||
'date' => $today,
|
'date' => $today,
|
||||||
'hub_list' => $hub_data,
|
'hub_list' => $hub_data,
|
||||||
'hub_coverage' => $hub_coverage,
|
'hub_coverage' => $hub_coverage,
|
||||||
'not_covered' => $not_covered,
|
'not_covered' => $not_covered,
|
||||||
|
'agg_data' => $agg_data,
|
||||||
];
|
];
|
||||||
|
|
||||||
return $this->render('analytics/forecast_submit.html.twig', $params);
|
return $this->render('analytics/forecast_submit.html.twig', $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function initDayData()
|
||||||
|
{
|
||||||
|
$day_data = [];
|
||||||
|
// each weekday
|
||||||
|
for ($i = 0; $i < 7; $i++)
|
||||||
|
{
|
||||||
|
$day_data[$i] = [
|
||||||
|
'weekday' => $this->weekdays[$i],
|
||||||
|
'total_jos' => 0,
|
||||||
|
'total_riders' => 0,
|
||||||
|
'shifts' => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $day_data;
|
||||||
|
}
|
||||||
|
|
||||||
protected function runScheduler($scheduler_data)
|
protected function runScheduler($scheduler_data)
|
||||||
{
|
{
|
||||||
// run python script to solve scheduling for riders
|
// run python script to solve scheduling for riders
|
||||||
|
|
@ -193,7 +242,7 @@ class AnalyticsController extends Controller
|
||||||
foreach ($scheduler_data as $weekday_data)
|
foreach ($scheduler_data as $weekday_data)
|
||||||
$args[] = implode('-', $weekday_data);
|
$args[] = implode('-', $weekday_data);
|
||||||
|
|
||||||
error_log(print_r($args, true));
|
// error_log(print_r($args, true));
|
||||||
|
|
||||||
// error_log('running...' . $sched_script);
|
// error_log('running...' . $sched_script);
|
||||||
|
|
||||||
|
|
@ -204,11 +253,11 @@ class AnalyticsController extends Controller
|
||||||
error_log('SCHEDULER DID NOT RUN PROPERLY');
|
error_log('SCHEDULER DID NOT RUN PROPERLY');
|
||||||
|
|
||||||
$res = $proc->getOutput();
|
$res = $proc->getOutput();
|
||||||
error_log($res);
|
// error_log($res);
|
||||||
|
|
||||||
|
|
||||||
// segregate into weekdays
|
// segregate into weekdays
|
||||||
$day_data = [];
|
$day_data = $this->initDayData();
|
||||||
$i = 0;
|
$i = 0;
|
||||||
foreach ($scheduler_data as $weekday_data)
|
foreach ($scheduler_data as $weekday_data)
|
||||||
{
|
{
|
||||||
|
|
@ -216,12 +265,7 @@ class AnalyticsController extends Controller
|
||||||
foreach ($weekday_data as $hourly_jo)
|
foreach ($weekday_data as $hourly_jo)
|
||||||
$total_jos += $hourly_jo;
|
$total_jos += $hourly_jo;
|
||||||
|
|
||||||
$day_data[$i] = [
|
$day_data[$i]['total_jos'] = $total_jos;
|
||||||
'weekday' => $this->weekdays[$i],
|
|
||||||
'total_jos' => $total_jos,
|
|
||||||
'total_riders' => 0,
|
|
||||||
'shifts' => [],
|
|
||||||
];
|
|
||||||
|
|
||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
|
|
@ -251,7 +295,7 @@ class AnalyticsController extends Controller
|
||||||
for ($i = 1; $i < count($this->hour_shifts[$hour_shift_index]); $i++)
|
for ($i = 1; $i < count($this->hour_shifts[$hour_shift_index]); $i++)
|
||||||
$rider_hours[$this->hour_shifts[$hour_shift_index][$i]] = 1;
|
$rider_hours[$this->hour_shifts[$hour_shift_index][$i]] = 1;
|
||||||
|
|
||||||
error_log('allocating ' . $rider_count . ' for ' . $label);
|
// error_log('allocating ' . $rider_count . ' for ' . $label);
|
||||||
|
|
||||||
// add shifts to the weekday
|
// add shifts to the weekday
|
||||||
for ($i = 1; $i < count($this->day_shifts[$day_shift_index]); $i++)
|
for ($i = 1; $i < count($this->day_shifts[$day_shift_index]); $i++)
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,37 @@
|
||||||
<div id="map_coverage" style="height:600px; margin-bottom: 15px;">
|
<div id="map_coverage" style="height:600px; margin-bottom: 15px;">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xl-12">
|
||||||
|
<div class="m-portlet m-portlet--mobile">
|
||||||
|
<table class="shift-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 250px;">Day</th>
|
||||||
|
<th style="width: 100px;"># JO</th>
|
||||||
|
<th style="width: 100px;"># Rider</th>
|
||||||
|
<th style="width: 100px;">JO per Rider</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for i in 0..6 %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ agg_data[i].label }}</td>
|
||||||
|
<td>{{ agg_data[i].total_jos }}</td>
|
||||||
|
<td>{{ agg_data[i].total_riders }}</td>
|
||||||
|
{% if agg_data[i].total_riders == 0 %}
|
||||||
|
<td>0</td>
|
||||||
|
{% else %}
|
||||||
|
<td>{{ (agg_data[i].total_jos / agg_data[i].total_riders) | round(1, 'common') }}</td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% for hub in hub_list %}
|
{% for hub in hub_list %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xl-12">
|
<div class="col-xl-12">
|
||||||
|
|
@ -65,6 +96,41 @@
|
||||||
<div id="month-all-weekday-chart-{{ hub.id }}" style="height: 400px;">
|
<div id="month-all-weekday-chart-{{ hub.id }}" style="height: 400px;">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<table class="shift-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 250px;">Day</th>
|
||||||
|
<th style="width: 100px;"># JO</th>
|
||||||
|
<th style="width: 100px;"># Rider</th>
|
||||||
|
<th style="width: 100px;">JO per Rider</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for i in 0..6 %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ hub.data_shift[i].weekday }}</td>
|
||||||
|
<td>{{ hub.data_shift[i].total_jos }}</td>
|
||||||
|
<td>{{ hub.data_shift[i].total_riders }}</td>
|
||||||
|
{% if hub.data_shift[i].total_riders == 0 %}
|
||||||
|
<td>0</td>
|
||||||
|
{% else %}
|
||||||
|
<td>{{ (hub.data_shift[i].total_jos / hub.data_shift[i].total_riders) | round(1, 'common') }}</td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
<tr>
|
||||||
|
<td>Overall</td>
|
||||||
|
<td>{{ hub.total_jos }}</td>
|
||||||
|
<td>{{ hub.total_riders }}</td>
|
||||||
|
{% if hub.total_riders == 0 %}
|
||||||
|
<td>0</td>
|
||||||
|
{% else %}
|
||||||
|
<td>{{ (hub.total_jos / hub.total_riders) | round(1, 'common') }}</td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
{% for day_data in hub.data_shift %}
|
{% for day_data in hub.data_shift %}
|
||||||
<div id="shift-table-{{ hub.id }}">
|
<div id="shift-table-{{ hub.id }}">
|
||||||
<table class="shift-table">
|
<table class="shift-table">
|
||||||
|
|
@ -116,32 +182,6 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<table class="shift-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th style="width: 250px;">Day</th>
|
|
||||||
<th style="width: 100px;"># JO</th>
|
|
||||||
<th style="width: 100px;"># Rider</th>
|
|
||||||
<th style="width: 100px;">JO per Rider</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for i in 0..6 %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ hub.data_shift[i].weekday }}</td>
|
|
||||||
<td>{{ hub.data_shift[i].total_jos }}</td>
|
|
||||||
<td>{{ hub.data_shift[i].total_riders }}</td>
|
|
||||||
<td>{{ (hub.data_shift[i].total_jos / hub.data_shift[i].total_riders) | round(1, 'common') }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
<tr>
|
|
||||||
<td>Overall</td>
|
|
||||||
<td>{{ hub.total_jos }}</td>
|
|
||||||
<td>{{ hub.total_riders }}</td>
|
|
||||||
<td>{{ (hub.total_jos / hub.total_riders) | round(1, 'common') }}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue