diff --git a/config/resq.services.yaml b/config/resq.services.yaml index 1756cf98..f38949c5 100644 --- a/config/resq.services.yaml +++ b/config/resq.services.yaml @@ -226,3 +226,9 @@ services: $redis_prov: "@App\\Service\\RedisClientProvider" $loc_key: "%env(LOCATION_RIDER_ACTIVE_KEY)%" $status_key: "%env(STATUS_RIDER_KEY)%" + + # inventory manager + App\Service\InventoryManager: + arguments: + $em: "@doctrine.orm.entity_manager" + $map_tools: "@App\\Service\\MapTools" diff --git a/config/services.yaml b/config/services.yaml index 1756cf98..f38949c5 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -226,3 +226,9 @@ services: $redis_prov: "@App\\Service\\RedisClientProvider" $loc_key: "%env(LOCATION_RIDER_ACTIVE_KEY)%" $status_key: "%env(STATUS_RIDER_KEY)%" + + # inventory manager + App\Service\InventoryManager: + arguments: + $em: "@doctrine.orm.entity_manager" + $map_tools: "@App\\Service\\MapTools" diff --git a/src/Controller/JobOrderController.php b/src/Controller/JobOrderController.php index cdb2d665..97b49565 100644 --- a/src/Controller/JobOrderController.php +++ b/src/Controller/JobOrderController.php @@ -21,6 +21,7 @@ use App\Service\GISManagerInterface; use App\Service\MapTools; use App\Service\MQTTClient; use App\Service\APNSClient; +use App\Service\InventoryManager; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -1078,7 +1079,7 @@ class JobOrderController extends Controller } public function autoAssignSubmit(Request $req, JobOrderHandlerInterface $jo_handler, - EntityManagerInterface $em, MapTools $map_tools) + InventoryManager $im) { $this->denyAccessUnlessGranted('jo_autoassign.test', null, 'No access.'); @@ -1103,8 +1104,7 @@ class JobOrderController extends Controller if (($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) || ($jo->getServicetype() == ServiceType::BATTERY_REPLACEMENT_WARRANTY)) - $this->autoAssignHubAndRider($jo, $em, $map_tools); - + $im->autoAssignHubAndRider($jo); // return successful response return $this->json([ @@ -1112,106 +1112,4 @@ class JobOrderController extends Controller ]); } - - protected function autoAssignHubAndRider($jo, EntityManagerInterface $em, MapTools $map_tools) - { - // get the nearest 10 hubs - // TODO: move this snippet to a function - $hubs = $map_tools->getClosestHubs($jo->getCoordinates(), 10, date("H:i:s")); - - $nearest_hubs = []; - $nearest_hubs_with_distance = []; - - foreach ($hubs as $hub) - { - $nearest_hubs_with_distance[] = $hub; - $nearest_hubs[] = $hub['hub']; - } - - // get battery sku - $invoice = $jo->getInvoice(); - if ($invoice != null) - { - $items = $invoice->getItems(); - $sku = ''; - foreach ($items as $item) - { - $sku = $item->getBattery()->getSAPCode(); - } - - // api call to check inventory - // pass the list of nearest hubs and the sku - // go through returned list of hubs for available riders - // for now, use all hubs - $hubs_with_inventory = $em->getRepository(Hub::class)->findAll(); - $nearest = []; - foreach ($hubs_with_inventory as $hub_with_inventory) - { - // check rider availability - if (count($hub_with_inventory->getAvailableRiders()) > 0) - { - // check against nearest hubs with distance - foreach ($nearest_hubs_with_distance as $nhd) - { - // get distance of hub from location, compare with $nearest. if less, replace nearest - if ($hub_with_inventory->getID() == $nhd['hub']->getID()) - { - if (empty($nearest)) - { - $nearest = $nhd; - } - else - { - if ($nhd['distance'] < $nearest['distance']) - $nearest = $nhd; - } - } - } - } - } - - // return $nearest - error_log('Nearest Hub ' . $nearest['hub']->getID()); - error_log('With distance ' . $nearest['distance']); - - $jo->setHub($nearest['hub']); - - $hub_riders = $nearest['hub']->getAvailableRiders(); - $rider = null; - if (count($hub_riders) > 1) - { - // this will no longer be necessary when the contents - // of randomizeRider changes - $available_riders = []; - foreach ($hub_riders as $rider) - { - $available_riders[] = $rider; - } - - $rider = $this->randomizeRider($available_riders); - } - else - $rider = $hub_riders[0]; - - $jo->setRider($rider); - - $jo->setStatus(JOStatus::ASSIGNED); - - $em->persist($jo); - $em->flush(); - - } - } - - protected function randomizeRider($riders) - { - // TODO: get redis to track the sales per rider per day - // check the time they came in - // for now, randomize the rider - $selected_index = array_rand($riders); - - $selected_rider = $riders[$selected_index]; - - return $selected_rider; - } } diff --git a/src/Entity/Hub.php b/src/Entity/Hub.php index 840f6d8c..03e0b202 100644 --- a/src/Entity/Hub.php +++ b/src/Entity/Hub.php @@ -44,6 +44,12 @@ class Hub */ protected $outlets; + // branch code + /** + * @ORM\Column(type="string", length=80) + */ + protected $branch_code; + public function __construct() { $this->time_open = new DateTime(); @@ -114,4 +120,16 @@ class Hub { return $this->outlets; } + + public function setBranchCode($branch_code) + { + $this->branch_code = $branch_code; + return $this; + } + + public function getBranchCode() + { + return $this->branch_code; + } + } diff --git a/src/Service/InventoryManager.php b/src/Service/InventoryManager.php new file mode 100644 index 00000000..6620e9ab --- /dev/null +++ b/src/Service/InventoryManager.php @@ -0,0 +1,122 @@ +em = $em; + $this->map_tools = $map_tools; + } + + public function autoAssignHubAndRider(JobOrder $jo) + { + // get the nearest 10 hubs + // TODO: move this snippet to a function + $hubs = $this->map_tools->getClosestHubs($jo->getCoordinates(), 10, date("H:i:s")); + + $nearest_hubs = []; + $nearest_hubs_with_distance = []; + + foreach ($hubs as $hub) + { + $nearest_hubs_with_distance[] = $hub; + // TODO: uncomment this when we have branch codes in data + //$nearest_hubs[] = $hub['hub']->getBranchCode(); + $nearest_hubs[] = $hub['hub']; + } + + // get battery sku + $invoice = $jo->getInvoice(); + if ($invoice != null) + { + $items = $invoice->getItems(); + $sku = ''; + foreach ($items as $item) + { + $sku = $item->getBattery()->getSAPCode(); + } + + // api call to check inventory + // pass the list of nearest hubs and the sku + // go through returned list of hubs for available riders + // for now, use all hubs + $hubs_with_inventory = $this->em->getRepository(Hub::class)->findAll(); + $nearest = []; + foreach ($hubs_with_inventory as $hub_with_inventory) + { + // check rider availability + if (count($hub_with_inventory->getAvailableRiders()) > 0) + { + // check against nearest hubs with distance + foreach ($nearest_hubs_with_distance as $nhd) + { + // get distance of hub from location, compare with $nearest. if less, replace nearest + if ($hub_with_inventory->getID() == $nhd['hub']->getID()) + { + if (empty($nearest)) + { + $nearest = $nhd; + } + else + { + if ($nhd['distance'] < $nearest['distance']) + $nearest = $nhd; + } + } + } + } + } + + $jo->setHub($nearest['hub']); + + $hub_riders = $nearest['hub']->getAvailableRiders(); + $rider = null; + if (count($hub_riders) > 1) + { + // this will no longer be necessary when the contents + // of randomizeRider changes + $available_riders = []; + foreach ($hub_riders as $rider) + { + $available_riders[] = $rider; + } + + $rider = $this->randomizeRider($available_riders); + } + else + $rider = $hub_riders[0]; + + $jo->setRider($rider); + + $jo->setStatus(JOStatus::ASSIGNED); + + $this->em->persist($jo); + $this->em->flush(); + + } + } + + protected function randomizeRider($riders) + { + // TODO: get redis to track the sales per rider per day + // check the time they came in + // for now, randomize the rider + $selected_index = array_rand($riders); + + $selected_rider = $riders[$selected_index]; + + return $selected_rider; + } +}