resq/src/Controller/CustomerAppAPI/RiderController.php
2023-05-22 13:00:54 +08:00

241 lines
8.2 KiB
PHP

<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Ramcar\JOStatus;
use App\Ramcar\APIRiderStatus;
use App\Entity\RiderRating;
use App\Entity\JobOrder;
use App\Service\RiderTracker;
use Exception;
class RiderController extends ApiController
{
public function getRiderStatus(Request $req, RiderTracker $rt)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get customer
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(false, 'No customer information found.');
}
// check if we have an ongoing job order
/*
$ongoing_jos = $em->getRepository(JobOrder::class)->findBy([
'customer' => $cust,
'status' => [JOStatus::PENDING, JOStatus::RIDER_ASSIGN, JOStatus::IN_TRANSIT, JOStatus::ASSIGNED, JOStatus::IN_PROGRESS],
]);
*/
$ongoing_jos = $this->getOngoingJobOrders($cust);
// $res->setData(['here' => count($ongoing_jos)]);
// return $res->getReturnResponse();
if (count($ongoing_jos) <= 0) {
try {
// check if the latest fulfilled jo they have needs rider rating
$query = $this->em->createQuery('select jo from App\Entity\JobOrder jo where jo.customer = :cust and jo.status = :status order by jo.date_fulfill desc');
$fulfill_jo = $query->setParameters([
'cust' => $cust,
'status' => JOStatus::FULFILLED,
])
->setMaxResults(1)
->getSingleResult();
} catch (Exception $e) {
// response
return new ApiResponse(true, '', [
'status' => APIRiderStatus::NO_PENDING_JO,
]);
}
// we got a recently fulfilled job order
if ($fulfill_jo) {
// check if the rider has been rated
if (!$fulfill_jo->hasRiderRating()) {
$dest = $fulfill_jo->getCoordinates();
$data = [
'jo_id' => $fulfill_jo->getID(),
'service_type' => $fulfill_jo->getServiceType(),
'destination' => [
'long' => $dest->getLongitude(),
'lat' => $dest->getLatitude(),
],
'delivery_address' => $fulfill_jo->getDeliveryAddress(),
'delivery_instructions' => $fulfill_jo->getDeliveryInstructions(),
];
$rider = $fulfill_jo->getRider();
// default image url
$url_prefix = $req->getSchemeAndHttpHost();
$image_url = $url_prefix . '/assets/images/user.gif';
if ($rider->getImageFile() != null)
$image_url = $url_prefix . '/uploads/' . $rider->getImageFile();
$data['status'] = APIRiderStatus::RIDER_RATING;
// default rider location to hub
$data['rider'] = [
'id' => $rider->getID(),
'name' => $rider->getFullName(),
'plate_num' => $rider->getPlateNumber(),
'contact_num' => $rider->getContactNumber(),
'image_url' => $image_url,
];
// response
return new ApiResponse(true, '', $data);
}
}
// response, no pending
return new ApiResponse(true, '', [
'status' => APIRiderStatus::NO_PENDING_JO,
]);
}
// get first jo that's pending
$jo = $ongoing_jos[0];
$dest = $jo->getCoordinates();
$data = [
'jo_id' => $jo->getID(),
'service_type' => $jo->getServiceType(),
'destination' => [
'long' => $dest->getLongitude(),
'lat' => $dest->getLatitude(),
],
'delivery_address' => $jo->getDeliveryAddress(),
'delivery_instructions' => $jo->getDeliveryInstructions(),
];
switch ($jo->getStatus()) {
case JOStatus::PENDING:
$data['status'] = APIRiderStatus::OUTLET_ASSIGN;
break;
case JOStatus::RIDER_ASSIGN:
$data['status'] = APIRiderStatus::RIDER_ASSIGN;
break;
case JOStatus::ASSIGNED:
case JOStatus::IN_TRANSIT:
case JOStatus::IN_PROGRESS:
$rider = $jo->getRider();
// get rider coordinates from redis
$coord = $rt->getRiderLocation($rider->getID());
// default image url
$url_prefix = $req->getSchemeAndHttpHost();
$image_url = $url_prefix . '/assets/images/user.gif';
if ($rider->getImageFile() != null)
$image_url = $url_prefix . '/uploads/' . $rider->getImageFile();
$data['status'] = APIRiderStatus::RIDER_PICK_UP;
// TODO: fix this to actual location of rider
// default rider location to hub
$data['rider'] = [
'id' => $rider->getID(),
'name' => $rider->getFullName(),
'plate_num' => $rider->getPlateNumber(),
'contact_num' => $rider->getContactNumber(),
'image_url' => $image_url,
'location' => [
'long' => $coord->getLongitude(),
'lat' => $coord->getLatitude()
]
];
break;
}
// response
return new ApiResponse(true, '', $data);
}
public function addRiderRating(Request $req)
{
// validate params
$validity = $this->validateRequest($req, [
'jo_id',
'rating',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get customer
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(false, 'No customer information found.');
}
// get job order
$jo_id = $req->request->get('jo_id');
$jo = $this->em->getRepository(JobOrder::class)->find($jo_id);
if ($jo == null) {
return new ApiResponse(false, 'No job order found.');
}
// get rider
$rider = $jo->getRider();
if ($rider == null) {
return new ApiResponse(false, 'No rider found.');
}
// check that the customer owns the job order
$jo_cust = $jo->getCustomer();
if ($jo_cust->getID() != $cust->getID()) {
return new ApiResponse(false, 'Job order was not initiated by customer.');
}
// TODO: check job order status, if it's complete
// add rider rating
$rating_num = $req->request->get('rating', -1);
// if rating is -1
if ($rating_num == -1) {
$jo->setHasRiderRating();
$this->em->flush();
// response
return new ApiResponse();
}
$rating = new RiderRating();
$rating->setRider($rider)
->setCustomer($cust)
->setJobOrder($jo)
->setRating($rating_num);
// rider rating comment
$comment = $req->request->get('comment');
if (!empty($comment))
$rating->setComment($comment);
// mark jo as rider rated already
$jo->setHasRiderRating();
$this->em->persist($rating);
$this->em->flush();
// TODO: preliminary rating computation on the entity for now
$rider->updateRatingAverage();
$this->em->persist($rider);
$this->em->flush();
// response
return new ApiResponse();
}
}