diff --git a/config/services.yaml b/config/services.yaml index 8f05c28b..4fb5f088 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -270,3 +270,4 @@ services: App\Service\HubSelector: arguments: $em: "@doctrine.orm.entity_manager" + $im: "@App\\Service\\InventoryManager" diff --git a/src/Service/HubSelector.php b/src/Service/HubSelector.php index a2f5d53f..6773f0d8 100644 --- a/src/Service/HubSelector.php +++ b/src/Service/HubSelector.php @@ -8,6 +8,8 @@ use CrEOF\Spatial\PHP\Types\Geometry\Point; use App\Entity\Hub; +use App\Service\InventoryManager; + use App\Ramcar\HubCriteria; use App\Ramcar\ServiceType; @@ -15,9 +17,10 @@ class HubSelector { protected $em; - public function __construct(EntityManagerInterface $em) + public function __construct(EntityManagerInterface $em, InventoryManager $im) { $this->em = $em; + $this->im = $im; } public function find(HubCriteria $criteria) @@ -42,10 +45,12 @@ class HubSelector if ($date_time != null) { // call function for jo type, inventory == true, and check for date and time + $results = $this->getClosestHubsWithJoTypeAndInventoryAndTime($point, $limit_results, $limit_distance, $jo_type, $items, $date_time); } else { // call function for jo type and inventory == true + $results = $this->getClosestHubsWithJoTypeAndInventory($point, $limit_results, $limit_distance, $jo_type, $items); } } else @@ -82,18 +87,130 @@ class HubSelector return $results; } - protected function getClosestHubsWithJoTypeAndTime($point, $limit_results, $limit_distance, $jo_type, $date_time) + protected function getClosestHubsWithJoTypeAndInventoryAndTime($point, $limit_results, $limit_distance, $jo_type, $items, $date_time) { // get closest hubs that are open at the given time offering jo_type service based on st_distance function from db - $query = $this->em->createQuery('SELECT h, st_distance(h.coordinates, point(:lng, :lat)) as dist FROM App\Entity\Hub h' . ($time ? ' WHERE :time BETWEEN h.time_open AND h.time_close' : '') . ' ORDER BY dist') + $query = $this->em->createQuery('SELECT h, st_distance(h.coordinates, point(:lng, :lat)) as dist FROM App\Entity\Hub h' . ($time ? ' WHERE :time BETWEEN h.time_open AND h.time_close' : '') . ' ORDER BY dist'); $query = $this->em->createQuery($query_string) ->setParameter('lat', $point->getLatitude()) ->setParameter('lng', $point->getLongitude()); - // add the jo_type/service parameter + // TODO: add the jo_type/service parameter - // have to add date and time to query + // TODO: have to add date and time to query + // right now, hub only has opening times + // so we extract the time from date_time + $time = $date_time->format("H:i:s"); + if ($time) { + $query->setParameter('time', $time); + } + + $query->setMaxResults($limit_results); + + // error_log($query->getSql()); + $result = $query->getResult(); + + $hubs = []; + $final_data = []; + foreach ($result as $row) + { + $hubs[] = $row[0]; + + // get coordinates of hub + $hub_coordinates = $row[0]->getCoordinates(); + + $cust_lat = $point->getLatitude(); + $cust_lng = $point->getLongitude(); + + $hub_lat = $hub_coordinates->getLatitude(); + $hub_lng = $hub_coordinates->getLongitude(); + + // get distance in kilometers from customer point to hub point + $dist = $this->distance($cust_lat, $cust_lng, $hub_lat, $hub_lng); + + if ($dist < $limit_distance) + { + // TODO: insert call to function that will check inventory here + // checkInventory is going to return true if hub has all items + $this->checkInventory($items, $$row[0]); + // TODO: add checking here if hub has all items or not + $final_data[] = [ + 'hub' => $row[0], + 'db_distance' => $row['dist'], + 'distance' => $dist, + 'duration' => 0, + ]; + } + } + + return $final_data; + } + + protected function getClosestHubsWithJoTypeAndInventory($point, $limit_results, $limit_distance, $jo_type, $items) + { + // get closest hubs based on st_distance function from db + $query_string = 'SELECT h, st_distance(h.coordinates, point(:lng, :lat)) as dist FROM App\Entity\Hub h WHERE h.status_open = true ORDER BY dist'; + + $query = $this->em->createQuery($query_string) + ->setParameter('lat', $point->getLatitude()) + ->setParameter('lng', $point->getLongitude()); + + // TODO: add the jo_type/service parameter + + $query->setMaxResults($limit_results); + + // error_log($query->getSql()); + $result = $query->getResult(); + + $hubs = []; + $final_data = []; + foreach ($result as $row) + { + $hubs[] = $row[0]; + + // get coordinates of hub + $hub_coordinates = $row[0]->getCoordinates(); + + $cust_lat = $point->getLatitude(); + $cust_lng = $point->getLongitude(); + + $hub_lat = $hub_coordinates->getLatitude(); + $hub_lng = $hub_coordinates->getLongitude(); + + // get distance in kilometers from customer point to hub point + $dist = $this->distance($cust_lat, $cust_lng, $hub_lat, $hub_lng); + + if ($dist < $limit_distance) + { + // TODO: insert call to function that will check inventory here + // checkInventory is going to return true if hub has all items + $this->checkInventory($items, $$row[0]); + // TODO: add checking here if hub has all items or not + $final_data[] = [ + 'hub' => $row[0], + 'db_distance' => $row['dist'], + 'distance' => $dist, + 'duration' => 0, + ]; + } + } + + return $final_data; + } + + protected function getClosestHubsWithJoTypeAndTime($point, $limit_results, $limit_distance, $jo_type, $date_time) + { + // get closest hubs that are open at the given time offering jo_type service based on st_distance function from db + $query = $this->em->createQuery('SELECT h, st_distance(h.coordinates, point(:lng, :lat)) as dist FROM App\Entity\Hub h' . ($time ? ' WHERE :time BETWEEN h.time_open AND h.time_close' : '') . ' ORDER BY dist'); + + $query = $this->em->createQuery($query_string) + ->setParameter('lat', $point->getLatitude()) + ->setParameter('lng', $point->getLongitude()); + + // TODO: add the jo_type/service parameter + + // TODO: have to add date and time to query // right now, hub only has opening times // so we extract the time from date_time $time = $date_time->format("H:i:s"); @@ -147,7 +264,7 @@ class HubSelector ->setParameter('lat', $point->getLatitude()) ->setParameter('lng', $point->getLongitude()); - // add the jo type/service parameter here + // TODO: add the jo type/service parameter here $query->setMaxResults($limit_results); @@ -195,7 +312,7 @@ class HubSelector ->setParameter('lat', $point->getLatitude()) ->setParameter('lng', $point->getLongitude()); - // have to add date and time to query + // TODO: have to add date and time to query // right now, hub only has opening times // so we extract the time from date_time $time = $date_time->format("H:i:s"); @@ -286,6 +403,13 @@ class HubSelector return $final_data; } + protected function checkInventory($items, $hub) + { + // check if hub has all items + + // return true or false + } + // convert db distance to kilometers protected function distance($lat1, $lon1, $lat2, $lon2) {