From ede1d0412365241cbd33b353d469845a65e705d5 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Fri, 24 Apr 2020 09:32:46 +0000 Subject: [PATCH] Add API call to get nearest hubs and slots. #389 --- config/routes/api.yaml | 5 + src/Controller/APIController.php | 437 +++++++++++++++++++++++++++++++ 2 files changed, 442 insertions(+) diff --git a/config/routes/api.yaml b/config/routes/api.yaml index f55b0d83..fbbdecfd 100644 --- a/config/routes/api.yaml +++ b/config/routes/api.yaml @@ -149,3 +149,8 @@ api_partner_review: path: /api/partners/{pid}/review controller: App\Controller\APIController:reviewPartner methods: [POST] + +api_nearest_hub_slots: + path: /api/hub_slots/{jo_id} + controller: App\Controller\APIController::getNearestHubAndSlots + methods: [GET] diff --git a/src/Controller/APIController.php b/src/Controller/APIController.php index 38472669..aae32486 100644 --- a/src/Controller/APIController.php +++ b/src/Controller/APIController.php @@ -2364,6 +2364,56 @@ class APIController extends Controller implements LoggedController return $res->getReturnResponse(); } + public function getNearestHubAndSlots(Request $req, $jo_id, EntityManagerInterface $em, + MapTools $map_tools) + { + $required_params = []; + + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + // find JO + $jo = $em->getRepository(JobOrder::class)->find($jo_id); + if ($jo == null) + { + $res->setError(true) + ->setErrorMessage('No job order found.'); + return $res->getReturnResponse(); + } + + // find nearest hub + if (($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) || + ($jo->getServicetype() == ServiceType::BATTERY_REPLACEMENT_WARRANTY)) + { + // get nearest hub + // TODO: might have to find advance nearest hub with inventory later + $nearest_hub_slots = $this->findAdvanceNearestHubAndSlots($jo, $em, $map_tools); + } + else + { + $nearest_hub_slots = $this->findAdvanceNearestHubAndSlots($jo, $em, $map_tools); + } + + if (empty($nearest_hub_slots['hub'])) + { + $res->setError(true) + ->setErrorMessage('No hub found.'); + return $res->getReturnResponse(); + } + + // make hub data + $data = [ + 'hub_id' => $nearest_hub_slots['hub']->getID(), + 'hub_slots' => $nearest_hub_slots['slots'], + ]; + + $res->setData($data); + + return $res->getReturnResponse(); + + } + protected function findCustomerByNumber($number) { $em = $this->getDoctrine()->getManager(); @@ -2732,6 +2782,7 @@ class APIController extends Controller implements LoggedController // 5 - 13-14 // 6 - 14-15 // 7 - 15-16 + // TODO: check if no pending JOs foreach ($jos_advance_orders as $advance_jo) { // get time schedule @@ -2863,4 +2914,390 @@ class APIController extends Controller implements LoggedController } return $results; } + + protected function findAdvanceNearestHubAndSlots(JobOrder $jo, EntityManagerInterface $em, MapTools $map_tools) + { + // get the nearest 10 hubs + $hub_data = []; + $hubs = $map_tools->getClosestOpenHubs($jo->getCoordinates(), 10); + + foreach ($hubs as $hub) + { + $nearest_hubs_with_distance[] = $hub; + // TODO: insert checking for branch code here when inventory manager is up + } + + $nearest = null; + $slot_found = false; + // find the nearest hub + foreach ($nearest_hubs_with_distance as $nhd) + { + if (empty($nearest)) + $nearest = $nhd; + else + { + if ($nhd['distance'] < $nearest['distance']) + $nearest = $nhd; + } + } + + // get slots of nearest hub + if ($nearest != null) + { + $hub_slots = $this->getHubRiderSlots($nearest['hub'], $em); + + $hub_data = [ + 'hub' => $nearest['hub'], + 'slots' => $hub_slots, + ]; + } + + return $hub_data; + + } + + protected function getHubRiderSlots(Hub $hub, EntityManagerInterface $em) + { + // array of # of riders that can handle JOs in a timeslot + $hub_rider_slots = []; + + // populate the array with the hub's rider slots + for ($i = 0; $i <=7; $i++) + { + $hub_rider_slots[$i] = $hub->getRiderSlots(); + } + + // check hub's advance orders for the day + // get number of advance orders for the next day if request came in before midnight + // or for current day if request came in after midnight + // check request_time + $request_time = time(); + $midnight = strtotime('00:00'); + $start_date = new DateTime(); + $end_date = new DateTime(); + + if ($request_time < $midnight) + { + // add +1 to start date to get the next day + // add +3 to date to end date to get the advance orders for the next three days + $start_date->add(new DateInterval('P1D')); + } + $end_date->add(new DateInterval('P2D')); + + // set time bounds for the start and end date + $start_date->setTime(0, 1); + $end_date->setTime(23, 59); + + $str_request_time = date('Y-m-d H:i:s', $request_time); + $time_of_request = DateTime::createFromFormat('Y-m-d H:i:s', $str_request_time); + + // NOTE: get advance orders via query + // get JOs assigned to hub that are advance orders and scheduled for the next three days with + // for hub assignment status + $query = $em->createQuery('select jo from App\Entity\JobOrder jo where jo.hub = :hub and jo.flag_advance = true and + jo.date_schedule >= :date_start and jo.date_schedule <= :date_end and jo.status = :status'); + $jos_advance_orders = $query->setParameters([ + 'hub' => $hub, + 'date_start' => $start_date, + 'date_end' => $end_date, + 'status' => JOStatus::ASSIGNED, + ]) + ->getResult(); + + // check each JO's date_schedule, decrement rider_slots if date schedule falls in that slot + // index - equivalent time + // 0 - 8-9 + // 1 - 9-10 + // 2 - 10-11 + // 3 - 11-12 + // 4 - 12 -13 + // 5 - 13-14 + // 6 - 14-15 + // 7 - 15-16 + $hub_slots = []; + + // get the dates for the next three days + $first_date = $start_date->format('Y-m-d'); + + // 2nd day + $second_date = $start_date->add(new DateInterval('P1D')); + $sec_date = $second_date->format('Y-m-d'); + + // third day + $third_date = $end_date->format('Y-m-d'); + + // no advance orders + if (empty($jos_advance_orders)) + { + // set hub slots for the next three days + $index = -1; // set all slots + $slot_status = true; + + $hub_slots[$first_date] = $this->setHubSlots($index, $slot_status); + $hub_slots[$sec_date] = $this->setHubSlots($index, $slot_status); + $hub_slots[$third_date] = $this->setHubSlots($index, $slot_status); + } + else + { + foreach ($jos_advance_orders as $advance_jo) + { + error_log('advance jo ' . $advance_jo->getID()); + // get time schedule + + // dili date schedule ang isulod sa hub slots! + + $jo_date_schedule = $advance_jo->getDateSchedule(); + + $date_schedule = $jo_date_schedule->format('m-d-Y'); + $time_schedule = $jo_date_schedule->format('H:i'); + + $hour_schedule = $jo_date_schedule->format('H'); + $minute_schedule = $jo_date_schedule->format('i'); + + // check if date in hub slots + if (!isset($hub_slots[$date_schedule])) + { + $hub_slots[$date_schedule] = []; + } + + if ($minute_schedule != '00') + { + switch($hour_schedule) { + case '8': + $hub_rider_slots[0]--; + $hub_rider_slots[1]--; + break; + case '9': + $hub_rider_slots[1]--; + $hub_rider_slots[2]--; + break; + case '10': + $hub_rider_slots[2]--; + $hub_rider_slots[3]--; + break; + case '11': + $hub_rider_slots[3]--; + $hub_rider_slots[4]--; + break; + case '12': + $hub_rider_slots[4]--; + $hub_rider_slots[5]--; + break; + case '13': + $hub_rider_slots[5]--; + $hub_rider_slots[6]--; + break; + case '14': + $hub_rider_slots[6]--; + $hub_rider_slots[7]--; + break; + case '15': + error_log('No slots for the day'); + break; + default: + error_log('Does not fit in any time slot. ' . $time_schedule); + } + } + else + { + switch ($hour_schedule) { + case '8': + $hub_rider_slots[0]--; + break; + case '9': + $hub_rider_slots[1]--; + break; + case '10': + $hub_rider_slots[2]--; + break; + case '11': + $hub_rider_slots[3]--; + break; + case '12': + $hub_rider_slots[4]--; + break; + case '13': + $hub_rider_slots[5]--; + break; + case '14': + $hub_rider_slots[6]--; + break; + case '15': + $hub_rider_slots[7]--; + break; + default: + error_log('Does not fit in any time slot.' . $time_schedule); + } + } + + // check values of hub_rider_slot to mark if available or not + for ($i = 0; $i <=7; $i++) + { + if ($hub_rider_slots[$i] > 0) + { + // set the time label + switch($i) { + case '8': + $hub_slots[$date_schedule] = [ + 'label' => '8-9 AM', + 'available' => true, + ]; + break; + case '9': + $hub_slots[$date_schedule] = [ + 'label' => '9-10 AM', + 'available' => true, + ]; + break; + case '10': + $hub_slots[$date_schedule] = [ + 'label' => '10-11 AM', + 'available' => true, + ]; + break; + case '11': + $hub_slots[$date_schedule] = [ + 'label' => '11 AM-12 PM', + 'available' => true, + ]; + break; + case '12': + $hub_slots[$date_schedule] = [ + 'label' => '12-1 PM', + 'available' => true, + ]; + break; + case '13': + $hub_slots[$date_schedule] = [ + 'label' => '1-2 PM', + 'available' => true, + ]; + break; + case '14': + $hub_slots[$date_schedule] = [ + 'label' => '2-3 PM', + 'available' => true, + ]; + break; + case '15': + $hub_slots[$date_schedule] = [ + 'label' => '3-4 PM', + 'available' => true, + ]; + break; + default: + error_log('Invalid rider slot index.'); + } + } + else + { + // set the time label + switch($i) { + case '8': + $hub_slots[$date_schedule] = [ + 'label' => '8-9 AM', + 'available' => true, + ]; + break; + case '9': + $hub_slots[$date_schedule] = [ + 'label' => '9-10 AM', + 'available' => true, + ]; + break; + case '10': + $hub_slots[$date_schedule] = [ + 'label' => '10-11 AM', + 'available' => true, + ]; + break; + case '11': + $hub_slots[$date_schedule] = [ + 'label' => '11 AM-12 PM', + 'available' => true, + ]; + break; + case '12': + $hub_slots[$date_schedule] = [ + 'label' => '12-1 PM', + 'available' => true, + ]; + break; + case '13': + $hub_slots[$date_schedule] = [ + 'label' => '1-2 PM', + 'available' => true, + ]; + break; + case '14': + $hub_slots[$date_schedule] = [ + 'label' => '2-3 PM', + 'available' => true, + ]; + break; + case '15': + $hub_slots[$date_schedule] = [ + 'label' => '3-4 PM', + 'available' => true, + ]; + break; + default: + error_log('Invalid rider slot index.'); + } + } + } + } + } + + return $hub_slots; + } + + protected function setHubSlots($index, $status) + { + $data = []; + + // set all slots to true + if ($index = -1) + { + $data[] = [ + [ + 'label' => '8-9 AM', + 'available' => $status, + ], + [ + 'label' => '9-10 AM', + 'available' => $status, + ], + [ + 'label' => '10-11 AM', + 'available' => $status, + ], + [ + 'label' => '11 AM-12 PM', + 'available' => $status, + ], + [ + 'label' => '12 PM-1 PM', + 'available' => $status, + ], + [ + 'label' => '1-2 PM', + 'available' => $status, + ], + [ + 'label' => '2-3 PM', + 'available' => $status, + ], + [ + 'label' => '3-4 PM', + 'available' => $status, + ] + ]; + } + else + { + } + + return $data; + } }