Add newRequestJobOrder API call. #389

This commit is contained in:
Korina Cordero 2020-04-28 09:08:48 +00:00
parent 383fc1ee0a
commit f030eeef2a
3 changed files with 410 additions and 0 deletions

View file

@ -154,3 +154,8 @@ api_nearest_hub_slots:
path: /api/hub_slots
controller: App\Controller\APIController::getNearestHubAndSlots
methods: [GET]
api_new_jo_request:
path: /api/new_job_order
controller: App\Controller\APIController::newRequestJobOrder
methods: [POST]

View file

@ -23,6 +23,7 @@ use App\Ramcar\APIRiderStatus;
use App\Ramcar\TransactionOrigin;
use App\Ramcar\TradeInType;
use App\Ramcar\JOEventType;
use App\Ramcar\AdvanceOrderSlot;
use App\Service\InvoiceGeneratorInterface;
use App\Service\RisingTideGateway;
@ -2305,6 +2306,342 @@ class APIController extends Controller implements LoggedController
}
public function newRequestJobOrder(Request $req, InvoiceGeneratorInterface $ic, GeofenceTracker $geo,
MapTools $map_tools, InventoryManager $im, MQTTClient $mclient,
RiderAssignmentHandlerInterface $rah)
{
// check required parameters and api key
$required_params = [
'service_type',
'cv_id',
'trade_in',
'long',
'lat',
'warranty',
'mode_of_payment',
];
$em = $this->getDoctrine()->getManager();
$res = $this->checkParamsAndKey($req, $em, $required_params);
if ($res->isError())
return $res->getReturnResponse();
// trade in type
$trade_in = $req->request->get('trade_in');
// address
$address = $req->request->get('delivery_address', 'Set by mobile application');
// instructions
$instructions = $req->request->get('delivery_instructions', '');
// longitude and latitude
$long = $req->request->get('long');
$lat = $req->request->get('lat');
// geofence
$is_covered = $geo->isCovered($long, $lat);
if (!$is_covered)
{
// TODO: put geofence error message in config file somewhere
$res->setError(true)
->setErrorMessage('Oops! Our service is limited to some areas in Metro Manila, Laguna, and Baguio only. We will update you as soon as we are able to cover your area');
return $res->getReturnResponse();
}
$hub = null;
$hub_id = $req->request->get('hub_id');
if (strlen($hub_id) > 0)
$hub = $em->getRepository(Hub::class)->find($hub_id);
$schedule_date = $req->request->get('date_schedule');
$slot_id = $req->request->get('slot_id');
$advance_order = $req->request->get('flag_advance_order');
$flag_advance_order = ($advance_order === 'true') ? true : false;
$jo = new JobOrder();
$jo->setSource(TransactionOrigin::MOBILE_APP)
->setStatus(JOStatus::PENDING)
->setDeliveryInstructions('')
->setTier1Notes('')
->setTier2Notes('')
->setDeliveryAddress($address)
->setTradeInType($trade_in)
->setDeliveryInstructions($instructions)
// TODO: error check for valid mode of payment
->setModeOfPayment($req->request->get('mode_of_payment'))
->setAdvanceOrder($flag_advance_order);
// customer
$cust = $this->session->getCustomer();
if ($cust == null)
{
$res->setError(true)
->setErrorMessage('No customer information found');
return $res->getReturnResponse();
}
$jo->setCustomer($cust);
// validate service type
$stype = $req->request->get('service_type');
if (!ServiceType::validate($stype))
{
$res->setError(true)
->setErrorMessage('Invalid service type');
return $res->getReturnResponse();
}
$jo->setServiceType($stype);
// validate warranty
$warr = $req->request->get('warranty');
if (!WarrantyClass::validate($warr))
{
$res->setError(true)
->setErrorMessage('Invalid warranty class');
return $res->getReturnResponse();
}
$jo->setWarrantyClass($warr);
// set coordinates
$point = new Point($long, $lat);
$jo->setCoordinates($point);
// make invoice criteria
$icrit = new InvoiceCriteria();
$icrit->setServiceType($stype);
// check promo
$promo_id = $req->request->get('promo_id');
if (!empty($promo_id))
{
$promo = $em->getRepository(Promo::class)->find($promo_id);
if ($promo == null)
{
$res->setError(true)
->setErrorMessage('Invalid promo id');
return $res->getReturnResponse();
}
// put in criteria
$icrit->addPromo($promo);
}
// check customer vehicle
$cv = $em->getRepository(CustomerVehicle::class)->find($req->request->get('cv_id'));
if ($cv == null)
{
$res->setError(true)
->setErrorMessage('Invalid customer vehicle id');
return $res->getReturnResponse();
}
$icrit->setCustomerVehicle($cv);
$jo->setCustomerVehicle($cv);
// check if customer owns vehicle
if ($cust->getID() != $cv->getCustomer()->getID())
{
$res->setError(true)
->setErrorMessage('Customer does not own vehicle');
return $res->getReturnResponse();
}
// check battery
$batt_id = $req->request->get('batt_id');
if ($batt_id != null)
{
$batt = $em->getRepository(Battery::class)->find($batt_id);
if ($batt == null)
{
$res->setError(true)
->setErrorMessage('Invalid battery id');
return $res->getReturnResponse();
}
}
else
$batt = null;
/*
// put battery in criteria
$icrit->addBattery($batt);
*/
// check trade-in
// only allow motolite, other, none
switch ($trade_in)
{
case TradeInType::MOTOLITE:
case TradeInType::OTHER:
break;
default:
$trade_in = '';
break;
}
$icrit->addEntry($batt, $trade_in, 1);
// send to invoice generator
$invoice = $ic->generateInvoice($icrit);
$jo->setInvoice($invoice);
// assign hub and rider
// check if hub is null
if ($hub == null)
{
// find nearest hub
if (($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) ||
($jo->getServicetype() == ServiceType::BATTERY_REPLACEMENT_WARRANTY))
{
// get nearest hub
// $nearest_hub = $this->findNearestHubWithInventory($jo, $batt, $em, $map_tools, $im);
$nearest_hub = $this->findNearestHub($jo, $em, $map_tools);
}
else
{
$nearest_hub = $this->findNearestHub($jo, $em, $map_tools);
}
if (!empty($nearest_hub))
{
//error_log('found nearest hub ' . $nearest_hub->getID());
// assign rider
$available_riders = $nearest_hub->getAvailableRiders();
if (count($available_riders) > 0)
{
$assigned_rider = null;
if (count($available_riders) > 1)
{
// TODO: the setting of riders into an array
// will no longer be necessary when the contents
// of randomizeRider changes
$riders = [];
foreach ($available_riders as $rider)
{
$riders[] = $rider;
}
$assigned_rider = $this->randomizeRider($riders);
}
else
$assigned_rider = $available_riders[0];
//error_log('found rider ' . $assigned_rider->getID());
$jo->setHub($nearest_hub);
$jo->setRider($assigned_rider);
$jo->setStatus(JOStatus::ASSIGNED);
$assigned_rider->setAvailable(false);
}
}
}
else
{
$date_schedule = null;
if ((strlen($schedule_date) > 0) && (strlen($slot_id) > 0))
{
$time_schedule = $this->getTimeFromSlot($slot_id);
if (!empty($time_schedule))
{
$s_date = $schedule_date . ' ' . $time_schedule;
$date_schedule = DateTime::createFromFormat('Y-m-d H:i', $s_date);
//error_log($date_schedule->format('Y-m-d H:i'));
}
}
$jo->setHub($hub);
$jo->setStatus(JOStatus::RIDER_ASSIGN);
if ($date_schedule != null)
$jo->setDateSchedule($date_schedule);
}
$em->persist($jo);
$em->persist($invoice);
// add event log for JO
$event = new JOEvent();
$event->setDateHappen(new DateTime())
->setTypeID(JOEventType::CREATE)
->setJobOrder($jo);
$em->persist($event);
// check JO status
if ($jo->getStatus() == JOStatus::ASSIGNED)
{
// add event logs for hub and rider assignments
$hub_assign_event = new JOEvent();
$hub_assign_event->setDateHappen(new DateTime())
->setTypeID(JOEventType::HUB_ASSIGN)
->setJobOrder($jo);
$em->persist($hub_assign_event);
$rider_assign_event = new JOEvent();
$rider_assign_event->setDateHappen(new DateTime())
->setTypeID(JOEventType::RIDER_ASSIGN)
->setJobOrder($jo);
$em->persist($rider_assign_event);
// user mqtt event
$payload = [
'event' => 'outlet_assign'
];
$mclient->sendEvent($jo, $payload);
$rah->assignJobOrder($jo, $jo->getRider());
}
if ($jo->getStatus() == JOStatus::RIDER_ASSIGN)
{
// add event logs for hub assignments
$hub_assign_event = new JOEvent();
$hub_assign_event->setDateHappen(new DateTime())
->setTypeID(JOEventType::HUB_ASSIGN)
->setJobOrder($jo);
$em->persist($hub_assign_event);
// user mqtt event
$payload = [
'event' => 'outlet_assign'
];
$mclient->sendEvent($jo, $payload);
}
$em->flush();
// make invoice json data
$invoice_data = [
'total_price' => $invoice->getTotalPrice(),
'vat_ex_price' => $invoice->getVATExclusivePrice(),
'vat' => $invoice->getVAT(),
'discount' => $invoice->getDiscount(),
'trade_in' => $invoice->getTradeIn(),
];
$items = $invoice->getItems();
$items_data = [];
foreach ($items as $item)
{
$items_data[] = [
'title' => $item->getTitle(),
'qty' => $item->getQuantity() + 0,
'price' => $item->getPrice() + 0.0,
];
}
$invoice_data['items'] = $items_data;
// make job order data
$data = [
'jo_id' => $jo->getID(),
'invoice' => $invoice_data
];
// set data
$res->setData($data);
return $res->getReturnResponse();
}
protected function findCustomerByNumber($number)
{
$em = $this->getDoctrine()->getManager();
@ -2979,4 +3316,43 @@ class APIController extends Controller implements LoggedController
}
}
}
protected function getTimeFromSlot($slot_id)
{
$time_selected = '';
switch($slot_id) {
case '08_09':
$time_selected = AdvanceOrderSlot::_08_09;
break;
case '09_10':
$time_selected = AdvanceOrderSlot::_09_10;
break;
case '10_11':
$time_selected = AdvanceOrderSlot::_10_11;
break;
case '11_12':
$time_selected = AdvanceOrderSlot::_11_12;
break;
case '12_13':
$time_selected = AdvanceOrderSlot::_12_13;
break;
case '13_14':
$time_selected = AdvanceOrderSlot::_13_14;
break;
case '14_15':
$time_selected = AdvanceOrderSlot::_14_15;
break;
case '15_16':
$time_selected = AdvanceOrderSlot::_15_16;
break;
case '16_17':
$time_selected = AdvanceOrderSlot::_16_17;
break;
default:
error_log('Invalid slot id ' . $slot_id);
}
return $time_selected;
}
}

View file

@ -0,0 +1,29 @@
<?php
namespace App\Ramcar;
class AdvanceOrderSlot extends NameValue
{
// starting times
const _08_09 = '08:00';
const _09_10 = '09:00';
const _10_11 = '10:00';
const _11_12 = '11:00';
const _12_13 = '12:00';
const _13_14 = '13:00';
const _14_15 = '14:00';
const _15_16 = '15:00';
const _16_17 = '16:00';
const COLLECTION = [
'08:00' => '08:00',
'09:00' => '09:00',
'10:00' => '10:00',
'11:00' => '11:00',
'12:00' => '12:00',
'13:00' => '13:00',
'14:00' => '14:00',
'15:00' => '15:00',
'16:00' => '16:00',
];
}