Resolve "Resq 1.5 changes" #1556

Merged
korina.cordero merged 30 commits from 632-resq-1-5-changes into master-fix 2021-12-03 05:54:22 +00:00
7 changed files with 634 additions and 17 deletions

View file

@ -185,3 +185,38 @@ api_jo_info:
path: /api/job_order/{id}/info
controller: App\Controller\APIController::getJobOrderInfo
methods: [GET]
api_ongoing_job_orders:
path: /api/job_orders/ongoing
controller: App\Controller\APIController::getAllOngoingJobOrders
methods: [GET]
api_ongoing_jo_count:
path: /api/job_orders/ongoing/count
controller: App\Controller\APIController::getOngoingJobOrderCount
methods: [GET]
api_new_location:
path: /api/new_location
controller: App\Controller\APIController::addLocation
methods: [POST]
api_locations:
path: /api/locations
controller: App\Controller\APIController::getLocations
methods: [GET]
api_cust_vehicle_remove:
path: /api/vehicles/{id}/remove
controller: App\Controller\APIController::removeVehicle
methods: [POST]
api_latest_job_order:
path: /api/job_order/latest
controller: App\Controller\APIController::getLatestJobOrder
methods: [GET]
#api_completed_job_orders:
# path: /api/job_orders/completed
# controller: App\Controller\APIController::getCompletedJobOrders
# methods: [GET]

View file

@ -66,6 +66,7 @@ use App\Entity\PrivacyPolicy;
use App\Entity\Hub;
use App\Entity\SAPBattery;
use App\Entity\WarrantySerial;
use App\Entity\CustomerMetadata;
use DateTime;
use DateInterval;
@ -741,7 +742,9 @@ class APIController extends Controller implements LoggedController
// vehicles
$cv_list = [];
$cvs = $cust->getVehicles();
// $cvs = $cust->getVehicles();
// only get the customer's vehicles whose flag_active is true
$cvs = $em->getRepository(CustomerVehicle::class)->findBy(['flag_active' => true, 'customer' => $cust]);
foreach ($cvs as $cv)
{
$battery_id = null;
@ -1542,7 +1545,7 @@ class APIController extends Controller implements LoggedController
$ongoing_jos = $em->getRepository(JobOrder::class)->findBy([
'customer' => $cust,
'status' => [JOStatus::PENDING, JOStatus::RIDER_ASSIGN, JOStatus::IN_TRANSIT, JOStatus::ASSIGNED, JOStatus::IN_PROGRESS],
]);
], ['date_schedule' => 'desc']);
return $ongoing_jos;
}
@ -1912,18 +1915,18 @@ class APIController extends Controller implements LoggedController
{
$status = $jo->getStatus();
$dest = $jo->getCoordinates();
$dest = $jo->getCoordinates();
$jo_data = [
'id' => $jo->getID(),
$jo_data = [
'id' => $jo->getID(),
'date_create' => $jo->getDateCreate()->format('M d, Y'),
'service_type' => $jo->getServiceType(),
'destination' => [
'long' => $dest->getLongitude(),
'lat' => $dest->getLatitude(),
],
'delivery_address' => $jo->getDeliveryAddress(),
'delivery_instructions' => $jo->getDeliveryInstructions(),
'service_type' => $jo->getServiceType(),
'destination' => [
'long' => $dest->getLongitude(),
'lat' => $dest->getLatitude(),
],
'delivery_address' => $jo->getDeliveryAddress(),
'delivery_instructions' => $jo->getDeliveryInstructions(),
'jo_status' => $status,
'status' => $this->generateAPIRiderStatus($status),
];
@ -1940,6 +1943,14 @@ class APIController extends Controller implements LoggedController
'warranty' => $warranty,
];
// customer information
$customer = $jo->getCustomer();
$jo_data['customer'] = [
'first_name' => $customer->getFirstName(),
'last_name' => $customer->getLastName(),
'mobile_number' => $customer->getPhoneMobile(),
];
// rider
$rider = $jo->getRider();
if ($rider != null)
@ -2023,7 +2034,12 @@ class APIController extends Controller implements LoggedController
// get job orders
$all_jo_data = [];
$jos = $cust->getJobOrders();
// $jos = $cust->getJobOrders();
// get the fulfilled and cancelled job orders, since ongoing jos are not yet part of history
$jos = $em->getRepository(JobOrder::class)->findBy([
'customer' => $cust,
'status' => [JOStatus::CANCELLED, JOStatus::FULFILLED]
], ['date_schedule' => 'DESC']);
foreach ($jos as $jo)
{
// NOTE: use generateJobOrderData method, maybe?
@ -2050,11 +2066,34 @@ class APIController extends Controller implements LoggedController
// rider
$rider = $jo->getRider();
// check if jo has rider rating set to true
$has_rider_rating = $jo->hasRiderRating();
$rating = 0;
$comment = '';
if ($rider != null)
{
$jo_data['rider'] = $rider->getFullName();
// find the rider rating if any
if ($has_rider_rating)
{
$jo_rating = $jo->getRating();
if ($jo_rating != null)
{
$rating = $jo_rating->getRating();
// get comment
$comment = $jo_rating->getComment();
}
}
}
// rider rating for jo
$jo_data['has_rider_rating'] = $has_rider_rating;
$jo_data['rider_rating'] = $rating;
$jo_data['comment'] = $comment;
// invoice items
$items = [];
$jo_items = $jo->getInvoice()->getItems();
@ -2070,7 +2109,6 @@ class APIController extends Controller implements LoggedController
$jo_data['items'] = $items;
// dates depending on status
switch ($status)
{
@ -2265,6 +2303,13 @@ class APIController extends Controller implements LoggedController
];
$res->setData($data);
// check if is_covered is false. If so, we need to set the error part in the response
if (!$is_covered)
{
$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();
}
@ -2507,6 +2552,23 @@ class APIController extends Controller implements LoggedController
$partners = [];
foreach($result as $row)
{
// get all the reviews for each partner and average the ratings
$partner_id = $row[0]->getID();
$partner = $em->getRepository(Partner::class)->find($partner_id);
$partner_reviews = $em->getRepository(Review::class)->findBy(['partner' => $partner]);
$average_rating = 0;
if (count($partner_reviews) > 0)
{
$rating = 0;
foreach ($partner_reviews as $review)
{
$rating = $rating + $review->getRating();
}
$average_rating = $rating / sizeof($partner_reviews);
}
$partners[] = [
'id' => $row[0]->getID(),
'name' => $row[0]->getName(),
@ -2518,6 +2580,7 @@ class APIController extends Controller implements LoggedController
'longitude' => $row[0]->getCoordinates()->getLongitude(),
'latitude' => $row[0]->getCoordinates()->getLatitude(),
'db_distance' => $row['dist'],
'rating' => $average_rating,
];
}
@ -2670,6 +2733,9 @@ class APIController extends Controller implements LoggedController
// instructions
$instructions = $req->request->get('delivery_instructions', '');
// landmark
$landmark = $req->request->get('landmark', ' ');
// longitude and latitude
$long = $req->request->get('long');
$lat = $req->request->get('lat');
@ -2708,6 +2774,14 @@ class APIController extends Controller implements LoggedController
$hub = null;
$hub_id = $req->request->get('hub_id');
// check if hub_id is -1 which means user clicked Book Now before 5 PM
// but confirmed the order after 5 PM
if ($hub_id == -1)
{
$res->setError(true)
->setErrorMessage('Book Now no longer available.');
return $res->getReturnResponse();
}
if (strlen($hub_id) > 0)
$hub = $em->getRepository(Hub::class)->find($hub_id);
@ -2747,7 +2821,8 @@ class APIController extends Controller implements LoggedController
// TODO: error check for valid mode of payment
->setModeOfPayment($req->request->get('mode_of_payment'))
->setAdvanceOrder($flag_advance_order)
->setStatusAutoAssign(AutoAssignStatus::NOT_ASSIGNED);
->setStatusAutoAssign(AutoAssignStatus::NOT_ASSIGNED)
->setLandmark($landmark);
// customer
// $cust = $this->session->getCustomer();
@ -3157,6 +3232,9 @@ class APIController extends Controller implements LoggedController
$api_version = $this->getParameter('api_version');
$app_version = $req->query->get('version');
// putting this in for the future, in case we have diverging versions
$os = $req->query->get('os');
$platform = $req->query->get('platform');
$api_v = explode('.', $api_version);
$app_v = explode('.', $app_version);
@ -3526,6 +3604,290 @@ class APIController extends Controller implements LoggedController
return $res->getReturnResponse();
}
public function getAllOngoingJobOrders(EntityManagerInterface $em, Request $req, RiderTracker $rt)
{
$required_params = [];
$res = $this->checkParamsAndKey($req, $em, $required_params);
if ($res->isError())
return $res->getReturnResponse();
// get customer
$cust = $this->session->getCustomer();
if ($cust == null)
{
$res->setError(true)
->setErrorMessage('No customer information found');
return $res->getReturnResponse();
}
$ongoing_jos = $this->getOngoingJobOrders($cust);
// initialize data
$jo_data = [];
foreach ($ongoing_jos as $jo)
{
$jo_data[] = $this->generateJobOrderData($req, $jo, $rt);
}
$data = [
'ongoing_job_orders' => $jo_data,
];
$res->setData($data);
return $res->getReturnResponse();
}
public function getOngoingJobOrderCount(EntityManagerInterface $em, Request $req)
{
$required_params = [];
$res = $this->checkParamsAndKey($req, $em, $required_params);
if ($res->isError())
return $res->getReturnResponse();
// get customer
$cust = $this->session->getCustomer();
if ($cust == null)
{
$res->setError(true)
->setErrorMessage('No customer information found');
return $res->getReturnResponse();
}
$ongoing_jos = $this->getOngoingJobOrders($cust);
$data = [
'ongoing_job_order_count' => count($ongoing_jos),
];
$res->setData($data);
return $res->getReturnResponse();
}
public function addLocation(EntityManagerInterface $em, Request $req)
{
$required_params = [
'name',
'address',
'longitude',
'latitude',
'landmark',
];
$res = $this->checkParamsAndKey($req, $em, $required_params);
if ($res->isError())
return $res->getReturnResponse();
// get customer
$cust = $this->session->getCustomer();
if ($cust == null)
{
$res->setError(true)
->setErrorMessage('No customer information found');
return $res->getReturnResponse();
}
// get the information
$name = $req->request->get('name');
$address = $req->request->get('address');
$lng = $req->request->get('longitude');
$lat = $req->request->get('latitude');
$landmark = $req->request->get('landmark');
$loc_info = [
'address' => $address,
'longitude' => $lng,
'latitude' => $lat,
'landmark' => $landmark,
];
// check if customer already has existing metadata
$c_meta = $em->getRepository(CustomerMetadata::class)->findOneBy(['customer' => $cust]);
if ($c_meta == null)
{
// create new customer meta
$cust_meta = new CustomerMetadata();
$cust_meta->setCustomer($cust);
$cust_meta->addMetaInfo($name, $loc_info);
$em->persist($cust_meta);
}
else
{
// limit locations to 6. If more than 6, pop the first one out
// add location to existing customer meta
$meta_count = count($c_meta->getAllMetaInfo());
if ($meta_count >= 6)
$c_meta->popMetaInfo();
$c_meta->addMetaInfo($name, $loc_info);
}
$em->flush();
return $res->getReturnResponse();
}
public function getLocations(EntityManagerInterface $em, Request $req)
{
$required_params = [];
$res = $this->checkParamsAndKey($req, $em, $required_params);
if ($res->isError())
return $res->getReturnResponse();
// get customer
$cust = $this->session->getCustomer();
if ($cust == null)
{
$res->setError(true)
->setErrorMessage('No customer information found');
return $res->getReturnResponse();
}
// get the customer meta for customer
$locations = [];
$cust_meta = $em->getRepository(CustomerMetadata::class)->findOneBy(['customer' => $cust]);
if ($cust_meta != null)
{
$locations[] = $cust_meta->getAllMetaInfo();
}
$data = [
'locations' => $locations,
];
$res->setData($data);
return $res->getReturnResponse();
}
public function removeVehicle($id, EntityManagerInterface $em, Request $req)
{
$required_params = [];
$res = $this->checkParamsAndKey($req, $em, $required_params);
if ($res->isError())
return $res->getReturnResponse();
// get customer
$cust = $this->session->getCustomer();
if ($cust == null)
{
$res->setError(true)
->setErrorMessage('No customer information found');
return $res->getReturnResponse();
}
// find customer vehicle
$cv = $em->getRepository(CustomerVehicle::class)->find($id);
if ($cv == null)
{
$res->setError(true)
->setErrorMessage('Invalid customer vehicle id');
return $res->getReturnResponse();
}
// confirm that customer vehicle belongs to customer
if ($cv->getCustomer()->getID() != $cust->getID())
{
$res->setError(true)
->setErrorMessage('Vehicle does not belong to customer');
return $res->getReturnResponse();
}
// we cannot remove a vehicle from customer if customer vehicle has already has JOs for it.
// instead we set the customer vehicle's flag_active to false
$cv->setActive(false);
$em->flush();
// response
return $res->getReturnResponse();
}
public function getLatestJobOrder(EntityManagerInterface $em, Request $req, RiderTracker $rt)
{
// check required parameters and api key
$res = $this->checkParamsAndKey($req, $em, []);
if ($res->isError())
return $res->getReturnResponse();
// get customer
$cust = $this->session->getCustomer();
if ($cust == null)
{
$res->setError(true)
->setErrorMessage('No customer information found');
return $res->getReturnResponse();
}
// get the latest job order for customer
$latest_jo = $em->getRepository(JobOrder::class)->findOneBy(['customer' => $cust], ['id' => 'DESC']);
$jo_data = null;
if ($latest_jo != null)
{
// TODO: clean the response up to just return what is needed
$jo_data = $this->generateLatestJobOrderData($req, $latest_jo, $rt);
}
$data = [
'latest_job_order' => $jo_data,
];
$res->setData($data);
// response
return $res->getReturnResponse();
}
// commenting it out. Modify the getJOHistory instead to just get the fulfilled
// and cancelled job orders, since ongoing is not yet part of history
/*
public function getCompletedJobOrders(Request $req, EntityManagerInterface $em, RiderTracker $rt)
{
$required_params = [];
$res = $this->checkParamsAndKey($req, $em, $required_params);
if ($res->isError())
return $res->getReturnResponse();
// get customer
$cust = $this->session->getCustomer();
if ($cust == null)
{
$res->setError(true)
->setErrorMessage('No customer information found');
return $res->getReturnResponse();
}
$completed_jos = $this->getCompletedJOs($cust, $em);
// initialize data
$jo_data = [];
foreach ($completed_jos as $jo)
{
$jo_data[] = $this->generateJobOrderData($req, $jo, $rt);
}
$data = [
'completed_job_orders' => $jo_data,
];
$res->setData($data);
return $res->getReturnResponse();
}
protected function getCompletedJOs($cust, EntityManagerInterface $em)
{
$completed_jos = $em->getRepository(JobOrder::class)->findBy([
'customer' => $cust,
'status' => [JOStatus::CANCELLED, JOStatus::FULFILLED],
], ['date_schedule' => 'desc']);
return $completed_jos;
}
*/
protected function updateWarranty($res, $em, $rt, $trans, $req, $serial, $inv_filename = null, $wcard_filename = null,
$logger, $log_data, $user_id, $action, $source)
{
@ -4124,4 +4486,110 @@ class APIController extends Controller implements LoggedController
return $time_selected;
}
protected function generateLatestJobOrderData($req, $jo, $rt)
{
$status = $jo->getStatus();
$dest = $jo->getCoordinates();
$jo_data = [
'id' => $jo->getID(),
'date_create' => $jo->getDateCreate()->format('M d, Y'),
'service_type' => $jo->getServiceType(),
'destination' => [
'long' => $dest->getLongitude(),
'lat' => $dest->getLatitude(),
],
'delivery_address' => $jo->getDeliveryAddress(),
'delivery_instructions' => $jo->getDeliveryInstructions(),
'jo_status' => $status,
'status' => $this->generateAPIRiderStatus($status),
'landmark' => $jo->getLandmark(),
];
// customer vehicle and warranty
$cv = $jo->getCustomerVehicle();
// get latest warranty using plate number
$warranty = $this->findWarranty($cv->getPlateNumber());
$jo_data['customer_vehicle'] = [
'id' => $cv->getID(),
'plate_number' => $cv->getPlateNumber(),
'warranty' => $warranty,
];
// customer information
$customer = $jo->getCustomer();
$jo_data['customer'] = [
'first_name' => $customer->getFirstName(),
'last_name' => $customer->getLastName(),
'mobile_number' => $customer->getPhoneMobile(),
];
// rider
$rider = $jo->getRider();
if ($rider != null)
{
// 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();
$coord = $rt->getRiderLocation($rider->getID());
$jo_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()
]
];
}
else
{
$jo_data['rider'] = null;
}
// invoice items
$items = [];
$jo_items = $jo->getInvoice()->getItems();
foreach ($jo_items as $item)
{
$items[] = [
'id' => $item->getID(),
'title' => $item->getTitle(),
'qty' => $item->getQuantity(),
'price' => $item->getPrice(),
];
}
$jo_data['items'] = $items;
// dates depending on status
switch ($status)
{
case JOStatus::FULFILLED:
if ($jo->getDateFulfill() == null)
$jo_data['date_fulfilled'] = '';
else
$jo_data['date_fulfilled'] = $jo->getDateFulfill()->format('M d, Y');
break;
case JOStatus::CANCELLED:
$date_cancel = $jo->getDateCancel();
if ($date_cancel == null)
$date_cancel = new DateTime();
$jo_data['date_cancelled'] = $date_cancel->format('M d, Y');
break;
}
return $jo_data;
}
}

View file

@ -222,6 +222,12 @@ class Customer
*/
protected $car_club_customer_hub;
// ratings made by customer
/**
* @ORM\OneToMany(targetEntity="RiderRating", mappedBy="customer")
*/
protected $ratings;
public function __construct()
{
$this->numbers = new ArrayCollection();
@ -259,6 +265,8 @@ class Customer
$this->date_create = new DateTime();
$this->create_source = 'unknown';
$this->ratings = new ArrayCollection();
}
public function getID()

View file

@ -0,0 +1,87 @@
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity
* @ORM\Table(name="customer_metadata")
* @UniqueEntity("customer")
*/
class CustomerMetadata
{
// unique id
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
// customer
/**
* @ORM\OneToOne(targetEntity="Customer")
* @ORM\JoinColumn(name="customer_id", referencedColumnName="id")
*/
protected $customer;
// other information, like locations
/**
* @ORM\Column(type="json")
*/
protected $meta_info;
public function __construct()
{
$this->meta_info = [];
}
public function getID()
{
return $this->id;
}
public function setCustomer(Customer $customer)
{
$this->customer = $customer;
return $this;
}
public function getCustomer()
{
return $this->customer;
}
public function addMetaInfo($id, $value)
{
$this->meta_info[$id] = $value;
return $this;
}
public function getMetaInfo($id)
{
// return null if we don't have it
if (!isset($this->meta_info[$id]))
return null;
return $this->meta_info[$id];
}
public function getAllMetaInfo()
{
return $this->meta_info;
}
public function popMetaInfo()
{
if (count($this->meta_info) > 0)
{
array_shift($this->meta_info);
}
}
}

View file

@ -365,6 +365,12 @@ class JobOrder
*/
protected $delivery_status;
// rider rating
/**
* @ORM\OneToOne(targetEntity="RiderRating", mappedBy="job_order")
*/
protected $rating;
public function __construct()
{
$this->date_create = new DateTime();
@ -1050,4 +1056,8 @@ class JobOrder
return $this->delivery_status;
}
public function getRating()
{
return $this->rating;
}
}

View file

@ -136,6 +136,11 @@ class Rider
*/
protected $api_user;
/**
* @ORM\OneToMany(targetEntity="RiderRating", mappedBy="rider")
*/
protected $ratings;
public function __construct()
{
$this->job_orders = new ArrayCollection();
@ -150,6 +155,8 @@ class Rider
$this->active_job_order = null;
$this->current_job_order = null;
$this->api_user = null;
$this->ratings = new ArrayCollection();
}
public function getID()

View file

@ -1045,10 +1045,10 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
}
}
$obj->fulfill();
if (empty($error_array))
{
$obj->fulfill();
// the event
$event = new JOEvent();
$event->setDateHappen(new DateTime())
@ -1134,6 +1134,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
if (!empty($phone_number))
$this->sendSMSToCustomer($phone_number);
}
return $error_array;
}
// cancel job order