diff --git a/src/Controller/AnalyticsController.php b/src/Controller/AnalyticsController.php index 56934b4f..ed492600 100644 --- a/src/Controller/AnalyticsController.php +++ b/src/Controller/AnalyticsController.php @@ -5,6 +5,7 @@ namespace App\Controller; use Doctrine\ORM\Query; use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\EntityManagerInterface; + use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Bundle\FrameworkBundle\Controller\Controller; @@ -14,6 +15,7 @@ use Catalyst\MenuBundle\Annotation\Menu; use CrEOF\Spatial\PHP\Types\Geometry\Point; use DateTime; +use DateInterval; use App\Entity\JobOrder; use App\Entity\Hub; @@ -26,6 +28,10 @@ class AnalyticsController extends Controller */ public function forecast(EntityManagerInterface $em) { + + $date_start = DateTime::createFromFormat('Y-m-d H:i:s', '2018-01-01 00:00:00'); + $date_end = DateTime::createFromFormat('Y-m-d H:i:s', '2020-04-31 23:59:59'); + // get hub to analyze $hub = $em->getRepository(Hub::class)->find(86); $hub_coord = $hub->getCoordinates(); @@ -33,20 +39,130 @@ class AnalyticsController extends Controller // distance limit in meters $distance = 5000; + $conn = $em->getConnection(); + // create query // formula to convert to km is 111195 * st_distance - $query = $em->createQuery('select jo from App\\Entity\\JobOrder jo where st_distance(jo.coordinates, point(:lng, :lat)) * 111195 <= :distance_limit and jo.date_schedule >= :date_start and jo.date_schedule <= :date_end'); - $query->setParameter('lng', $hub_coord->getLongitude()) - ->setParameter('lat', $hub_coord->getLatitude()) - ->setParameter('distance_limit', $distance) - ->setParameter('date_start', DateTime::createFromFormat('YmdHis', '20180501000000')) - ->setParameter('date_end', DateTime::createFromFormat('YmdHis', '20180531235959')); - $jos = $query->getResult(); + $sql = "select id, round(st_distance(coordinates, Point(:lng, :lat)) * 111195) as dist, date_schedule from job_order where st_distance(coordinates, Point(:lng, :lat)) * 111195 <= :distance_limit and date_schedule >= :date_start and date_schedule <= :date_end and status <> 'cancelled' order by date_schedule asc"; + // $query = $em->createQuery('select jo from App\\Entity\\JobOrder jo where st_distance(jo.coordinates, point(:lng, :lat)) * 111195 <= :distance_limit and jo.date_schedule >= :date_start and jo.date_schedule <= :date_end'); + $stmt = $conn->prepare($sql); + $stmt->bindValue('lng', $hub_coord->getLongitude()); + $stmt->bindValue('lat', $hub_coord->getLatitude()); + $stmt->bindValue('distance_limit', $distance); + $stmt->bindValue('date_start', $date_start->format('Y-m-d H:i:s')); + $stmt->bindValue('date_end', $date_end->format('Y-m-d H:i:s')); + $stmt->execute(); + $jos = $stmt->fetchAll(); error_log(count($jos)); + + // get 'today' + $today = new DateTime(); + $today = DateTime::createFromFormat('Ymd', '20201101'); + + // initialize counters + $c_weekday = []; + $c_day = []; + + // loop through job orders + foreach ($jos as $jo) + { + $date = DateTime::createFromFormat('Y-m-d H:i:s', $jo['date_schedule']); + $year = $date->format('Y'); + $month = $date->format('m'); + $day = $date->format('d'); + $weekday = $date->format('l'); + $hour = $date->format('H'); + + // year day + if (!isset($c_day[$year][$month][$day])) + $c_day[$year][$month][$day] = 0; + $c_day[$year][$month][$day]++; + + // weekday + if (!isset($c_weekday[$year][$month][$weekday][$hour])) + $c_weekday[$year][$month][$weekday][$hour] = 0; + $c_weekday[$year][$month][$weekday][$hour]++; + } + + error_log(print_r($c_weekday, true)); + + $res_year = []; + $date_loop = clone $date_start; + for (; $date_loop <= $date_end; $date_loop->add(new DateInterval('P1D'))) + { + $year = $date_loop->format('Y'); + $month = $date_loop->format('m'); + $day = $date_loop->format('d'); + $year_field = 'y' . $date_loop->format('Y'); + $id = $date_loop->format('m-d'); + + // NOTE: toss aside feb 29 + if ($id == '02-29') + continue; + + if (!isset($res_year[$id][$year_field])) + { + $res_year[$id]['date'] = $date_loop->format('M j'); + $res_year[$id][$year_field] = 0; + } + + if (isset($c_day[$year][$month][$day])) + $res_year[$id][$year_field] = $c_day[$year][$month][$day]; + } + + // error_log(print_r($res_year, true)); + + $chart_year = []; + foreach ($res_year as $day => $day_data) + $chart_year[] = $day_data; + + // error_log(print_r($chart_year, true)); + + // error_log(print_r($c_day, true)); + + $chart_weekday = $this->generateWeekdayData($c_weekday, $today); + + error_log(print_r($chart_weekday, true)); - $params = []; + $params = [ + 'data_year' => $chart_year, + 'data_weekday' => $chart_weekday, + ]; return $this->render('analytics/forecast.html.twig', $params); } + + protected function generateWeekdayData($all_weekday_data, $today) + { + $data = []; + + // build hours + $hours = []; + for ($i = 0; $i < 24; $i++) + $hours[] = sprintf('%02d', $i); + + $month = $today->format('m'); + $weekday = $today->format('l'); + + $year_data = []; + foreach ($all_weekday_data as $year => $year_data) + { + // go through the hours + foreach ($hours as $hour) + { + $id = $hour + 0; + if (!isset($data[$id])) + $data[$id] = [ + 'hour' => $hour, + ]; + + // get hour data + if (isset($year_data[$month][$weekday][$hour])) + $data[$id]['y' . $year] = $year_data[$month][$weekday][$hour]; + } + } + + return $data; + } } diff --git a/templates/analytics/forecast.html.twig b/templates/analytics/forecast.html.twig index 8d9997f3..cee5b87f 100644 --- a/templates/analytics/forecast.html.twig +++ b/templates/analytics/forecast.html.twig @@ -25,7 +25,10 @@ -
+
+
+ +
@@ -39,70 +42,67 @@ {% endblock %}