Create InventoryManager service to connect to API. #374
This commit is contained in:
parent
0e09705c1d
commit
eb5710b846
5 changed files with 186 additions and 102 deletions
|
|
@ -57,3 +57,9 @@ COUNTRY_CODE=+insert_country_code_here
|
||||||
|
|
||||||
# dashboard
|
# dashboard
|
||||||
DASHBOARD_ENABLE=set_to_true_or_false
|
DASHBOARD_ENABLE=set_to_true_or_false
|
||||||
|
|
||||||
|
# auth token for Inventory API
|
||||||
|
INVENTORY_API_URL=insert_api_url_here
|
||||||
|
INVENTORY_API_OCP=insert_ocp_text_here
|
||||||
|
INVENTORY_API_AUTH_TOKEN_PREFIX=Bearer
|
||||||
|
INVENTORY_API_AUTH_TOKEN=insert_auth_token_here
|
||||||
|
|
|
||||||
|
|
@ -230,5 +230,7 @@ services:
|
||||||
# inventory manager
|
# inventory manager
|
||||||
App\Service\InventoryManager:
|
App\Service\InventoryManager:
|
||||||
arguments:
|
arguments:
|
||||||
$em: "@doctrine.orm.entity_manager"
|
$api_url: "%env(INVENTORY_API_URL)%"
|
||||||
$map_tools: "@App\\Service\\MapTools"
|
$api_ocp_key: "%env(INVENTORY_API_OCP)%"
|
||||||
|
$api_auth_prefix: "%env(INVENTORY_API_AUTH_TOKEN_PREFIX)%"
|
||||||
|
$api_auth_token: "%env(INVENTORY_API_AUTH_TOKEN)%"
|
||||||
|
|
|
||||||
|
|
@ -230,5 +230,7 @@ services:
|
||||||
# inventory manager
|
# inventory manager
|
||||||
App\Service\InventoryManager:
|
App\Service\InventoryManager:
|
||||||
arguments:
|
arguments:
|
||||||
$em: "@doctrine.orm.entity_manager"
|
$api_url: "%env(INVENTORY_API_URL)%"
|
||||||
$map_tools: "@App\\Service\\MapTools"
|
$api_ocp_key: "%env(INVENTORY_API_OCP)%"
|
||||||
|
$api_auth_prefix: "%env(INVENTORY_API_AUTH_TOKEN_PREFIX)%"
|
||||||
|
$api_auth_token: "%env(INVENTORY_API_AUTH_TOKEN)%"
|
||||||
|
|
|
||||||
|
|
@ -1079,6 +1079,7 @@ class JobOrderController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
public function autoAssignSubmit(Request $req, JobOrderHandlerInterface $jo_handler,
|
public function autoAssignSubmit(Request $req, JobOrderHandlerInterface $jo_handler,
|
||||||
|
EntityManagerInterface $em, MapTools $map_tools,
|
||||||
InventoryManager $im)
|
InventoryManager $im)
|
||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('jo_autoassign.test', null, 'No access.');
|
$this->denyAccessUnlessGranted('jo_autoassign.test', null, 'No access.');
|
||||||
|
|
@ -1104,7 +1105,7 @@ class JobOrderController extends Controller
|
||||||
|
|
||||||
if (($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) ||
|
if (($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) ||
|
||||||
($jo->getServicetype() == ServiceType::BATTERY_REPLACEMENT_WARRANTY))
|
($jo->getServicetype() == ServiceType::BATTERY_REPLACEMENT_WARRANTY))
|
||||||
$im->autoAssignHubAndRider($jo);
|
$this->autoAssignHubAndRider($jo, $em, $map_tools, $im);
|
||||||
|
|
||||||
// return successful response
|
// return successful response
|
||||||
return $this->json([
|
return $this->json([
|
||||||
|
|
@ -1112,4 +1113,126 @@ class JobOrderController extends Controller
|
||||||
]);
|
]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function autoAssignHubAndRider($jo, EntityManagerInterface $em,
|
||||||
|
MapTools $map_tools, InventoryManager $im)
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
|
// TODO: uncomment this when we have branch codes in data
|
||||||
|
// and when they have real codes and not test ones
|
||||||
|
//$nearest_branch_codes[] = $hub['hub']->getBranchCode();
|
||||||
|
$nearest_branch_codes[] = $hub['hub'];
|
||||||
|
$nearest_branch_codes = ['WestAve','jay_franchise'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// get battery sku
|
||||||
|
$invoice = $jo->getInvoice();
|
||||||
|
if ($invoice != null)
|
||||||
|
{
|
||||||
|
$items = $invoice->getItems();
|
||||||
|
$skus = [];
|
||||||
|
foreach ($items as $item)
|
||||||
|
{
|
||||||
|
// TODO: uncomment this when they have real codes and not test ones
|
||||||
|
//$skus[] = $item->getBattery()->getSAPCode();
|
||||||
|
$skus[] = 'WMGD31EL-CPNM0-L';
|
||||||
|
}
|
||||||
|
|
||||||
|
// api call to check inventory
|
||||||
|
// pass the list of branch codes of nearest hubs and the skus
|
||||||
|
// go through returned list of branch codes
|
||||||
|
$hubs_with_inventory = $im->getBranchInventory($nearest_branch_codes, $skus);
|
||||||
|
// TODO: check for empty result for now.
|
||||||
|
if (!empty($hubs_with_inventory))
|
||||||
|
{
|
||||||
|
$nearest = [];
|
||||||
|
$flag_hub_found = false;
|
||||||
|
foreach ($hubs_with_inventory as $hub_with_inventory)
|
||||||
|
{
|
||||||
|
error_log($hub_with_inventory['BranchCode']);
|
||||||
|
// find hub according to branch code
|
||||||
|
$found_hub = $em->getRepository(Hub::class)->findOneBy(['branch_code' => $hub_with_inventory['BranchCode']]);
|
||||||
|
if ($found_hub != null)
|
||||||
|
{
|
||||||
|
// check rider availability
|
||||||
|
if (count($found_hub->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 ($found_hub->getID() == $nhd['hub']->getID())
|
||||||
|
{
|
||||||
|
if (empty($nearest))
|
||||||
|
{
|
||||||
|
$nearest = $nhd;
|
||||||
|
$flag_hub_found = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($nhd['distance'] < $nearest['distance'])
|
||||||
|
{
|
||||||
|
$nearest = $nhd;
|
||||||
|
$flag_hub_found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($flag_hub_found)
|
||||||
|
{
|
||||||
|
$jo->setHub($nearest['hub']);
|
||||||
|
|
||||||
|
$hub_riders = $nearest['hub']->getAvailableRiders();
|
||||||
|
$rider = null;
|
||||||
|
if (count($hub_riders) > 1)
|
||||||
|
{
|
||||||
|
// TODO: 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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,121 +2,72 @@
|
||||||
|
|
||||||
namespace App\Service;
|
namespace App\Service;
|
||||||
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
|
|
||||||
use App\Entity\JobOrder;
|
|
||||||
use App\Entity\Hub;
|
|
||||||
|
|
||||||
use App\Ramcar\JOStatus;
|
|
||||||
|
|
||||||
class InventoryManager
|
class InventoryManager
|
||||||
{
|
{
|
||||||
protected $em;
|
protected $api_url;
|
||||||
protected $map_tools;
|
protected $api_ocp_key;
|
||||||
|
protected $api_auth_prefix;
|
||||||
|
protected $api_auth_token;
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em, MapTools $map_tools)
|
public function __construct($api_url, $api_ocp_key, $api_auth_prefix, $api_auth_token)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->api_url = $api_url;
|
||||||
$this->map_tools = $map_tools;
|
$this->api_ocp_key = $api_ocp_key;
|
||||||
|
$this->api_auth_prefix = $api_auth_prefix;
|
||||||
|
$this->api_auth_token = $api_auth_token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function autoAssignHubAndRider(JobOrder $jo)
|
public function getBranchInventory($nearest_branch_codes, $skus)
|
||||||
{
|
{
|
||||||
// get the nearest 10 hubs
|
// api call to check inventory
|
||||||
// TODO: move this snippet to a function
|
// pass the list of branch codes and the skus
|
||||||
$hubs = $this->map_tools->getClosestHubs($jo->getCoordinates(), 10, date("H:i:s"));
|
$data = [
|
||||||
|
"BranchCodes" => $nearest_branch_codes,
|
||||||
|
"Skus" => $skus,
|
||||||
|
];
|
||||||
|
|
||||||
$nearest_hubs = [];
|
$json_data = json_encode($data);
|
||||||
$nearest_hubs_with_distance = [];
|
error_log('JSON ' . $json_data);
|
||||||
|
|
||||||
foreach ($hubs as $hub)
|
// initializes a new cURL session
|
||||||
{
|
$curl = curl_init($this->api_url);
|
||||||
$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
|
// Set the CURLOPT_RETURNTRANSFER option to true
|
||||||
$invoice = $jo->getInvoice();
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||||
if ($invoice != null)
|
|
||||||
{
|
|
||||||
$items = $invoice->getItems();
|
|
||||||
$sku = '';
|
|
||||||
foreach ($items as $item)
|
|
||||||
{
|
|
||||||
$sku = $item->getBattery()->getSAPCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
// api call to check inventory
|
// Set the CURLOPT_POST option to true for POST request
|
||||||
// pass the list of nearest hubs and the sku
|
curl_setopt($curl, CURLOPT_POST, true);
|
||||||
// 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']);
|
// Set the request data as JSON using json_encode function
|
||||||
|
curl_setopt($curl, CURLOPT_POSTFIELDS, $json_data);
|
||||||
|
|
||||||
$hub_riders = $nearest['hub']->getAvailableRiders();
|
// set timeout
|
||||||
$rider = null;
|
curl_setopt($curl, CURLOPT_TIMEOUT, 300);
|
||||||
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);
|
$authorization = $this->api_auth_prefix . ' ' . $this->api_auth_token;
|
||||||
}
|
$ocp = $this->api_ocp_key;
|
||||||
else
|
|
||||||
$rider = $hub_riders[0];
|
|
||||||
|
|
||||||
$jo->setRider($rider);
|
curl_setopt($curl, CURLOPT_HTTPHEADER, [
|
||||||
|
'Authorization: ' . $authorization,
|
||||||
|
'Content-Type: application/json',
|
||||||
|
'Ocp-Apim-Subscription-Key: ' . $ocp,
|
||||||
|
]);
|
||||||
|
|
||||||
$jo->setStatus(JOStatus::ASSIGNED);
|
$response = curl_exec($curl);
|
||||||
|
|
||||||
$this->em->persist($jo);
|
// close cURL session
|
||||||
$this->em->flush();
|
curl_close($curl);
|
||||||
|
|
||||||
}
|
// response is array of these
|
||||||
|
// {
|
||||||
|
// "BranchCode": "TestBranch1",
|
||||||
|
// "BranchName": "Test Branch",
|
||||||
|
// "SapCode": "WMGD31EL-CPNM0-L",
|
||||||
|
// "Quantity": 4
|
||||||
|
// },
|
||||||
|
$results = json_decode($response, true);
|
||||||
|
|
||||||
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue