From 642803217dd29a5685fcd273f7809ea3de59f003 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 23 Jun 2021 07:07:41 +0000 Subject: [PATCH 01/42] Add new route file for resqapi. #591 --- config/routes/resqapi.yaml | 193 +++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 config/routes/resqapi.yaml diff --git a/config/routes/resqapi.yaml b/config/routes/resqapi.yaml new file mode 100644 index 00000000..bc92a595 --- /dev/null +++ b/config/routes/resqapi.yaml @@ -0,0 +1,193 @@ +# resqapi aka mobile api + +# customer/registration-related endpoints +resqapi_register: + path: /resqapi/register + controller: App\Controller\ResqAPI\CustomerController::register + methods: [POST] + +resqapi_confirm: + path: /resqapi/number_confirm + controller: App\Controller\ResqAPI\CustomerController::confirmNumber + methods: [POST] + +resqapi_validate: + path: /resqapi/code_validate + controller: App\Controller\ResqAPI\CustomerController::validateCode + methods: [POST] + +resqapi_info_get: + path: /resqapi/info + controller: App\Controller\ResqAPI\CustomerController::getInfo + methods: [GET] + +resqapi_info_update: + path: /resqapi/info + controller: App\Controller\ResqAPI\CustomerController::updateInfo + methods: [POST] + +resqapi_status: + path: /resqapi/status + controller: App\Controller\ResqAPI\CustomerController::getStatus + methods: [GET] + +resqapi_resend_code: + path: /resqapi/resend_code + controller: App\Controller\ResqAPI\CustomerController:resendCode + methods: [POST] + +resqapi_version_check: + path: /resqapi/version_check + controller: App\Controller\ResqAPI\CustomerController::versionCheck + methods: [GET] + +resqapi_device_id: + path: /resqapi/device_id + controller: App\Controller\ResqAPI\CustomerController:updateDeviceID + methods: [POST] + +resqapi_privacy: + path: /resqapi/privacy + controller: App\Controller\ResqAPI\CustomerController:privacySettings + methods: [POST] + +# vehicle manufacturer and vehicle endpoints +resqapi_vehicle_mfg_list: + path: /resqapi/vehicle/mfgs + controller: App\Controller\ResqAPI\VehicleController::listVehicleManufacturers + methods: [GET] + +resqapi_vehicle_make_list: + path: /resqapi/vehicle/mfgs/{mfg_id}/makes + controller: App\Controller\ResqAPI\VehicleController::listVehicleMakes + methods: [GET] + +# customer vehicle endpoints +resqapi_cust_vehicle_add: + path: /resqapi/vehicles + controller: App\Controller\ResqAPI\CustomerVehicleController::addVehicle + methods: [POST] + +resqapi_cust_vehicle_update: + path: /resqapi/vehicles/{id} + controller: App\Controller\ResqAPI\CustomerVehicleController::updateVehicle + methods: [POST] + +resqapi_cust_vehicle_list: + path: /resqapi/vehicles + controller: App\Controller\ResqAPI\CustomerVehicleController::listVehicles + methods: [GET] + +# promo endpoints +resqapi_promo_list: + path: /resqapi/promos + controller: App\Controller\ResqAPI\PromoController::listPromos + methods: [GET] + +# battery endpoints +resqapi_battery_list: + path: /resqapi/vehicles/{vid}/compatible_batteries + controller: App\Controller\ResqAPI\BatteryController::getCompatibleBatteries + methods: [GET] + +# service endpoints +resqapi_service_list: + path: /resqapi/services + controller: App\Controller\ResqAPI\ServiceController:listServices + methods: [GET] + +# partner endpoints +resqapi_partner_info: + path: /resqapi/partners/{pid} + controller: App\Controller\ResqAPI\PartnerController:getPartnerInformation + methods: [GET] + +resqapi_partner: + path: /resqapi/partners + controller: App\Controller\ResqAPI\PartnerController:getClosestPartners + methods: [GET] + +resqapi_partner_review: + path: /resqapi/partners/{pid}/review + controller: App\Controller\ResqAPI\PartnerController:reviewPartner + methods: [POST] + +# rider endpoints +resq_rider_status: + path: /resqapi/rider + controller: App\Controller\ResqAPI\RiderController::getRiderStatus + methods: [GET] + +resqapi_rider_rating_add: + path: /resqapi/rider_rating + controller: App\Controller\ResqAPI\RiderController::addRiderRating + methods: [POST] + +# job order endpoints +resqapi_jo_request: + path: /resqapi/job_order + controller: App\Controller\ResqAPI\JobOrderController::requestJobOrder + methods: [POST] + +resqapi_estimate: + path: /resqapi/estimate + controller: App\Controller\ResqAPI\JobOrderController::getEstimate + methods: [POST] + +resqapi_ongoing: + path: /resqapi/job_order/ongoing + controller: App\Controller\ResqAPI\JobOrderController::getOngoing + methods: [GET] + +resqapi_jo_cancel: + path: /resqapi/job_order/cancel + controller: App\Controller\ResqAPI\JobOrderController:cancelJobOrder + methods: [POST] + +resqapi_jo_history: + path: /resqapi/job_order/history + controller: App\Controller\ResqAPI\JobOrderController:getJOHistory + methods: [GET] + +resqapi_jo_invoice: + path: /resqapi/job_order/invoice + controller: App\Controller\ResqAPI\JobOrderController:getJOInvoice + methods: [GET] + +resqapi_location_support: + path: /resqapi/location_support + controller: App\Controller\ResqAPI\JobOrderController:locationSupport + methods: [GET] + +resqapi_nearest_hub_slots: + path: /resqapi/hub_slots + controller: App\Controller\ResqAPI\JobOrderController::getNearestHubAndSlots + methods: [GET] + +resqapi_new_jo_request: + path: /resqapi/new_job_order + controller: App\Controller\ResqAPI\JobOrderController::newRequestJobOrder + methods: [POST] + +resqapi_schedule_option_status: + path: /resqapi/schedule_option_status + controller: App\Controller\ResqAPI\JobOrderController::scheduleOptionStatus + methods: [GET] + +# warranty endpoints +resqapi_activate_warranty: + path: /resqapi/activate_warranty + controller: App\Controller\ResqAPI\WarrantyController:activateWarranty + methods: [POST] + +# paperless warranty / qr code +resqapi_warr_serial_check: + path: /resqapi/warranty/{serial} + controller: App\Controller\ResqAPI\WarrantyController::warrantyCheck + methods: [GET] + +resqapi_warr_serial_register: + path: /resqapi/warranty/{serial} + controller: App\Controller\ResqAPI\WarrantyController::warrantyRegister + methods: [POST] + -- 2.43.5 From 2125f36e77033db9ad56ad4a15adf8279af9e67a Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 23 Jun 2021 08:24:49 +0000 Subject: [PATCH 02/42] Add MobileUser entity. Add association between MobileUser and Customer. #591 --- src/Entity/Customer.php | 25 ++++ src/Entity/MobileUser.php | 268 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 293 insertions(+) create mode 100644 src/Entity/MobileUser.php diff --git a/src/Entity/Customer.php b/src/Entity/Customer.php index 2257bfb2..54f9e8ba 100644 --- a/src/Entity/Customer.php +++ b/src/Entity/Customer.php @@ -215,6 +215,12 @@ class Customer */ protected $customer_tags; + // mobile users linked to this customer + /** + * @ORM\OneToMany(targetEntity="MobileUser", mappedBy="customer") + */ + protected $mobile_users; + public function __construct() { $this->numbers = new ArrayCollection(); @@ -222,6 +228,7 @@ class Customer $this->vehicles = new ArrayCollection(); $this->job_orders = new ArrayCollection(); $this->customer_tags = new ArrayCollection(); + $this->mobile_users = new ArrayCollection(); $this->customer_classification = CustomerClassification::REGULAR; $this->customer_notes = ''; @@ -656,4 +663,22 @@ class Customer $this->customer_tags->removeElement($customer_tag); $customer_tag->removeCustomer($this); } + + public function addMobileUser(MobileUser $mobile_user) + { + $this->mobile_users->add($mobile_user); + return $this; + } + + public function clearMobileUsers() + { + $this->mobile_users->clear(); + return $this; + } + + public function getMobileUsers() + { + return $this->mobile_users; + } + } diff --git a/src/Entity/MobileUser.php b/src/Entity/MobileUser.php new file mode 100644 index 00000000..0830ae89 --- /dev/null +++ b/src/Entity/MobileUser.php @@ -0,0 +1,268 @@ +id = $this->generateKeyID(); + $this->date_generated = new DateTime(); + $this->customer = null; + $this->confirm_flag = false; + $this->date_confirmed = null; + $this->date_code_sent = null; + $this->reviews = new ArrayCollection(); + $this->capi_user_id = 0; + } + + public function generateKeyID() + { + // use uniqid for now, since primary key dupes will trigger exceptions + return uniqid(); + } + + public function getID() + { + return $this->id; + } + + public function setPhoneModel($model) + { + $this->phone_model = $model; + return $this; + } + + public function getPhoneModel() + { + return $this->phone_model; + } + + public function setOSType($type) + { + $this->os_type = $type; + return $this; + } + + public function getOSType() + { + return $this->os_type; + } + + public function getOSVersion() + { + return $this->os_version; + } + + public function setPhoneID($id) + { + $this->phone_id = $id; + return $this; + } + + public function getPhoneID() + { + return $this->phone_id; + } + + public function setDevicePushID($id) + { + $this->device_push_id = $id; + return $this; + } + + public function getDevicePushID() + { + return $this->device_push_id; + } + + public function setCustomer(Customer $cust = null) + { + $this->customer = $cust; + return $this; + } + + public function getCustomer() + { + return $this->customer; + } + + public function getDateGenerated() + { + return $this->date_generated; + } + + public function setPhoneNumber($num) + { + $this->phone_number = $num; + return $this; + } + + public function getPhoneNumber() + { + return $this->phone_number; + } + + public function setConfirmCode($code) + { + $this->confirm_code = $code; + return $this; + } + + public function getConfirmCode() + { + return $this->confirm_code; + } + + public function setConfirmed($flag = true) + { + $this->confirm_flag = $flag; + return $this; + } + + public function isConfirmed() + { + return $this->confirm_flag; + } + + public function setDateConfirmed(DateTime $date) + { + $this->date_confirmed = $date; + return $this; + } + + public function getDateConfirmed() + { + return $this->date_confirmed; + } + + public function setDateCodeSent(DateTime $date) + { + $this->date_code_sent = $date; + return $this; + } + + public function getDateCodeSent() + { + return $this->date_code_sent; + } + + public function getReviews() + { + return $this->reviews; + } + + public function setCapiUserId($capi_user_id) + { + $this->capi_user_id = $capi_user_id; + } + + public function getCapiUserId() + { + return $this->capi_user_id; + } + +} -- 2.43.5 From 69c221f78cc053849a954ebb2c8b3f87f7757877 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 23 Jun 2021 09:30:28 +0000 Subject: [PATCH 03/42] Add controller for customer-related requests for mobile API. #591 --- src/Controller/ResqAPI/CustomerController.php | 419 ++++++++++++++++++ 1 file changed, 419 insertions(+) create mode 100644 src/Controller/ResqAPI/CustomerController.php diff --git a/src/Controller/ResqAPI/CustomerController.php b/src/Controller/ResqAPI/CustomerController.php new file mode 100644 index 00000000..dc1c260a --- /dev/null +++ b/src/Controller/ResqAPI/CustomerController.php @@ -0,0 +1,419 @@ +acl_gen = $acl_gen; + } + + public function register(Request $req, EntityManagerInterface $em) + { + // no need for access for register + + $res = new APIResult(); + // confirm parameters + $required_params = [ + 'phone_model', + 'os_type', + 'os_version', + 'phone_id' + ]; + + // TODO: APIController has a function called checkRequiredParameters that does the same thing + // as checkMissingParameters. Maybe we can use that? + $missing = $this->checkMissingParameters($req, $required_params); + if (count($missing) > 0) + { + $params = implode(', ', $missing); + $res->setError(true) + ->setErrorMessage('Missing parameter(s): ' . $params); + return $res->getReturnResponse(); + } + + // retry until we get a unique id + while (true) + { + try + { + // create mobile user + $mobile_user = new MobileUser(); + $mobile_user->setPhoneModel($req->request->get('phone_model')) + ->setOSType($req->request->get('os_type')) + ->setOSVersion($req->request->get('os_version')) + ->setPhoneID($req->request->get('phone_id')); + + // reopen in case we get an exception + if (!$em->isOpen()) + { + $em = $em->create( + $em->getConnection(), + $em->getConfiguration() + ); + } + + // save + $em->persist($mobile_user); + $em->flush(); + } + catch (DBALException $e) + { + error_log($e->getMessage()); + // delay one second and try again + sleep(1); + continue; + } + + break; + } + + // return data + // need to make sure the names returned to app are the same + // so we still use session_id name + // TODO: depending on what data type we return, this might need changes + $data = [ + 'session_id' => $mobile_user->getID() + ]; + + // response + return $res->getReturnResponse(); + } + + public function confirmNumber(RisingTideGateway $rt, Request $req, EntityManagerInterface $em) + { + // check parameters + $required_params = [ + 'phone_number', + ]; + + // check required parameters and api key + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + // phone number + $phone_number = $req->request->get('phone_number'); + + // get otp_mode from .env + $dotenv = new Dotenv(); + $dotenv->loadEnv(__DIR__.'/../../.env'); + + $otp_mode = $_ENV['OTP_MODE']; + + // check for hardcoded phone number for app store testing + if ($phone_number == '639991112233') + { + $code = '123456'; + // TODO: mobile session no longer exists, use mobile_user + $this->session->setConfirmCode($code) + ->setPhoneNumber($phone_number); + $em->flush(); + + return $res->getReturnResponse(); + } + + // check if otp_mode is test + if ($otp_mode == 'test') + { + $code = '123456'; + // TODO: mobile session no longer exists, use mobile_user + $this->session->setConfirmCode($code) + ->setPhoneNumber($phone_number); + $em->flush(); + + return $res->getReturnResponse(); + } + + // TODO: spam protection + + // TODO: validate phone number + + // generate code and save + $code = $this->generateConfirmCode(); + // TODO: mobile session no longer exists, use mobile_user + $this->session->setConfirmCode($code) + ->setPhoneNumber($phone_number); + $em->flush(); + + if ($otp_mode != 'test') + { + // send sms to number + $this->sendConfirmationCode($rt, $phone_number, $code); + } + + // response + return $res->getReturnResponse(); + } + + // TODO: needs to be modified for mobile user + public function validateCode(Request $req, EntityManagerInterface $em) + { + // check parameters + $required_params = [ + 'code', + ]; + + // check required parameters and api key + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + // code is wrong + $code = $req->request->get('code'); + if ($this->session->getConfirmCode() != $code) + { + $res->setError(true) + ->setErrorMessage('Wrong confirm code'); + return $res->getReturnResponse(); + } + + // set confirm date + $date = new DateTime(); + $this->session->setDateConfirmed($date) + ->setConfirmed(); + + + // TODO: check if we have the number registered before and merge + $dupe_sess = $this->findNumberSession($this->session->getPhoneNumber()); + if ($dupe_sess != null) + { + $dupe_cust = $dupe_sess->getCustomer(); + $this->session->setCustomer($dupe_cust); + } + + // TODO: check if mobile matches mobile of customer + $customer = $this->findCustomerByNumber($this->session->getPhoneNumber()); + if ($customer != null) + { + // TODO: if there is a dupe_sess, do we need to check if + // dupe_cust is the same as the customer we found? + $this->session->setCustomer($customer); + } + + $em->flush(); + + // response + return $res->getReturnResponse(); + } + + // TODO: needs to be modified for mobile user + public function getInfo(Request $req, EntityManagerInterface $em) + { + // check required parameters and api key + $required_params = []; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + // if no customer found + $cust = $this->session->getCustomer(); + if ($cust == null) + { + $data = [ + 'first_name' => '', + 'last_name' => '', + 'priv_third_party' => (bool) false, + 'priv_promo' => (bool) false, + ]; + $res->setData($data); + + return $res->getReturnResponse(); + } + + // send back customer details + $data = [ + 'first_name' => $cust->getFirstName(), + 'last_name' => $cust->getLastName(), + 'priv_third_party' => (bool) $cust->getPrivacyThirdParty(), + 'priv_promo' => (bool) $cust->getPrivacyPromo(), + ]; + $res->setData($data); + + return $res->getReturnResponse(); + } + + // TODO: needs to be modified for mobile user + public function updateInfo(Request $req, EntityManagerInterface $em) + { + // check required parameters and api key + $required_params = [ + 'first_name', + 'last_name', + ]; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + $cust = $this->updateCustomerInfo($req, $em); + + // get privacy policy for mobile + $dotenv = new Dotenv(); + $dotenv->loadEnv(__DIR__.'/../../.env'); + + $policy_mobile_id = $_ENV['POLICY_MOBILE']; + + $mobile_policy = $em->getRepository(PrivacyPolicy::class)->find($policy_mobile_id); + + // set policy id + if ($mobile_policy != null) + { + $cust->setPrivacyPolicyMobile($mobile_policy); + } + + $em->flush(); + + return $res->getReturnResponse(); + } + + // TODO: needs to be modified for mobile user + public function getStatus(Request $req, EntityManagerInterface $em) + { + // check required parameters and api key + $required_params = []; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + // set data + $data = []; + if ($this->session->isConfirmed()) + $data['status'] = 'confirmed'; + else + $data['status'] = 'unconfirmed'; + $res->setData($data); + + return $res->getReturnResponse(); + } + + + + // TODO: this might not be needed if we use APIController's checkRequiredParameters + protected function checkMissingParameters(Request $req, $params = []) + { + $missing = []; + + // check if parameters are there + foreach ($params as $param) + { + if ($req->getMethod() == 'GET') + { + $check = $req->query->get($param); + if (empty($check)) + $missing[] = $param; + } + else if ($req->getMethod() == 'POST') + { + $check = $req->request->get($param); + if (empty($check)) + $missing[] = $param; + } + else + return $params; + } + + return $missing; + } + + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkParamsAndKey(Request $req, $em, $params) + { + // TODO: depends on what we decide to return + // returns APIResult object + $res = new APIResult(); + + // check for api_key in query string + $api_key = $req->query->get('api_key'); + if (empty($api_key)) + { + $res->setError(true) + ->setErrorMessage('Missing API key'); + return $res; + } + + // check missing parameters + $missing = $this->checkMissingParameters($req, $params); + if (count($missing) > 0) + { + $miss_string = implode(', ', $missing); + $res->setError(true) + ->setErrorMessage('Missing parameter(s): ' . $miss_string); + return $res; + } + + // check api key + $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); + if ($mobile_user == null) + { + $res->setError(true) + ->setErrorMessage('Invalid API Key'); + return $res; + } + + // store session + $this->session = $sess; + + return $res; + } + + // TODO: type hint entity manager + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkAPIKey($em, $api_key) + { + // find the api key (session id) + // TODO: user validation needs to be changed + $m_user = $em->getRepository(MobileUser::class)->find($api_key); + if ($m_user == null) + return null; + + return $m_user; + } + + // TODO: needs to be modified for mobile user + protected function updateCustomerInfo($req, $em) + { + // create new customer if it's not there + $cust = $this->session->getCustomer(); + if ($cust == null) + { + $cust = new Customer(); + $em->persist($cust); + + $this->session->setCustomer($cust); + } + + $cust->setFirstName($req->request->get('first_name')) + ->setLastName($req->request->get('last_name')) + ->setEmail($req->request->get('email', '')) + ->setConfirmed($this->session->isConfirmed()); + + // update mobile phone of customer + $cust->setPhoneMobile(substr($this->session->getPhoneNumber(), 2)); + + return $cust; + } + + +} -- 2.43.5 From ece60b177d2db7170c13ee3d136b082fcaa3674f Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 24 Jun 2021 07:47:56 +0000 Subject: [PATCH 04/42] Add controllers for vehicle and customer vehicle. #591 --- src/Controller/ResqAPI/CustomerController.php | 170 ++++++++++ .../ResqAPI/CustomerVehicleController.php | 319 ++++++++++++++++++ src/Controller/ResqAPI/VehicleController.php | 190 +++++++++++ 3 files changed, 679 insertions(+) create mode 100644 src/Controller/ResqAPI/CustomerVehicleController.php create mode 100644 src/Controller/ResqAPI/VehicleController.php diff --git a/src/Controller/ResqAPI/CustomerController.php b/src/Controller/ResqAPI/CustomerController.php index dc1c260a..378e0e57 100644 --- a/src/Controller/ResqAPI/CustomerController.php +++ b/src/Controller/ResqAPI/CustomerController.php @@ -17,6 +17,8 @@ use App\Ramcar\APIResult; use App\Entity\MobileUser; +use App\Service\RisingTideGateway; + use Catalyst\APIBundle\Access\Generator as ACLGenerator; class CustomerController extends APIController @@ -306,9 +308,177 @@ class CustomerController extends APIController return $res->getReturnResponse(); } + // TODO: needs to be modified for mobile user + public function resendCode(Request $req, RisingTideGateway $rt, EntityManagerInterface $em) + { + $required_params = []; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + // already confirmed + if ($this->session->isConfirmed()) + { + $res->setError(true) + ->setErrorMessage('User is already confirmed.'); + return $res->getReturnResponse(); + } + + // have sent code before + if ($this->session->getDateCodeSent() != null) + { + $res->setError(true) + ->setErrorMessage('Can only send confirm code every 5 mins.'); + return $res->getReturnResponse(); + } + + + // TODO: send via sms + $phone_number = $this->session->getPhoneNumber(); + $code = $this->session->getConfirmCode(); + $this->sendConfirmationCode($rt, $phone_number, $code); + + + return $res->getReturnResponse(); + } + + // TODO: modify the return or the result if we change what we return + public function versionCheck(Request $req) + { + $res = new APIResult(); + + $required_params = [ + 'version', + ]; + + $missing = $this->checkMissingParameters($req, $required_params); + if (count($missing) > 0) + { + $params = implode(', ', $missing); + $res->setError(true) + ->setErrorMessage('Missing parameter(s): ' . $params); + return $res->getReturnResponse(); + } + + $need_update = false; + $msg = 'Version is up to date.'; + + $api_version = $this->getParameter('api_version'); + + $app_version = $req->query->get('version'); + + $api_v = explode('.', $api_version); + $app_v = explode('.', $app_version); + + if ($api_v[0] < $app_v[0]) + { + $res->setError(true) + ->setErrorMessage('Invalid application version: ' . $app_version); + return $res->getReturnResponse(); + } + + if ($api_v[0] > $app_v[0]) + { + $need_update = true; + $msg = 'Your version is outdated and needs an update to use the latest features RES-Q has to offer.'; + } + + + $data = [ + 'need_update' => $need_update, + 'message' => $msg, + ]; + + $res->setData($data); + + return $res->getReturnResponse(); + } + + // TODO: needs to be modified for mobile user + public function updateDeviceID(Request $req, EntityManagerInterface $em) + { + $required_params = [ + 'device_id', + ]; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + $device_id = $req->request->get('device_id'); + $this->session->setDevicePushID($device_id); + + $em->flush(); + + // response + return $res->getReturnResponse(); + } + + // TODO: needs to be modified for mobile user + public function privacySettings(Request $req, EntityManagerInterface $em) + { + $required_params = [ + 'priv_third_party', + // 'priv_promo', + ]; + $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(); + } + + // set privacy settings + $priv_promo = $req->request->get('priv_promo', false); + $priv_third_party = $req->request->get('priv_third_party'); + $cust->setPrivacyThirdParty($priv_third_party) + ->setPrivacyPromo($priv_promo); + + // get the policy ids from .env + $dotenv = new Dotenv(); + $dotenv->loadEnv(__DIR__.'/../../.env'); + + $policy_promo_id = $_ENV['POLICY_PROMO']; + $policy_third_party_id = $_ENV['POLICY_THIRD_PARTY']; + + // check if privacy settings are true + // if true, set the private policy for the customer + if ($priv_promo) + { + // find the promo policy + $policy = $em->getRepository(PrivacyPolicy::class)->find($policy_promo_id); + + // set policy id + if ($policy != null) + { + $cust->setPrivacyPolicyPromo($policy); + } + } + + if ($priv_third_party) + { + // find the third party policy + $policy = $em->getRepository(PrivacyPolicy::class)->find($policy_third_party_id); + + // set policy id + if ($policy != null) + { + $cust->setPrivacyPolicyThirdParty($policy); + } + } + + $em->flush(); + + return $res->getReturnResponse(); + } // TODO: this might not be needed if we use APIController's checkRequiredParameters + // or we put this into a service? protected function checkMissingParameters(Request $req, $params = []) { $missing = []; diff --git a/src/Controller/ResqAPI/CustomerVehicleController.php b/src/Controller/ResqAPI/CustomerVehicleController.php new file mode 100644 index 00000000..5ce7ab6b --- /dev/null +++ b/src/Controller/ResqAPI/CustomerVehicleController.php @@ -0,0 +1,319 @@ +acl_gen = $acl_gen; + } + + public function addVehicle(Request $req, EntityManagerInterface $em) + { + // check requirements + $res = $this->checkVehicleRequirements($req, $em); + if ($res->isError()) + return $res->getReturnResponse(); + + // customer vehicle + $cv = new CustomerVehicle(); + + $res = $this->setCustomerVehicleObject($req, $res, $cv, $em); + + return $res->getReturnResponse(); + } + + // TODO: needs to be modified for mobile user + public function updateVehicle(Request $req, $id, EntityManagerInterface $em) + { + // check requirements + $res = $this->checkVehicleRequirements($req, $em); + if ($res->isError()) + return $res->getReturnResponse(); + + // get customer vehicle + $cv = $em->getRepository(CustomerVehicle::class)->find($id); + + // check if it exists + if ($cv == null) + { + $res->setError(true) + ->setErrorMessage('Vehicle does not exist'); + return $res->getReturnResponse(); + } + + // check if it's owned by customer + if ($cv->getCustomer()->getID() != $this->session->getCustomer()->getID()) + { + $res->setError(true) + ->setErrorMessage('Invalid vehicle'); + return $res->getReturnResponse(); + } + + $res = $this->setCustomerVehicleObject($req, $res, $cv, $em); + + return $res->getReturnResponse(); + } + + // TODO: needs to be modified for mobile user + public function listVehicles(Request $req, EntityManagerInterface $em) + { + // check required parameters and api key + $required_params = []; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + // customer + $cust = $this->session->getCustomer(); + if ($cust == null) + { + $res->setError(true) + ->setErrorMessage('No customer information found'); + return $res->getReturnResponse(); + } + + // vehicles + $cv_list = []; + $cvs = $cust->getVehicles(); + foreach ($cvs as $cv) + { + $battery_id = null; + if ($cv->getCurrentBattery() != null) + $battery_id = $cv->getCurrentBattery()->getID(); + + $wty_ex = null; + if ($cv->getWarrantyExpiration() != null) + $wty_ex = $cv->getWarrantyExpiration()->format('Y-m-d'); + + $warranty = $this->findWarranty($cv->getPlateNumber()); + + $cv_name = ''; + if ($cv->getName() != null) + $cv_name = $cv->getName(); + + $cv_list[] = [ + 'cv_id' => $cv->getID(), + 'mfg_id' => $cv->getVehicle()->getManufacturer()->getID(), + 'make_id' => $cv->getVehicle()->getID(), + 'name' => $cv_name, + 'plate_num' => $cv->getPlateNumber(), + 'model_year' => $cv->getModelYear(), + 'color' => $cv->getColor(), + 'condition' => $cv->getStatusCondition(), + 'fuel_type' => $cv->getFuelType(), + 'wty_code' => $cv->getWarrantyCode(), + 'wty_expire' => $wty_ex, + 'curr_batt_id' => $battery_id, + 'is_motolite' => $cv->hasMotoliteBattery() ? 1 : 0, + 'is_active' => $cv->isActive() ? 1 : 0, + 'warranty' => $warranty, + ]; + } + + // data + $data = [ + 'vehicles' => $cv_list + ]; + $res->setData($data); + + return $res->getReturnResponse(); + } + + protected function checkVehicleRequirements(Request $req, EntityManagerInterface $em) + { + // check required parameters and api key + $required_params = [ + 'make_id', + 'name', + 'plate_num', + 'model_year', + 'color', + 'condition', + 'fuel_type', + ]; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res; + + // TODO: check valid plate number + // TODO: check valid fuel type (gas / diesel) + // TODO: check current battery id + // TODO: check condition (brand new / second-hand) + // TODO: check is_motolite and is_active (1 or 0) + // TODO: check warranty expiration date (YYYYMMDD) + // TODO: check model year coverage if it fits in between + + return $res; + } + + + protected function setCustomerVehicleObject(Request $req, APIResult $res, + CustomerVehicle $cv, EntityManagerInterface $em) + { + // check customer + $cust = $this->session->getCustomer(); + if ($cust == null) + { + $res->setError(true) + ->setErrorMessage('No customer information found'); + return $res; + } + + // get vehicle + $vehicle = $em->getRepository(Vehicle::class)->find($req->request->get('make_id')); + if ($vehicle == null) + { + $res->setError(true) + ->setErrorMessage('Invalid vehicle make id'); + return $res; + } + + $cv->setCustomer($cust) + ->setVehicle($vehicle) + ->setName($req->request->get('name')) + ->setPlateNumber($req->request->get('plate_num')) + ->setModelYear($req->request->get('model_year')) + ->setColor($req->request->get('color')) + ->setFuelType($req->request->get('fuel_type')) + ->setStatusCondition($req->request->get('condition')); + + // set warranty code and expiration + // TODO: check warranty requirements + if (!empty($req->request->get('wty_code'))) + $cv->setWarrantyCode($req->request->get('wty_code')); + if (!empty($req->request->get('wty_expire'))) + $cv->setWarrantyExpiration(new DateTime($req->request->get('wty_expire'))); + + // TODO: get current battery + + // is motolite + if ($req->request->get('is_motolite') == 0) + $cv->setHasMotoliteBattery(false); + else + $cv->setHasMotoliteBattery(true); + + // is active + if ($req->request->get('is_active') == 0) + $cv->setActive(false); + else + $cv->setActive(true); + + // save + $em->persist($cv); + $em->flush(); + + // data + $data = [ + 'cv_id' => $cv->getID() + ]; + $res->setData($data); + + return $res; + } + + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkParamsAndKey(Request $req, $em, $params) + { + // TODO: depends on what we decide to return + // returns APIResult object + $res = new APIResult(); + + // check for api_key in query string + $api_key = $req->query->get('api_key'); + if (empty($api_key)) + { + $res->setError(true) + ->setErrorMessage('Missing API key'); + return $res; + } + + // check missing parameters + $missing = $this->checkMissingParameters($req, $params); + if (count($missing) > 0) + { + $miss_string = implode(', ', $missing); + $res->setError(true) + ->setErrorMessage('Missing parameter(s): ' . $miss_string); + return $res; + } + + // check api key + $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); + if ($mobile_user == null) + { + $res->setError(true) + ->setErrorMessage('Invalid API Key'); + return $res; + } + + // store session + $this->session = $sess; + + return $res; + } + + // TODO: this might not be needed if we use APIController's checkRequiredParameters + // or we put this into a service? + protected function checkMissingParameters(Request $req, $params = []) + { + $missing = []; + + // check if parameters are there + foreach ($params as $param) + { + if ($req->getMethod() == 'GET') + { + $check = $req->query->get($param); + if (empty($check)) + $missing[] = $param; + } + else if ($req->getMethod() == 'POST') + { + $check = $req->request->get($param); + if (empty($check)) + $missing[] = $param; + } + else + return $params; + } + + return $missing; + } + + // TODO: type hint entity manager + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkAPIKey($em, $api_key) + { + // find the api key (session id) + // TODO: user validation needs to be changed + $m_user = $em->getRepository(MobileUser::class)->find($api_key); + if ($m_user == null) + return null; + + return $m_user; + } +} diff --git a/src/Controller/ResqAPI/VehicleController.php b/src/Controller/ResqAPI/VehicleController.php new file mode 100644 index 00000000..bbb8f5d0 --- /dev/null +++ b/src/Controller/ResqAPI/VehicleController.php @@ -0,0 +1,190 @@ +acl_gen = $acl_gen; + } + + public function listVehicleManufacturers(Request $req, EntityManagerInterface $em) + { + // check required parameters and api key + $required_params = []; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + // get manufacturer list + $mfgs = $em->getRepository(VehicleManufacturer::class)->findBy(['flag_mobile' => true], ['name' => 'asc']); + $mfg_list = []; + foreach ($mfgs as $mfg) + { + $mfg_list[] = [ + 'id' => $mfg->getID(), + 'name' => $mfg->getName(), + ]; + } + + $data = [ + 'manufacturers' => $mfg_list + ]; + $res->setData($data); + + return $res->getReturnResponse(); + } + + public function listVehicleMakes(Request $req, $mfg_id, EntityManagerInterface $em) + { + // check required parameters and api key + $required_params = []; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + // get manufacturer + $mfg = $em->getRepository(VehicleManufacturer::class)->find($mfg_id); + if ($mfg == null) + { + $res->setError(true) + ->setErrorMessage('Invalid vehicle manufacturer id'); + return $res->getReturnResponse(); + } + + // get makes + $vehicles = $em->getRepository(Vehicle::class)->findBy( + [ + 'flag_mobile' => true, + 'manufacturer' => $mfg_id, + ], + ['make' => 'asc'] + ); + // $vehicles = $mfg->getVehicles(); + $vlist = []; + foreach ($vehicles as $v) + { + $vlist[] = [ + 'id' => $v->getID(), + 'make' => trim($v->getMake() . ' ' . $v->getModelYearFormatted(false)), + // 'make' => $v->getMake() . ' ' . $v->getModelYearFrom() . '-' . $v->getModelYearTo(), + ]; + } + + $data = [ + 'manufacturer' => [ + 'id' => $mfg->getID(), + 'name' => $mfg->getName(), + ], + 'makes' => $vlist, + ]; + + $res->setData($data); + + return $res->getReturnResponse(); + } + + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkParamsAndKey(Request $req, $em, $params) + { + // TODO: depends on what we decide to return + // returns APIResult object + $res = new APIResult(); + + // check for api_key in query string + $api_key = $req->query->get('api_key'); + if (empty($api_key)) + { + $res->setError(true) + ->setErrorMessage('Missing API key'); + return $res; + } + + // check missing parameters + $missing = $this->checkMissingParameters($req, $params); + if (count($missing) > 0) + { + $miss_string = implode(', ', $missing); + $res->setError(true) + ->setErrorMessage('Missing parameter(s): ' . $miss_string); + return $res; + } + + // check api key + $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); + if ($mobile_user == null) + { + $res->setError(true) + ->setErrorMessage('Invalid API Key'); + return $res; + } + + // store session + $this->session = $sess; + + return $res; + } + + // TODO: this might not be needed if we use APIController's checkRequiredParameters + // or we put this into a service? + protected function checkMissingParameters(Request $req, $params = []) + { + $missing = []; + + // check if parameters are there + foreach ($params as $param) + { + if ($req->getMethod() == 'GET') + { + $check = $req->query->get($param); + if (empty($check)) + $missing[] = $param; + } + else if ($req->getMethod() == 'POST') + { + $check = $req->request->get($param); + if (empty($check)) + $missing[] = $param; + } + else + return $params; + } + + return $missing; + } + + // TODO: type hint entity manager + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkAPIKey($em, $api_key) + { + // find the api key (session id) + // TODO: user validation needs to be changed + $m_user = $em->getRepository(MobileUser::class)->find($api_key); + if ($m_user == null) + return null; + + return $m_user; + } +} -- 2.43.5 From fead12bcab4bafbe55a122e4fdf88c29db6dad0d Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 24 Jun 2021 08:45:09 +0000 Subject: [PATCH 05/42] Add controllers for battery, partner, promo, rider, and service. #591 --- src/Controller/ResqAPI/BatteryController.php | 168 +++++++++ src/Controller/ResqAPI/PartnerController.php | 257 +++++++++++++ src/Controller/ResqAPI/PromoController.php | 124 +++++++ src/Controller/ResqAPI/RiderController.php | 368 +++++++++++++++++++ src/Controller/ResqAPI/ServiceController.php | 164 +++++++++ 5 files changed, 1081 insertions(+) create mode 100644 src/Controller/ResqAPI/BatteryController.php create mode 100644 src/Controller/ResqAPI/PartnerController.php create mode 100644 src/Controller/ResqAPI/PromoController.php create mode 100644 src/Controller/ResqAPI/RiderController.php create mode 100644 src/Controller/ResqAPI/ServiceController.php diff --git a/src/Controller/ResqAPI/BatteryController.php b/src/Controller/ResqAPI/BatteryController.php new file mode 100644 index 00000000..3f44294d --- /dev/null +++ b/src/Controller/ResqAPI/BatteryController.php @@ -0,0 +1,168 @@ +acl_gen = $acl_gen; + } + + public function getCompatibleBatteries(Request $req, $vid, EntityManagerInterface $em) + { + // check required parameters and api key + $required_params = []; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + // get vehicle + $vehicle = $em->getRepository(Vehicle::class)->find($vid); + if ($vehicle == null) + { + $res->setError(true) + ->setErrorMessage('Invalid vehicle'); + return $res->getReturnResponse(); + } + + // batteries + $batt_list = []; + $batts = $vehicle->getBatteries(); + foreach ($batts as $batt) + { + // TODO: Add warranty_tnv to battery information + $batt_list[] = [ + 'id' => $batt->getID(), + 'mfg_id' => $batt->getManufacturer()->getID(), + 'mfg_name' => $batt->getManufacturer()->getName(), + 'model_id' => $batt->getModel()->getID(), + 'model_name' => $batt->getModel()->getName(), + 'size_id' => $batt->getSize()->getID(), + 'size_name' => $batt->getSize()->getName(), + 'price' => $batt->getSellingPrice(), + 'wty_private' => $batt->getWarrantyPrivate(), + 'wty_commercial' => $batt->getWarrantyCommercial(), + 'image_url' => $this->getBatteryImageURL($req, $batt), + ]; + } + + // data + $data = [ + 'vehicle' => [ + 'id' => $vehicle->getID(), + 'mfg_id' => $vehicle->getManufacturer()->getID(), + 'mfg_name' => $vehicle->getManufacturer()->getName(), + 'make' => $vehicle->getMake(), + 'model_year_from' => $vehicle->getModelYearFrom(), + 'model_year_to' => $vehicle->getModelYearTo(), + ], + 'batteries' => $batt_list, + ]; + $res->setData($data); + + return $res->getReturnResponse(); + } + + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkParamsAndKey(Request $req, $em, $params) + { + // TODO: depends on what we decide to return + // returns APIResult object + $res = new APIResult(); + + // check for api_key in query string + $api_key = $req->query->get('api_key'); + if (empty($api_key)) + { + $res->setError(true) + ->setErrorMessage('Missing API key'); + return $res; + } + + // check missing parameters + $missing = $this->checkMissingParameters($req, $params); + if (count($missing) > 0) + { + $miss_string = implode(', ', $missing); + $res->setError(true) + ->setErrorMessage('Missing parameter(s): ' . $miss_string); + return $res; + } + + // check api key + $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); + if ($mobile_user == null) + { + $res->setError(true) + ->setErrorMessage('Invalid API Key'); + return $res; + } + + // store session + $this->session = $sess; + + return $res; + } + + // TODO: this might not be needed if we use APIController's checkRequiredParameters + // or we put this into a service? + protected function checkMissingParameters(Request $req, $params = []) + { + $missing = []; + + // check if parameters are there + foreach ($params as $param) + { + if ($req->getMethod() == 'GET') + { + $check = $req->query->get($param); + if (empty($check)) + $missing[] = $param; + } + else if ($req->getMethod() == 'POST') + { + $check = $req->request->get($param); + if (empty($check)) + $missing[] = $param; + } + else + return $params; + } + + return $missing; + } + + // TODO: type hint entity manager + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkAPIKey($em, $api_key) + { + // find the api key (session id) + // TODO: user validation needs to be changed + $m_user = $em->getRepository(MobileUser::class)->find($api_key); + if ($m_user == null) + return null; + + return $m_user; + } +} diff --git a/src/Controller/ResqAPI/PartnerController.php b/src/Controller/ResqAPI/PartnerController.php new file mode 100644 index 00000000..e6bc0157 --- /dev/null +++ b/src/Controller/ResqAPI/PartnerController.php @@ -0,0 +1,257 @@ +acl_gen = $acl_gen; + } + + public function getClosestPartners(Request $req, EntityManagerInterface $em) + { + $required_params = [ + 'longitude', + 'latitude', + 'service_id', + 'limit', + ]; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + $long = $req->query->get('longitude'); + $lat = $req->query->get('latitude'); + $service_id = $req->query->get('service_id'); + $limit = $req->query->get('limit'); + + // get partners within range + $query = $em->createQuery('SELECT p, st_distance(p.coordinates, point(:lng, :lat)) as dist FROM App\Entity\Partner p + JOIN App\Entity\Service s where s.id = :service_id ORDER BY dist') + ->setParameter('lat', $lat) + ->setParameter('lng', $long) + ->setParameter('service_id', $service_id); + + $query->setMaxResults($limit); + $result = $query->getResult(); + + $data = []; + $partners = []; + foreach($result as $row) + { + $partners[] = [ + 'id' => $row[0]->getID(), + 'name' => $row[0]->getName(), + 'branch' => $row[0]->getBranch(), + 'address' => $row[0]->getAddress(), + 'contact_nums' => $row[0]->getContactNumbers(), + 'time_open' => $row[0]->getTimeOpen()->format("g:i A"), + 'time_close' => $row[0]->getTimeClose()->format("g:i A"), + 'longitude' => $row[0]->getCoordinates()->getLongitude(), + 'latitude' => $row[0]->getCoordinates()->getLatitude(), + 'db_distance' => $row['dist'], + ]; + } + + $data['partners'] = $partners; + + $res->setData($data); + + return $res->getReturnResponse(); + } + + public function getPartnerInformation(Request $req, $pid, EntityManagerInterface $em) + { + $required_params = []; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + // get partner + $partner = $em->getRepository(Partner::class)->findOneBy(['id' => $pid]); + if ($partner == null) + { + $res->setError(true) + ->setErrorMessage('No partner found.'); + return $res->getReturnResponse(); + } + + // get reviews for partner + $reviews = $em->getRepository(Review::class)->findBy(['partner' => $partner]); + + // get average rating for all reviews + $average_rating = 0; + if (!empty($reviews)) + { + $rating = 0; + foreach($reviews as $review) + { + $rating = $rating + $review->getRating(); + } + + $average_rating = $rating / sizeof($reviews); + } + + $data['partner'] = [ + 'id' => $partner->getID(), + 'name' => $partner->getName(), + 'branch' => $partner->getBranch(), + 'address' => $partner->getAddress(), + 'contact_nums' => $partner->getContactNumbers(), + 'time_open' => $partner->getTimeOpen()->format("g:i A"), + 'time_close' => $partner->getTimeClose()->format("g:i A"), + 'longitude' => $partner->getCoordinates()->getLongitude(), + 'latitude' => $partner->getCoordinates()->getLatitude(), + 'average_rating' => $average_rating, + ]; + + $res->setData($data); + + return $res->getReturnResponse(); + } + + public function reviewPartner($pid, Request $req, EntityManagerInterface $em) + { + $required_params = [ + 'rating', + 'message', + ]; + + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + $rating = $req->request->get('rating'); + $msg = $req->request->get('message'); + + // TODO: check rating if 1 - 5 + + // check if partner exists + $partner = $em->getRepository(Partner::class)->find($pid); + if ($partner == null) + { + $res->setError(true) + ->setErrorMessage('No partner found.'); + return $res->getReturnResponse(); + } + + $rev = new Review(); + $rev->setRating($rating) + ->setMessage($msg) + ->setPartner($partner) + ->setMobileSession($this->session); + + // save to db + $em->persist($rev); + $em->flush(); + + $data = []; + $res->setData($data); + + return $res->getReturnResponse(); + } + + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkParamsAndKey(Request $req, $em, $params) + { + // TODO: depends on what we decide to return + // returns APIResult object + $res = new APIResult(); + + // check for api_key in query string + $api_key = $req->query->get('api_key'); + if (empty($api_key)) + { + $res->setError(true) + ->setErrorMessage('Missing API key'); + return $res; + } + + // check missing parameters + $missing = $this->checkMissingParameters($req, $params); + if (count($missing) > 0) + { + $miss_string = implode(', ', $missing); + $res->setError(true) + ->setErrorMessage('Missing parameter(s): ' . $miss_string); + return $res; + } + + // check api key + $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); + if ($mobile_user == null) + { + $res->setError(true) + ->setErrorMessage('Invalid API Key'); + return $res; + } + + // store session + $this->session = $sess; + + return $res; + } + + // TODO: this might not be needed if we use APIController's checkRequiredParameters + // or we put this into a service? + protected function checkMissingParameters(Request $req, $params = []) + { + $missing = []; + + // check if parameters are there + foreach ($params as $param) + { + if ($req->getMethod() == 'GET') + { + $check = $req->query->get($param); + if (empty($check)) + $missing[] = $param; + } + else if ($req->getMethod() == 'POST') + { + $check = $req->request->get($param); + if (empty($check)) + $missing[] = $param; + } + else + return $params; + } + + return $missing; + } + + // TODO: type hint entity manager + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkAPIKey($em, $api_key) + { + // find the api key (session id) + // TODO: user validation needs to be changed + $m_user = $em->getRepository(MobileUser::class)->find($api_key); + if ($m_user == null) + return null; + + return $m_user; + } +} diff --git a/src/Controller/ResqAPI/PromoController.php b/src/Controller/ResqAPI/PromoController.php new file mode 100644 index 00000000..75dc419c --- /dev/null +++ b/src/Controller/ResqAPI/PromoController.php @@ -0,0 +1,124 @@ +acl_gen = $acl_gen; + } + + public function listPromos(Request $req, EntityManagerInterface $em) + { + // check required parameters and api key + $required_params = []; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + return $res->getReturnResponse(); + } + + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkParamsAndKey(Request $req, $em, $params) + { + // TODO: depends on what we decide to return + // returns APIResult object + $res = new APIResult(); + + // check for api_key in query string + $api_key = $req->query->get('api_key'); + if (empty($api_key)) + { + $res->setError(true) + ->setErrorMessage('Missing API key'); + return $res; + } + + // check missing parameters + $missing = $this->checkMissingParameters($req, $params); + if (count($missing) > 0) + { + $miss_string = implode(', ', $missing); + $res->setError(true) + ->setErrorMessage('Missing parameter(s): ' . $miss_string); + return $res; + } + + // check api key + $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); + if ($mobile_user == null) + { + $res->setError(true) + ->setErrorMessage('Invalid API Key'); + return $res; + } + + // store session + $this->session = $sess; + + return $res; + } + + // TODO: this might not be needed if we use APIController's checkRequiredParameters + // or we put this into a service? + protected function checkMissingParameters(Request $req, $params = []) + { + $missing = []; + + // check if parameters are there + foreach ($params as $param) + { + if ($req->getMethod() == 'GET') + { + $check = $req->query->get($param); + if (empty($check)) + $missing[] = $param; + } + else if ($req->getMethod() == 'POST') + { + $check = $req->request->get($param); + if (empty($check)) + $missing[] = $param; + } + else + return $params; + } + + return $missing; + } + + // TODO: type hint entity manager + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkAPIKey($em, $api_key) + { + // find the api key (session id) + // TODO: user validation needs to be changed + $m_user = $em->getRepository(MobileUser::class)->find($api_key); + if ($m_user == null) + return null; + + return $m_user; + } +} diff --git a/src/Controller/ResqAPI/RiderController.php b/src/Controller/ResqAPI/RiderController.php new file mode 100644 index 00000000..b7f97783 --- /dev/null +++ b/src/Controller/ResqAPI/RiderController.php @@ -0,0 +1,368 @@ +acl_gen = $acl_gen; + } + + // TODO: needs to be modified for mobile user + public function getRiderStatus(Request $req, RiderTracker $rt, EntityManagerInterface $em) + { + $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, $em); + + if (count($ongoing_jos) <= 0) + { + try + { + // check if the latest fulfilled jo they have needs rider rating + $query = $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) + { + // no pending + $res->setData([ + 'status' => APIRiderStatus::NO_PENDING_JO + ]); + return $res->getReturnResponse(); + } + + // 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, + ]; + $res->setData($data); + return $res->getReturnResponse(); + } + } + + // no pending + $res->setData([ + 'status' => APIRiderStatus::NO_PENDING_JO + ]); + return $res->getReturnResponse(); + } + + // 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; + $res->setData($data); + return $res->getReturnResponse(); + case JOStatus::RIDER_ASSIGN: + $data['status'] = APIRiderStatus::RIDER_ASSIGN; + $res->setData($data); + return $res->getReturnResponse(); + 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() + ] + ]; + $res->setData($data); + return $res->getReturnResponse(); + } + + $res->setData($data); + + return $res->getReturnResponse(); + } + + // TODO: needs to be modified for mobile user + public function addRiderRating(Request $req, EntityManagerInterface $em) + { + $required_params = [ + 'jo_id', + 'rating', + ]; + $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 job order + $jo_id = $req->request->get('jo_id'); + $jo = $em->getRepository(JobOrder::class)->find($jo_id); + if ($jo == null) + { + $res->setError(true) + ->setErrorMessage('No job order found'); + return $res->getReturnResponse(); + } + + // get rider + $rider = $jo->getRider(); + if ($rider == null) + { + $res->setError(true) + ->setErrorMessage('No rider found'); + return $res->getReturnResponse(); + } + + // check that the customer owns the job order + $jo_cust = $jo->getCustomer(); + if ($jo_cust->getID() != $cust->getID()) + { + $res->setError(true) + ->setErrorMessage('Job order was not initiated by customer'); + return $res->getReturnResponse(); + } + + // 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(); + $em->flush(); + + $res->setData([]); + + return $res->getReturnResponse(); + } + + + $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(); + + $em->persist($rating); + $em->flush(); + + // TODO: set average rating in rider entity + + $res->setData([]); + + return $res->getReturnResponse(); + } + + protected function getOngoingJobOrders($cust, $em) + { + $ongoing_jos = $em->getRepository(JobOrder::class)->findBy([ + 'customer' => $cust, + 'status' => [JOStatus::PENDING, JOStatus::RIDER_ASSIGN, JOStatus::IN_TRANSIT, JOStatus::ASSIGNED, JOStatus::IN_PROGRESS], + ]); + + return $ongoing_jos; + } + + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkParamsAndKey(Request $req, $em, $params) + { + // TODO: depends on what we decide to return + // returns APIResult object + $res = new APIResult(); + + // check for api_key in query string + $api_key = $req->query->get('api_key'); + if (empty($api_key)) + { + $res->setError(true) + ->setErrorMessage('Missing API key'); + return $res; + } + + // check missing parameters + $missing = $this->checkMissingParameters($req, $params); + if (count($missing) > 0) + { + $miss_string = implode(', ', $missing); + $res->setError(true) + ->setErrorMessage('Missing parameter(s): ' . $miss_string); + return $res; + } + + // check api key + $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); + if ($mobile_user == null) + { + $res->setError(true) + ->setErrorMessage('Invalid API Key'); + return $res; + } + + // store session + $this->session = $sess; + + return $res; + } + + // TODO: this might not be needed if we use APIController's checkRequiredParameters + // or we put this into a service? + protected function checkMissingParameters(Request $req, $params = []) + { + $missing = []; + + // check if parameters are there + foreach ($params as $param) + { + if ($req->getMethod() == 'GET') + { + $check = $req->query->get($param); + if (empty($check)) + $missing[] = $param; + } + else if ($req->getMethod() == 'POST') + { + $check = $req->request->get($param); + if (empty($check)) + $missing[] = $param; + } + else + return $params; + } + + return $missing; + } + + // TODO: type hint entity manager + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkAPIKey($em, $api_key) + { + // find the api key (session id) + // TODO: user validation needs to be changed + $m_user = $em->getRepository(MobileUser::class)->find($api_key); + if ($m_user == null) + return null; + + return $m_user; + } +} diff --git a/src/Controller/ResqAPI/ServiceController.php b/src/Controller/ResqAPI/ServiceController.php new file mode 100644 index 00000000..0c47867e --- /dev/null +++ b/src/Controller/ResqAPI/ServiceController.php @@ -0,0 +1,164 @@ +acl_gen = $acl_gen; + } + + public function listServices(Request $req, EntityManagerInterface $em) + { + $required_params = []; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + // services + $results = $em->getRepository(Service::class)->findAll(); + if (empty($results)) + { + $res->setError(true) + ->setErrorMessage('No services available.'); + return $res->getReturnResponse(); + } + + $services = []; + foreach ($results as $result) + { + /* + // get partners + $partners = []; + $service_partners = $result->getPartners(); + foreach($service_partners as $sp) + { + $partners[] = [ + 'id' => $sp->getID(), + 'name' => $sp->getName(), + 'branch' => $sp->getBranch(), + 'address' => $sp->getAddress(), + 'contact_nums' => $sp->getContactNumbers(), + 'time_open' => $sp->getTimeOpen()->format("g:i A"), + 'time_close' => $sp->getTimeClose()->format("g:i A"), + ]; + } + */ + + $services[] = [ + 'id' => $result->getID(), + 'name' => $result->getName(), + // 'partners' => $partners, + ]; + } + + $data['services'] = $services; + + $res->setData($data); + + return $res->getReturnResponse(); + } + + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkParamsAndKey(Request $req, $em, $params) + { + // TODO: depends on what we decide to return + // returns APIResult object + $res = new APIResult(); + + // check for api_key in query string + $api_key = $req->query->get('api_key'); + if (empty($api_key)) + { + $res->setError(true) + ->setErrorMessage('Missing API key'); + return $res; + } + + // check missing parameters + $missing = $this->checkMissingParameters($req, $params); + if (count($missing) > 0) + { + $miss_string = implode(', ', $missing); + $res->setError(true) + ->setErrorMessage('Missing parameter(s): ' . $miss_string); + return $res; + } + + // check api key + $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); + if ($mobile_user == null) + { + $res->setError(true) + ->setErrorMessage('Invalid API Key'); + return $res; + } + + // store session + $this->session = $sess; + + return $res; + } + + // TODO: this might not be needed if we use APIController's checkRequiredParameters + // or we put this into a service? + protected function checkMissingParameters(Request $req, $params = []) + { + $missing = []; + + // check if parameters are there + foreach ($params as $param) + { + if ($req->getMethod() == 'GET') + { + $check = $req->query->get($param); + if (empty($check)) + $missing[] = $param; + } + else if ($req->getMethod() == 'POST') + { + $check = $req->request->get($param); + if (empty($check)) + $missing[] = $param; + } + else + return $params; + } + + return $missing; + } + + // TODO: type hint entity manager + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkAPIKey($em, $api_key) + { + // find the api key (session id) + // TODO: user validation needs to be changed + $m_user = $em->getRepository(MobileUser::class)->find($api_key); + if ($m_user == null) + return null; + + return $m_user; + } +} -- 2.43.5 From f0b562b0cb38c5e4ca4f9ad8676663f35beda36d Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 24 Jun 2021 09:35:51 +0000 Subject: [PATCH 06/42] Add warranty controller. #591 --- .../ResqAPI/CustomerVehicleController.php | 74 ++- src/Controller/ResqAPI/WarrantyController.php | 600 ++++++++++++++++++ 2 files changed, 672 insertions(+), 2 deletions(-) create mode 100644 src/Controller/ResqAPI/WarrantyController.php diff --git a/src/Controller/ResqAPI/CustomerVehicleController.php b/src/Controller/ResqAPI/CustomerVehicleController.php index 5ce7ab6b..36f8e12a 100644 --- a/src/Controller/ResqAPI/CustomerVehicleController.php +++ b/src/Controller/ResqAPI/CustomerVehicleController.php @@ -107,7 +107,7 @@ class CustomerVehicleController extends APIController if ($cv->getWarrantyExpiration() != null) $wty_ex = $cv->getWarrantyExpiration()->format('Y-m-d'); - $warranty = $this->findWarranty($cv->getPlateNumber()); + $warranty = $this->findWarranty($cv->getPlateNumber(), $em); $cv_name = ''; if ($cv->getName() != null) @@ -168,7 +168,6 @@ class CustomerVehicleController extends APIController return $res; } - protected function setCustomerVehicleObject(Request $req, APIResult $res, CustomerVehicle $cv, EntityManagerInterface $em) { @@ -233,6 +232,77 @@ class CustomerVehicleController extends APIController return $res; } + // TODO: what to do with this? listVehicles calls this and so does getJOHistory in the JobOrderController + protected function findWarranty($plate_number, $em) + { + // NOTE: Modify the search for the latest warranty. This seems hacky. + // get latest warranty using plate number + $warranty_results = $em->getRepository(Warranty::class)->findBy(['plate_number' => $plate_number], + ['date_create' => 'desc']); + + $warr = []; + + // check if warranty_results is empty + if (empty($warranty_results)) + { + /* + $res->setError(true) + ->setErrorMessage('No warranty found for plate number'); + return $res->getReturnResponse(); + */ + + return $warr; + } + + // get first entry + $warranty = current($warranty_results); + + // check for null values for battery and date claim and date expire + $batt_model = ''; + $batt_size = ''; + $sap_batt = ''; + $claim_date = ''; + $expiry_date = ''; + + if (!(is_null($warranty->getBatteryModel()))) { + $batt_model = $warranty->getBatteryModel()->getName(); + } + if (!(is_null($warranty->getBatterySize()))) { + $batt_size = $warranty->getBatterySize()->getName(); + } + if (!(is_null($warranty->getSAPBattery()))) { + $sap_batt = $warranty->getSAPBattery()->getID(); + } + if (!(is_null($warranty->getDateClaim()))) { + $claim_date = $warranty->getDateClaim()->format("d M Y"); + } + if (!(is_null($warranty->getDateExpire()))) { + $expiry_date = $warranty->getDateExpire()->format("d M Y"); + } + + $warr[] = [ + 'id' => $warranty->getID(), + 'serial' => $warranty->getSerial(), + 'warranty_class' => $warranty->getWarrantyClass(), + 'plate_number' => $warranty->getPlateNumber(), + 'first_name' => $warranty->getFirstName(), + 'last_name' => $warranty->getLastName(), + 'mobile_number' => $warranty->getMobileNumber(), + 'battery_model' => $batt_model, + 'battery_size' => $batt_size, + 'sap_battery' => $sap_batt, + 'status' => $warranty->getStatus(), + 'date_create' => $warranty->getDateCreate()->format("d M Y g:i A"), + 'date_purchase' => $warranty->getDatePurchase()->format("d M Y"), + 'date_expire' => $expiry_date, + 'date_claim' => $claim_date, + 'claim_from' => $warranty->getClaimedFrom(), + 'is_activated' => $warranty->isActivated() ? 1 : 0, + ]; + + return $warr; + } + // TODO: since we broke the functions into separate files, we need // to figure out how to make this accessible to all ResqAPI controllers protected function checkParamsAndKey(Request $req, $em, $params) diff --git a/src/Controller/ResqAPI/WarrantyController.php b/src/Controller/ResqAPI/WarrantyController.php new file mode 100644 index 00000000..95322264 --- /dev/null +++ b/src/Controller/ResqAPI/WarrantyController.php @@ -0,0 +1,600 @@ +acl_gen = $acl_gen; + } + + public function warrantyRegister($serial, EntityManagerInterface $em, Request $req, KernelInterface $kernel, RisingTideGateway $rt, + TranslatorInterface $trans, WarrantyAPILogger $logger) + { + // check required parameters and api key + $required_params = [ + 'first_name', + 'last_name', + 'plate_number', + 'date_purchase', + ]; + + // handle file uploads + $invoice = $req->files->get('invoice'); + $warr_card = $req->files->get('warr_card'); + + // normalize serial + $serial = trim(strtoupper($serial)); + + // process picture uploads + $upload_dir = $kernel->getProjectDir() . '/public/warranty_uploads'; + $inv_filename = $this->handlePictureUpload($invoice, $upload_dir, $serial, 'invoice'); + $wcard_filename = $this->handlePictureUpload($warr_card, $upload_dir, $serial, 'wcard'); + + $user_id = $req->query->get('api_key'); + $log_data = [ + 'plate_number' => $req->request->get('plate_num'), + 'first_name' => $req->request->get('first_name'), + 'last_name' => $req->request->get('last_name'), + 'date_purchase' => $req->request->get('date_purchase'), + ]; + $action = 'create'; + $source = WarrantySource::MOBILE; + + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + { + $logger->logWarrantyInfo($log_data, $res->getErrorMessage(), $user_id, $action, $source); + return $res->getReturnResponse(); + } + + // update customer information + // $cust = $this->updateCustomerInfo($req, $em); + + // update warranty + $res = $this->updateWarranty($res, $em, $rt, $trans, $req, $serial, $inv_filename, $wcard_filename, + $logger, $log_data, $user_id, $action, $source); + + $em->flush(); + + return $res->getReturnResponse(); + } + + // TODO: needs to be modified for mobile user + public function warrantyCheck($serial, EntityManagerInterface $em, Request $req) + { + // check required parameters and api key + $required_params = []; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + // check if warranty serial is there + $warr_serial = $em->getRepository(WarrantySerial::class)->find($serial); + $warr = $em->getRepository(Warranty::class)->findOneBy(['serial' => $serial]); + $batt = null; + $is_registered = false; + + if ($warr_serial == null) + { + $res->setError(true) + ->setErrorMessage('Invalid warranty serial code.'); + return $res->getReturnResponse(); + } + + $today = new DateTime(); + + // if we have a warranty entry for the serial already + if ($warr != null) + { + $warr_plate = $warr->getPlateNumber(); + $is_registered = true; + $is_customer_warranty = false; + + // check if the warranty is registered to a car owned by the customer + $cust = $this->session->getCustomer(); + $is_customer_warranty = $this->checkCustomerPlateNumber($warr_plate, $cust); + + // null mobile number should be blank string instead + if ($warr->getMobileNumber() == null) + $mobile_num = ''; + else + $mobile_num = $warr->getMobileNumber(); + + $can_edit = $is_customer_warranty; + + // if customer plate number matches the one registered on the warranty + if ($is_customer_warranty) + { + // purchase date of customer + if ($warr->getDatePurchaseCustomer() != null) + $date_purchase_cust = $warr->getDatePurchaseCustomer()->format('Y-m-d'); + else + $date_purchase_cust = $today->format('Y-m-d'); + + // invoice + if ($warr->getFileInvoice() != null) + $invoice_url = $req->getSchemeAndHttpHost() . '/warranty_uploads/' . $warr->getFileInvoice(); + else + $invoice_url = ''; + + // warranty card + if ($warr->getFileWarrantyCard() != null) + $warr_card_url = $req->getSchemeAndHttpHost() . '/warranty_uploads/' . $warr->getFileWarrantyCard(); + else + $warr_card_url = ''; + + $customer = [ + 'first_name' => $warr->getFirstName() ?? '', + 'last_name' => $warr->getLastName() ?? '', + 'mobile_number' => $mobile_num, + 'plate_number' => $warr_plate, + 'email' => $warr->getEmail() ?? '', + 'contact_num' => $warr->getContactNumber() ?? '', + 'address' => $warr->getCustomerAddress() ?? '', + ]; + $other_data = [ + 'odometer' => (int) $warr->getOdometer() ?? 0, + 'date_purchase' => $date_purchase_cust, + 'invoice' => $invoice_url, + 'warr_card' => $warr_card_url, + 'dealer_name' => $warr->getDealerName() ?? '', + 'dealer_address' => $warr->getDealerAddress() ?? '', + ]; + } + else + { + // hide customer information if customer is not the one registered + $customer = [ + 'first_name' => '', + 'last_name' => '', + 'mobile_number' => '', + 'plate_number' => '', + 'email' => '', + 'contact_num' => '', + 'address' => '', + ]; + $other_data = [ + 'odometer' => 0, + 'date_purchase' => $today->format('Y-m-d'), + 'invoice' => '', + 'warr_card' => '', + 'dealer_name' => '', + 'dealer_address' => '', + ]; + } + } + else + { + $can_edit = true; + $customer = [ + 'first_name' => '', + 'last_name' => '', + 'mobile_number' => '', + 'plate_number' => '', + 'email' => '', + 'contact_num' => '', + 'address' => '', + ]; + $other_data = [ + 'odometer' => 0, + 'date_purchase' => $today->format('Y-m-d'), + 'invoice' => '', + 'warr_card' => '', + 'dealer_name' => '', + 'dealer_address' => '', + ]; + } + + $sku = $warr_serial->getSKU(); + $batt = null; + $cat_name = ''; + if ($sku != null) + $batt = $em->getRepository(SAPBattery::class)->find($sku); + else + { + // get the category name of the serial + $cat_name = $warr_serial->getMetaInfo('category_name'); + } + + // TODO: put this in a config file + $image_url = $req->getSchemeAndHttpHost() . '/battery/generic.png'; + if ($batt != null) + { + $battery = [ + 'brand' => $batt->getBrand()->getName(), + 'size' => $batt->getSize()->getName(), + 'image_url' => $image_url, + ]; + } + else + { + $battery = [ + 'brand' => $cat_name, + 'size' => '', + 'image_url' => '', + ]; + } + + // populate data + $data = [ + 'is_valid' => true, + 'is_registered' => $is_registered, + 'can_edit' => $can_edit, + 'customer' => $customer, + 'battery' => $battery, + 'odometer' => $other_data['odometer'], + 'invoice' => $other_data['invoice'], + 'warr_card' => $other_data['warr_card'], + 'date_purchase' => $other_data['date_purchase'], + 'dealer_name' => $other_data['dealer_name'], + 'dealer_address' => $other_data['dealer_address'], + 'message' => [ + 'register_error' => 'Warranty serial code has already been registered.', + 'edit_error' => 'Sorry, warranty is registered under another vehicle not in your list of vehicles.', + ], + ]; + + $res->setData($data); + + return $res->getReturnResponse(); + } + + public function activateWarranty(Request $req, EntityManagerInterface $em) + { + $required_params = ['plate_number']; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + $plate_number = $req->request->get('plate_number'); + + // find warranty using plate number + $warranty_results = $em->getRepository(Warranty::class)->findBy(['plate_number' => $plate_number], + ['date_create' => 'desc']); + + // check if warranty_results is empty + if (empty($warranty_results)) + { + $res->setError(true) + ->setErrorMessage('No warranty found for plate number'); + return $res->getReturnResponse(); + } + + // activate all entries + foreach ($warranty_results as $warranty) + { + $warranty->setActivated(); + } + + $em->flush(); + + return $res->getReturnResponse(); + } + + protected function handlePictureUpload($file, $target_dir, $serial, $name) + { + error_log("handling $name upload"); + // no file sent + if ($file == null) + { + error_log('no file'); + return null; + } + + // create target dir if it doesn't exist + if (!file_exists($target_dir)) + { + if (!mkdir($target_dir, 0744, true)) + { + error_log('failed to create folder for warranty pictures'); + return null; + } + } + + // move file + $filename = $name . '.' . $file->getClientOriginalExtension(); + $file->move($target_dir . '/' . $serial, $filename); + + error_log("filename - $filename"); + error_log($target_dir . '/' . $serial . '/' . $filename); + + return $serial . '/' . $filename; + } + + // TODO: needs to be modified for mobile user + protected function updateWarranty($res, $em, $rt, $trans, $req, $serial, $inv_filename = null, $wcard_filename = null, + $logger, $log_data, $user_id, $action, $source) + { + // get serial + $warr_serial = $em->getRepository(WarrantySerial::class)->find($serial); + if ($warr_serial == null) + { + $res->setError(true) + ->setErrorMessage('Invalid warranty serial code.'); + $logger->logWarrantyInfo($log_data, $res->getErrorMessage(), $user_id, $action, $source); + return $res; + } + + // check if warranty exists already + $warr = $em->getRepository(Warranty::class)->findOneBy(['serial' => $serial]); + + // skip warranty if it already exists + if ($warr != null) + { + /* + // NOTE: we could not update in the old version + $res->setError(true) + ->setErrorMessage('Warranty registration entry already exists.'); + return $res; + */ + + // check if warranty is registered to a serial owned by customer + $warr_plate = $warr->getPlateNumber(); + $cust = $this->session->getCustomer(); + $is_customer_warranty = $this->checkCustomerPlateNumber($warr_plate, $cust); + + if (!$is_customer_warranty) + { + $res->setError(true) + ->setErrorMessage('Warranty registered to a vehicle not in your list of vehicles.'); + $logger->logWarrantyInfo($log_data, $res->getErrorMessage(), $user_id, $action, $source); + return $res; + } + + $sms_msg = $trans->trans('warranty_update_confirm'); + } + else + { + $warr = new Warranty(); + $sms_msg = $trans->trans('warranty_register_confirm'); + + // set warranty source + $warr->setCreateSource($source); + } + + // get sap battery + $sku = $warr_serial->getSKU(); + $sap_bty = null; + if ($sku != null) + { + $sap_bty = $em->getRepository(SAPBattery::class)->find($sku); + if ($sap_bty == null) + { + $res->setError(true) + ->setErrorMessage('Could not find battery entry for warranty.'); + $logger->logWarrantyInfo($log_data, $res->getErrorMessage(), $user_id, $action, $source); + return $res; + } + } + + // default date purchase to today + // NOTE: might need to change this later + $date_pur = new DateTime(); + + // get date purchase specified by customer + $date_pur_cust = DateTime::createFromFormat('Y-m-d', $req->request->get('date_purchase')); + if (!$date_pur_cust) + { + $res->setError(true) + ->setErrorMessage('Invalid date format for date of purchase.'); + $logger->logWarrantyInfo($log_data, $res->getErrorMessage(), $user_id, $action, $source); + return $res; + } + + $customer = $this->session->getCustomer(); + if ($customer != null) + { + $warr->setCustomer($customer); + // get customer vehicles + + $vehicle = $this->findCustomerVehicle($em, $customer, $req->request->get('plate_number')); + if ($vehicle != null) + $warr->setVehicle($vehicle); + } + + // create or update warranty entry + $warr->setSerial($serial) + ->setFirstName($req->request->get('first_name')) + ->setLastName($req->request->get('last_name')) + ->setEmail($req->request->get('email')) + ->setPlateNumber($req->request->get('plate_number')) + // TODO: figure out how to compute date of purchase + ->setDatePurchase($date_pur) + // TODO: set status + // ->setStatus() + // TODO: set battery model and size id + // ->setBatterySize() + // ->setBatteryModel() + ->setSAPBattery($sap_bty) + ->setMobileNumber(substr($this->session->getPhoneNumber(), 2)) + ->setActivated(true) + + // files + ->setFileInvoice($inv_filename) + ->setFileWarrantyCard($wcard_filename) + + // new fields + ->setOdometer($req->request->get('odometer', 0)) + ->setDatePurchaseCustomer($date_pur_cust) + ->setContactNumber($req->request->get('contact_num')) + ->setCustomerAddress($req->request->get('cust_address')) + ->setDealerName($req->request->get('dealer_name')) + ->setDealerAddress($req->request->get('dealer_address')) + ->setValidated(false); + + // TODO: check for date purchase and date expire + + $em->persist($warr); + + // TODO: check if we need to do anyting else + $data = []; + + // set data to retrun to user + $res->setData($data); + + $logger->logWarrantyInfo($log_data, '', $user_id, $action, $source); + + // send sms + error_log('sending sms to - ' . $this->session->getPhoneNumber()); + $rt->sendSMS($this->session->getPhoneNumber(), 'MOTOLITE', $sms_msg); + + return $res; + } + + protected function findCustomerVehicle($em, $customer, $plate_number) + { + $clean_plate = Warranty::cleanPlateNumber($plate_number); + if ($clean_plate) + { + // find the customer vehicle and get the vehicle + $cv = $em->getRepository(CustomerVehicle::class)->findOneBy(['plate_number' => $clean_plate, 'customer' => $customer]); + if ($cv != null) + { + $vehicle = $cv->getVehicle(); + return $vehicle; + } + } + + return null; + } + + protected function checkCustomerPlateNumber($plate_number, $cust) + { + // strip spaces and make all caps + $plate_number = preg_replace('/\s+/', '', strtoupper($plate_number)); + + // if there's no customer linked to session + if ($cust != null) + { + // check all the customer vehicles + $cvs = $cust->getVehicles(); + foreach ($cvs as $cv) + { + $cv_plate = preg_replace('/\s+/', '', strtoupper($cv->getPlateNumber())); + + // did we find a match? + if ($cv_plate == $plate_number) + { + return true; + } + } + } + + return false; + } + + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkParamsAndKey(Request $req, $em, $params) + { + // TODO: depends on what we decide to return + // returns APIResult object + $res = new APIResult(); + + // check for api_key in query string + $api_key = $req->query->get('api_key'); + if (empty($api_key)) + { + $res->setError(true) + ->setErrorMessage('Missing API key'); + return $res; + } + + // check missing parameters + $missing = $this->checkMissingParameters($req, $params); + if (count($missing) > 0) + { + $miss_string = implode(', ', $missing); + $res->setError(true) + ->setErrorMessage('Missing parameter(s): ' . $miss_string); + return $res; + } + + // check api key + $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); + if ($mobile_user == null) + { + $res->setError(true) + ->setErrorMessage('Invalid API Key'); + return $res; + } + + // store session + $this->session = $sess; + + return $res; + } + + // TODO: this might not be needed if we use APIController's checkRequiredParameters + // or we put this into a service? + protected function checkMissingParameters(Request $req, $params = []) + { + $missing = []; + + // check if parameters are there + foreach ($params as $param) + { + if ($req->getMethod() == 'GET') + { + $check = $req->query->get($param); + if (empty($check)) + $missing[] = $param; + } + else if ($req->getMethod() == 'POST') + { + $check = $req->request->get($param); + if (empty($check)) + $missing[] = $param; + } + else + return $params; + } + + return $missing; + } + + // TODO: type hint entity manager + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkAPIKey($em, $api_key) + { + // find the api key (session id) + // TODO: user validation needs to be changed + $m_user = $em->getRepository(MobileUser::class)->find($api_key); + if ($m_user == null) + return null; + + return $m_user; + } +} -- 2.43.5 From 1d4a52bbf2be7f03acf4b103c505635f00a7b4a7 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Fri, 25 Jun 2021 08:24:03 +0000 Subject: [PATCH 07/42] Add JobOrderController for JO mobile requests. #591 --- src/Controller/ResqAPI/JobOrderController.php | 1730 +++++++++++++++++ 1 file changed, 1730 insertions(+) create mode 100644 src/Controller/ResqAPI/JobOrderController.php diff --git a/src/Controller/ResqAPI/JobOrderController.php b/src/Controller/ResqAPI/JobOrderController.php new file mode 100644 index 00000000..618e691a --- /dev/null +++ b/src/Controller/ResqAPI/JobOrderController.php @@ -0,0 +1,1730 @@ +acl_gen = $acl_gen; + } + + // TODO: modify for MobileUser + // break this down into smaller functions + // do we still use this? + public function requestJobOrder(Request $req, InvoiceGeneratorInterface $ic, GeofenceTracker $geo, + InventoryManager $im, MQTTClient $mclient, RiderAssignmentHandlerInterface $rah, + PromoLogger $promo_logger, EntityManagerInterface $em, HubSelector $hub_select, + HubDistributor $hub_dist, HubFilterLogger $hub_filter_logger, HubFilteringGeoChecker $hub_geofence) + { + // check required parameters and api key + $required_params = [ + 'service_type', + 'cv_id', + // 'batt_id', + 'trade_in', + 'long', + 'lat', + 'warranty', + 'mode_of_payment', + ]; + $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(); + } + + $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')); + + // 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); + + // set more hub criteria fields + $hub_criteria = new HubCriteria(); + $hub_criteria->setPoint($jo->getCoordinates()); + + if ($hub_geofence->isCovered($long, $lat)) + { + // TODO: set this properly, since the other flags + // are on default values. + // if true, set other values for HubCriteria + // error_log('Area is covered by hub filtering'); + $hub_criteria->setJoType($jo->getServiceType()) + ->setPaymentMethod($jo->getModeOfPayment()) + ->setRoundRobin(true); + } + + // add battery to items + $sku = $batt->getSAPCode(); + if (!empty($sku)) + $hub_criteria->addItem($batt->getSAPCode(), 1); + + // find nearest hubs + $nearest_hubs = $hub_select->find($hub_criteria); + + if (!empty($nearest_hubs)) + { + // go through the hub list, find the nearest hub + // with an available rider + //error_log('found nearest hub ' . $nearest_hub->getID()); + foreach ($nearest_hubs as $nearest_hub) + { + $available_riders = $nearest_hub['hub']->getAvailableRiders(); + if (count($available_riders) >= 1) + { + $assigned_rider = null; + if (count($available_riders) == 1) + { + $assigned_rider = $available_riders[0]; + } + else + { + // 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); + } + + $jo->setHub($nearest_hub['hub']); + $jo->setRider($assigned_rider); + $jo->setStatus(JOStatus::ASSIGNED); + $jo->setStatusAutoAssign(AutoAssignStatus::HUB_AND_RIDER_ASSIGNED); + + $assigned_rider->setAvailable(false); + + // update redis hub_jo_count for hub + $hub_dist->incrementJoCountForHub($nearest_hub['hub']); + + // break out of loop + break; + } + else + { + // log hub into hub_filter_log + $hub_filter_logger->logFilteredHub($nearest_hub['hub'], 'no_available_rider'); + // continue to go through list to find hub with an available rider + } + } + } + + $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()); + } + + $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 + ]; + + // check service type + if ($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) + { + $customer = $cv->getCustomer(); + $customer_tags = $customer->getCustomerTagObjects(); + if (!empty($customer_tags)) + { + foreach ($customer_tags as $customer_tag) + { + if ($customer_tag->getID() == $invoice->getUsedCustomerTagId()) + { + // remove associated entity + $customer->removeCustomerTag($customer_tag); + + // log the availment of promo from customer + $created_by = $req->query->get('api_key');; + $cust_id = $jo->getCustomer()->getID(); + $cust_fname = $jo->getCustomer()->getFirstName(); + $cust_lname = $jo->getCustomer()->getLastName(); + $jo_id = $jo->getID(); + $invoice_id = $jo->getInvoice()->getID(); + // TODO: check if we store total price of invoice or just the discounted amount + $amount = $jo->getInvoice()->getTotalPrice(); + $promo_logger->logPromoInfo($created_by, $cust_id, $cust_fname, $cust_lname, $jo_id, + $invoice_id, $amount); + } + } + } + } + + // set data + $res->setData($data); + + return $res->getReturnResponse(); + } + + // TODO: modify for MobileUser + // break this down into smaller functions + // do we still use this? + public function newRequestJobOrder(Request $req, InvoiceGeneratorInterface $ic, GeofenceTracker $geo, + MapTools $map_tools, InventoryManager $im, MQTTClient $mclient, + RiderAssignmentHandlerInterface $rah, PromoLogger $promo_logger, + HubSelector $hub_select, HubDistributor $hub_dist, HubFilterLogger $hub_filter_logger, + HubFilteringGeoChecker $hub_geofence, EntityManagerInterface $em) + { + // check required parameters and api key + $required_params = [ + 'service_type', + 'cv_id', + 'trade_in', + 'long', + 'lat', + 'warranty', + 'mode_of_payment', + ]; + $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'); + // check for 'false' text + if ($advance_order === false || $advance_order === 0 || $advance_order === '0' || $advance_order == 'false') + $flag_advance_order = false; + else + $flag_advance_order = true; + + $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) + ->setStatusAutoAssign(AutoAssignStatus::NOT_ASSIGNED); + + // 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) + { + $hub_criteria = new HubCriteria(); + $hub_criteria->setPoint($jo->getCoordinates()); + + if ($hub_geofence->isCovered($long, $lat)) + { + // if true, set other values for HubCriteria + // TODO: set this properly, since the other flags + // are on default values + // error_log('Area is covered by hub filtering'); + $hub_criteria->setJoType($jo->getServiceType()) + ->setPaymentMethod($jo->getModeOfPayment()) + ->setRoundRobin(true); + } + + // add battery to items + $sku = $batt->getSAPCode(); + if (!empty($sku)) + $hub_criteria->addItem($batt->getSAPCode(), 1); + + // find nearest hubs + $nearest_hubs = $hub_select->find($hub_criteria); + + if (!empty($nearest_hubs)) + { + // go through the hub list, find the nearest hub + // with an available rider + //error_log('found nearest hub ' . $nearest_hub->getID()); + foreach ($nearest_hubs as $nearest_hub) + { + $available_riders = $nearest_hub['hub']->getAvailableRiders(); + if (count($available_riders) >= 1) + { + $assigned_rider = null; + if (count($available_riders) == 1) + { + $assigned_rider = $available_riders[0]; + } + else + { + // 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); + } + + $jo->setHub($nearest_hub['hub']); + $jo->setRider($assigned_rider); + $jo->setStatus(JOStatus::ASSIGNED); + $jo->setStatusAutoAssign(AutoAssignStatus::HUB_AND_RIDER_ASSIGNED); + + $assigned_rider->setAvailable(false); + + // update redis hub_jo_count for hub + $hub_dist->incrementJoCountForHub($nearest_hub['hub']); + + // break out of loop + break; + } + else + { + // log hub into hub_filter_log + $hub_filter_logger->logFilteredHub($nearest_hub['hub'], 'no_available_rider'); + // continue to go through list to find hub with an available rider + } + } + } + } + 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); + $jo->setStatusAutoAssign(AutoAssignStatus::HUB_ASSIGNED); + + if ($date_schedule != null) + $jo->setDateSchedule($date_schedule); + + // update redis hub_jo_count for hub + $hub_dist->incrementJoCountForHub($hub); + } + + $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 + ]; + + // need to check for customer tag/promo + // check service type + if ($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) + { + $customer = $cv->getCustomer(); + $customer_tags = $customer->getCustomerTagObjects(); + if (!empty($customer_tags)) + { + foreach ($customer_tags as $customer_tag) + { + if ($customer_tag->getID() == $invoice->getUsedCustomerTagId()) + { + // remove associated entity + $customer->removeCustomerTag($customer_tag); + + // log the availment of promo from customer + $created_by = $req->query->get('api_key');; + $cust_id = $jo->getCustomer()->getID(); + $cust_fname = $jo->getCustomer()->getFirstName(); + $cust_lname = $jo->getCustomer()->getLastName(); + $jo_id = $jo->getID(); + $invoice_id = $jo->getInvoice()->getID(); + // TODO: check if we store total price of invoice or just the discounted amount + $amount = $jo->getInvoice()->getTotalPrice(); + $promo_logger->logPromoInfo($created_by, $cust_id, $cust_fname, $cust_lname, $jo_id, + $invoice_id, $amount); + } + } + } + } + + // set data + $res->setData($data); + + return $res->getReturnResponse(); + } + + // TODO: modify for MobileUser + public function getEstimate(Request $req, InvoiceGeneratorInterface $ic, EntityManagerInterface $em) + { + // $this->debugRequest($req); + + // check required parameters and api key + $required_params = [ + 'service_type', + 'cv_id', + // 'batt_id', + 'trade_in', + ]; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + // customer + $cust = $this->session->getCustomer(); + if ($cust == null) + { + $res->setError(true) + ->setErrorMessage('No customer information found'); + return $res->getReturnResponse(); + } + + // make invoice criteria + $icrit = new InvoiceCriteria(); + $icrit->setServiceType($req->request->get('service_type')); + + // 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); + + // 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 + $trade_in = $req->request->get('trade_in'); + 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); + + // make invoice json data + $data = [ + 'total_price' => (float) $invoice->getTotalPrice(), + 'vat_ex_price' => (float) $invoice->getVATExclusivePrice(), + 'vat' => (float) $invoice->getVAT(), + 'discount' => (float) $invoice->getDiscount(), + 'trade_in' => (float) $invoice->getTradeIn(), + ]; + $items = $invoice->getItems(); + $items_data = []; + foreach ($items as $item) + { + $my_data = [ + 'title' => $item->getTitle(), + 'qty' => (int) $item->getQuantity() + 0, + 'price' => (float) $item->getPrice() + 0.0, + ]; + + $item_batt = $item->getBattery(); + if ($item_batt != null) + { + $my_data['image_url'] = $this->getBatteryImageURL($req, $item_batt); + } + + $items_data[] = $my_data; + } + + $data['items'] = $items_data; + + // error_log(print_r($data, true)); + + // set data + $res->setData($data); + + return $res->getReturnResponse(); + } + + // TODO: modify for MobileUser + public function getOngoing(Request $req, EntityManagerInterface $em) + { + $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(); + } + + /* + // 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, $em); + + // initialize data + $data = []; + + // no ongoing + if (count($ongoing_jos) <= 0) + { + $data = [ + 'has_ongoing' => false, + ]; + } + else + { + $data = [ + 'has_ongoing' => true, + ]; + } + + $res->setData($data); + + return $res->getReturnResponse(); + } + + // TODO: modify for MobileUser + public function cancelJobOrder(Request $req, MQTTClient $mclient, EntityManagerInterface $em) + { + $required_params = [ + 'jo_id', + 'reason' + ]; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + // get job order + $jo_id = $req->request->get('jo_id'); + $jo = $em->getRepository(JobOrder::class)->find($jo_id); + if ($jo == null) + { + $res->setError(true) + ->setErrorMessage('No job order found'); + return $res->getReturnResponse(); + } + + // get customer + $cust = $this->session->getCustomer(); + if ($cust == null) + { + $res->setError(true) + ->setErrorMessage('No customer information found'); + return $res->getReturnResponse(); + } + + // check that the customer owns the job order + $jo_cust = $jo->getCustomer(); + if ($jo_cust->getID() != $cust->getID()) + { + $res->setError(true) + ->setErrorMessage('Job order was not initiated by customer'); + return $res->getReturnResponse(); + } + + // TODO: check job order status, if it's cancellable + $cancel_reason = $req->request->get('reason'); + + $jo->cancel($cancel_reason); + + // add event log + $event = new JOEvent(); + $event->setDateHappen(new DateTime()) + ->setTypeID(JOEventType::CANCEL) + ->setJobOrder($jo); + $em->persist($event); + + $em->flush(); + + // send mobile app event + $payload = [ + 'event' => 'cancelled', + 'reason' => $cancel_reason, + 'jo_id' => $jo->getID(), + ]; + // $mclient->sendEvent($jo, $payload); + $mclient->sendRiderEvent($jo, $payload); + + $res->setData([]); + + return $res->getReturnResponse(); + } + + // TODO: modify for MobileUser + public function getJOHistory(Request $req, EntityManagerInterface $em) + { + $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 job orders + $all_jo_data = []; + $jos = $cust->getJobOrders(); + foreach ($jos as $jo) + { + $status = $jo->getStatus(); + + $jo_data = [ + 'id' => $jo->getID(), + 'date_create' => $jo->getDateCreate()->format('M d, Y'), + 'service_type' => $jo->getServiceType(), + 'status' => $status, + ]; + + // 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, + ]; + + // rider + $rider = $jo->getRider(); + if ($rider != null) + { + $jo_data['rider'] = $rider->getFullName(); + } + + // 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; + } + + $all_jo_data[] = $jo_data; + } + + // return data + $data = [ + 'job_orders' => $all_jo_data + ]; + $res->setData($data); + + // response + return $res->getReturnResponse(); + } + + // TODO: modify for MobileUser + public function getJOInvoice(Request $req, EntityManagerInterface $em) + { + $required_params = [ + 'jo_id', + ]; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + // get job order + $jo_id = $req->query->get('jo_id'); + $jo = $em->getRepository(JobOrder::class)->find($jo_id); + if ($jo == null) + { + $res->setError(true) + ->setErrorMessage('No job order found'); + return $res->getReturnResponse(); + } + + // get customer + $cust = $this->session->getCustomer(); + if ($cust == null) + { + $res->setError(true) + ->setErrorMessage('No customer information found'); + return $res->getReturnResponse(); + } + + // check that the customer owns the job order + $jo_cust = $jo->getCustomer(); + if ($jo_cust->getID() != $cust->getID()) + { + $res->setError(true) + ->setErrorMessage('Job order was not initiated by customer'); + return $res->getReturnResponse(); + } + + $invoice = $jo->getInvoice(); + + / make invoice json data + $data = [ + 'total_price' => (float) $invoice->getTotalPrice(), + 'vat_ex_price' => (float) $invoice->getVATExclusivePrice(), + 'vat' => (float) $invoice->getVAT(), + 'discount' => (float) $invoice->getDiscount(), + 'trade_in' => (float) $invoice->getTradeIn(), + ]; + $items = $invoice->getItems(); + $items_data = []; + foreach ($items as $item) + { + $my_data = [ + 'title' => $item->getTitle(), + 'qty' => (int) $item->getQuantity() + 0, + 'price' => (float) $item->getPrice() + 0.0, + ]; + + $item_batt = $item->getBattery(); + if ($item_batt != null) + { + $my_data['image_url'] = $this->getBatteryImageURL($req, $item_batt); + } + + $items_data[] = $my_data; + } + + $data['items'] = $items_data; + + // set data + $res->setData($data); + + return $res->getReturnResponse(); + } + + public function locationSupport(Request $req, GeofenceTracker $geo, EntityManagerInterface $em) + { + $required_params = [ + 'longitude', + 'latitude', + ]; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + $long = $req->query->get('longitude'); + $lat = $req->query->get('latitude'); + + // geofence + $is_covered = $geo->isCovered($long, $lat); + + $data = [ + 'longitude' => $long, + 'latitude' => $lat, + 'supported' => $is_covered, + ]; + $res->setData($data); + + return $res->getReturnResponse(); + } + + // TODO: do we make this use the HubCriteria and HubSelector? YES? + public function getNearestHubAndSlots(Request $req, EntityManagerInterface $em, + MapTools $map_tools) + { + $required_params = [ + 'longitude', + 'latitude', + ]; + + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + $coordinates = new Point($req->query->get('longitude'), $req->query->get('latitude')); + $nearest_hub_slots = $this->findAdvanceNearestHubAndSlots($coordinates, $em, $map_tools); + + if (empty($nearest_hub_slots['hub'])) + { + $res->setError(true) + ->setErrorMessage('Thank you for reaching out to us. Due to the General Community Quarantine, our Operations are from 8AM to 6PM only. Please expect a call from us tomorrow and we will assist you with your request. Thank you and stay safe!'); + return $res->getReturnResponse(); + } + + // make hub data + $data = [ + 'hub_id' => $nearest_hub_slots['hub']->getID(), + 'hub_slots' => $nearest_hub_slots['slots'], + ]; + + $res->setData($data); + + return $res->getReturnResponse(); + + } + + public function scheduleOptionStatus(Request $req, EntityManagerInterface $em) + { + // check required parameters and api key + $required_params = []; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + $schedule_choice = true; + + // TODO: remove the time check after ECQ. This will then always return true + // get current time + $current_datetime = new DateTime(); + //$current_datetime = DateTime::createFromFormat('Y-m-d H:i', '2020-04-30 17:01'); + + // get the hour + $hour = $current_datetime->format('G'); + + if (($hour < 8) || ($hour > 16)) + $schedule_choice = false; + + $data = [ + 'display_schedule_choice' => $schedule_choice, + ]; + $res->setData($data); + + return $res->getReturnResponse(); + } + + protected function getOngoingJobOrders($cust, $em) + { + $ongoing_jos = $em->getRepository(JobOrder::class)->findBy([ + 'customer' => $cust, + 'status' => [JOStatus::PENDING, JOStatus::RIDER_ASSIGN, JOStatus::IN_TRANSIT, JOStatus::ASSIGNED, JOStatus::IN_PROGRESS], + ]); + + return $ongoing_jos; + } + + // TODO: what to do with this? listVehicles in CustomerVehicleController als calls this + protected function findWarranty($plate_number, $em) + { + // NOTE: Modify the search for the latest warranty. This seems hacky. + // get latest warranty using plate number + $warranty_results = $em->getRepository(Warranty::class)->findBy(['plate_number' => $plate_number], + ['date_create' => 'desc']); + + $warr = []; + + // check if warranty_results is empty + if (empty($warranty_results)) + { + /* + $res->setError(true) + ->setErrorMessage('No warranty found for plate number'); + return $res->getReturnResponse(); + */ + + return $warr; + } + + // get first entry + $warranty = current($warranty_results); + + // check for null values for battery and date claim and date expire + $batt_model = ''; + $batt_size = ''; + $sap_batt = ''; + $claim_date = ''; + $expiry_date = ''; + + if (!(is_null($warranty->getBatteryModel()))) { + $batt_model = $warranty->getBatteryModel()->getName(); + } + if (!(is_null($warranty->getBatterySize()))) { + $batt_size = $warranty->getBatterySize()->getName(); + } + if (!(is_null($warranty->getSAPBattery()))) { + $sap_batt = $warranty->getSAPBattery()->getID(); + } + if (!(is_null($warranty->getDateClaim()))) { + $claim_date = $warranty->getDateClaim()->format("d M Y"); + } + if (!(is_null($warranty->getDateExpire()))) { + $expiry_date = $warranty->getDateExpire()->format("d M Y"); + } + + $warr[] = [ + 'id' => $warranty->getID(), + 'serial' => $warranty->getSerial(), + 'warranty_class' => $warranty->getWarrantyClass(), + 'plate_number' => $warranty->getPlateNumber(), + 'first_name' => $warranty->getFirstName(), + 'last_name' => $warranty->getLastName(), + 'mobile_number' => $warranty->getMobileNumber(), + 'battery_model' => $batt_model, + 'battery_size' => $batt_size, + 'sap_battery' => $sap_batt, + 'status' => $warranty->getStatus(), + 'date_create' => $warranty->getDateCreate()->format("d M Y g:i A"), + 'date_purchase' => $warranty->getDatePurchase()->format("d M Y"), + 'date_expire' => $expiry_date, + 'date_claim' => $claim_date, + 'claim_from' => $warranty->getClaimedFrom(), + 'is_activated' => $warranty->isActivated() ? 1 : 0, + ]; + + return $warr; + } + + 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; + } + + // TODO: this might become irrelevant if we use HubCriteria (which I think we should, my blooper) + protected function findAdvanceNearestHubAndSlots(Point $coordinates, EntityManagerInterface $em, MapTools $map_tools) + { + // get the nearest 10 hubs + $hub_data = []; + $nearest_hubs_with_distance = []; + $hubs = $map_tools->getClosestOpenHubs($coordinates, 10); + + foreach ($hubs as $hub) + { + $nearest_hubs_with_distance[] = $hub; + // TODO: insert checking for branch code here when inventory manager is up + } + + $nearest = null; + $slot_found = false; + // find the nearest hub + if (!empty($nearest_hubs_with_distance)) + { + foreach ($nearest_hubs_with_distance as $nhd) + { + if (empty($nearest)) + $nearest = $nhd; + else + { + if ($nhd['distance'] < $nearest['distance']) + $nearest = $nhd; + } + } + + // get slots of nearest hub + if ($nearest != null) + { + $hub_slots = $this->getHubRiderSlots($nearest['hub'], $em); + + $hub_data = [ + 'hub' => $nearest['hub'], + 'slots' => $hub_slots, + ]; + } + } + + return $hub_data; + } + + protected function getHubRiderSlots(Hub $hub, EntityManagerInterface $em) + { + // check hub's advance orders for the day + + /* + // get number of advance orders for the next day if request came in before midnight + // or for current day if request came in after midnight + // check request_time + $request_time = time(); + $midnight = strtotime('00:00'); + */ + $start_date = new DateTime(); + $end_date = new DateTime(); + + // to keep things simple, just start on next day regardless of midnight timer + $start_date->add(new DateInterval('P1D')); + $end_date->add(new DateInterval('P3D')); + + /* + if ($request_time < $midnight) + { + // add +1 to start date to get the next day + // add +3 to date to end date to get the advance orders for the next three days + $start_date->add(new DateInterval('P1D')); + $end_date->add(new DateInterval('P1D')); + } + $end_date->add(new DateInterval('P2D')); + */ + + // set time bounds for the start and end date + $start_date->setTime(0, 1); + $end_date->setTime(23, 59); + + // NOTE: get advance orders via query + // get JOs assigned to hub that are advance orders and scheduled for the next three days with + // for hub assignment status + $query = $em->createQuery('select jo from App\Entity\JobOrder jo where jo.hub = :hub and jo.flag_advance = true and + jo.date_schedule >= :date_start and jo.date_schedule <= :date_end and jo.status != :status_cancelled + and jo.status != :status_fulfilled'); + $jos_advance_orders = $query->setParameters([ + 'hub' => $hub, + 'date_start' => $start_date, + 'date_end' => $end_date, + 'status_cancelled' => JOStatus::CANCELLED, + 'status_fulfilled' => JOStatus::FULFILLED, + ]) + ->getResult(); + // check request_time + // define slots + $slots = [ + '08_09' => '8:00 AM', + '09_10' => '9:00 AM', + '10_11' => '10:00 AM', + '11_12' => '11:00 AM', + '12_13' => '12:00 PM', + '13_14' => '1:00 PM', + '14_15' => '2:00 PM', + '15_16' => '3:00 PM', + '16_17' => '4:00 PM', + ]; + + // get the dates for the next three days + $first_date = $start_date->format('Y-m-d'); + $second_date = $start_date->add(new DateInterval('P1D')); + $sec_date = $second_date->format('Y-m-d'); + $third_date = $end_date->format('Y-m-d'); + + // define days + $days = [ + $first_date => $first_date, + $sec_date => $sec_date, + $third_date => $third_date, + ]; + + // initialize hub rider slots + $hub_rider_slots = []; + foreach ($days as $day) + { + foreach ($slots as $slot_key => $slot) + { + $hub_rider_slots[$day][$slot_key] = $hub->getRiderSlots(); + } + } + + // check each JO's date_schedule, decrement rider_slots if date schedule falls in that slot + foreach ($jos_advance_orders as $jo) + { + // get date key + $date_sched = $jo->getDateSchedule(); + $date_string = $date_sched->format('Y-m-d'); + $hour = $date_sched->format('H'); + $slot_id = sprintf('%02d_%02d', $hour, $hour + 1); + + error_log("SLOT - $date_string - $slot_id"); + + // decrement rider slot + if (isset($hub_rider_slots[$date_string][$slot_id])) + $hub_rider_slots[$date_string][$slot_id]--; + + // check if it goes through next slot (10 min allowance) + $mins = $date_sched->format('i'); + if ($mins > 10) + { + $next_slot_id = sprintf('%02d_%02d', $hour + 1, $hour + 2); + error_log("NEXT SLOT - $date_string - $next_slot_id"); + // decrement rider slot + if (isset($hub_rider_slots[$date_string][$next_slot_id])) + $hub_rider_slots[$date_string][$next_slot_id]--; + + } + } + + error_log(print_r($hub_rider_slots, true)); + + $hub_slots = $this->generateHubSlots($hub_rider_slots, $slots); + + return $hub_slots; + } + + protected function generateHubSlots($rider_slots, $slots) + { + $data = []; + foreach ($rider_slots as $day_id => $rslot) + { + $data[$day_id] = []; + + foreach ($rslot as $slot_id => $avail_slots) + { + $slot_data = [ + 'id' => $slot_id, + 'label' => $slots[$slot_id], + 'available' => true, + ]; + + // mark unavailable ones + if ($avail_slots <= 0) + $slot_data['available'] = false; + + // add to day data + $data[$day_id][] = $slot_data; + } + } + + return $data; + } + + 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; + } + + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkParamsAndKey(Request $req, $em, $params) + { + // TODO: depends on what we decide to return + // returns APIResult object + $res = new APIResult(); + + // check for api_key in query string + $api_key = $req->query->get('api_key'); + if (empty($api_key)) + { + $res->setError(true) + ->setErrorMessage('Missing API key'); + return $res; + } + + // check missing parameters + $missing = $this->checkMissingParameters($req, $params); + if (count($missing) > 0) + { + $miss_string = implode(', ', $missing); + $res->setError(true) + ->setErrorMessage('Missing parameter(s): ' . $miss_string); + return $res; + } + + // check api key + $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); + if ($mobile_user == null) + { + $res->setError(true) + ->setErrorMessage('Invalid API Key'); + return $res; + } + + // store session + $this->session = $sess; + + return $res; + } + + // TODO: this might not be needed if we use APIController's checkRequiredParameters + // or we put this into a service? + protected function checkMissingParameters(Request $req, $params = []) + { + $missing = []; + + // check if parameters are there + foreach ($params as $param) + { + if ($req->getMethod() == 'GET') + { + $check = $req->query->get($param); + if (empty($check)) + $missing[] = $param; + } + else if ($req->getMethod() == 'POST') + { + $check = $req->request->get($param); + if (empty($check)) + $missing[] = $param; + } + else + return $params; + } + + return $missing; + } + + // TODO: type hint entity manager + // TODO: since we broke the functions into separate files, we need + // to figure out how to make this accessible to all ResqAPI controllers + protected function checkAPIKey($em, $api_key) + { + // find the api key (session id) + // TODO: user validation needs to be changed + $m_user = $em->getRepository(MobileUser::class)->find($api_key); + if ($m_user == null) + return null; + + return $m_user; + } +} -- 2.43.5 From 35b228ef0c3c1292ac6810cb8f3d22e2399d459d Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 28 Jun 2021 04:49:00 +0000 Subject: [PATCH 08/42] Fix register for migration. #591 --- config/api_acl.yaml | 6 +++++ config/packages/security.yaml | 8 ++++++ src/Controller/ResqAPI/CustomerController.php | 25 ++++++------------- src/Controller/ResqAPI/JobOrderController.php | 2 +- src/Entity/MobileUser.php | 6 +++++ 5 files changed, 29 insertions(+), 18 deletions(-) diff --git a/config/api_acl.yaml b/config/api_acl.yaml index 2e5bbdd3..54363f6f 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -67,3 +67,9 @@ access_keys: acls: - id: dealer.list label: List + + - id: mobile_customer + label: Mobile Customer + acls: + - id: mobile_customer.register + label: Register Mobile Customer diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 4339eba4..bae83a76 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -46,6 +46,14 @@ security: provider: api_key_user_provider user_checker: Catalyst\AuthBundle\Service\UserChecker + mobile_api: + pattern: ^\/resqapi\/ + stateless: true + simple_preauth: + authenticator: Catalyst\APIBundle\Security\APIKeyAuthenticator + provider: api_key_user_provider + user_checker: Catalyst\AuthBundle\Service\UserChecker + main: provider: user_provider form_login: diff --git a/src/Controller/ResqAPI/CustomerController.php b/src/Controller/ResqAPI/CustomerController.php index 378e0e57..5a934f39 100644 --- a/src/Controller/ResqAPI/CustomerController.php +++ b/src/Controller/ResqAPI/CustomerController.php @@ -10,10 +10,7 @@ use Doctrine\ORM\Query; use Doctrine\ORM\EntityManagerInterface; use Catalyst\APIBundle\Controller\APIController; -// TODO: what do we use for response? APIResponse or APIResult? -// APIResult is what is used by APIController. APIResponse is what is used by CAPI use Catalyst\APIBundle\Response\APIResponse; -use App\Ramcar\APIResult; use App\Entity\MobileUser; @@ -33,8 +30,6 @@ class CustomerController extends APIController public function register(Request $req, EntityManagerInterface $em) { // no need for access for register - - $res = new APIResult(); // confirm parameters $required_params = [ 'phone_model', @@ -43,17 +38,12 @@ class CustomerController extends APIController 'phone_id' ]; - // TODO: APIController has a function called checkRequiredParameters that does the same thing - // as checkMissingParameters. Maybe we can use that? - $missing = $this->checkMissingParameters($req, $required_params); - if (count($missing) > 0) - { - $params = implode(', ', $missing); - $res->setError(true) - ->setErrorMessage('Missing parameter(s): ' . $params); - return $res->getReturnResponse(); - } + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $error_message); + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); // retry until we get a unique id while (true) { @@ -64,7 +54,8 @@ class CustomerController extends APIController $mobile_user->setPhoneModel($req->request->get('phone_model')) ->setOSType($req->request->get('os_type')) ->setOSVersion($req->request->get('os_version')) - ->setPhoneID($req->request->get('phone_id')); + ->setPhoneID($req->request->get('phone_id')) + ->setCapiUserId($user_id); // reopen in case we get an exception if (!$em->isOpen()) @@ -99,7 +90,7 @@ class CustomerController extends APIController ]; // response - return $res->getReturnResponse(); + return new APIResponse(true, 'Mobile user created.', $data); } public function confirmNumber(RisingTideGateway $rt, Request $req, EntityManagerInterface $em) diff --git a/src/Controller/ResqAPI/JobOrderController.php b/src/Controller/ResqAPI/JobOrderController.php index 618e691a..1035c986 100644 --- a/src/Controller/ResqAPI/JobOrderController.php +++ b/src/Controller/ResqAPI/JobOrderController.php @@ -1196,7 +1196,7 @@ class JobOrderController extends APIController $invoice = $jo->getInvoice(); - / make invoice json data + // make invoice json data $data = [ 'total_price' => (float) $invoice->getTotalPrice(), 'vat_ex_price' => (float) $invoice->getVATExclusivePrice(), diff --git a/src/Entity/MobileUser.php b/src/Entity/MobileUser.php index 0830ae89..127ccb47 100644 --- a/src/Entity/MobileUser.php +++ b/src/Entity/MobileUser.php @@ -152,6 +152,12 @@ class MobileUser return $this->os_type; } + public function setOSVersion($version) + { + $this->os_version = $version; + return $this; + } + public function getOSVersion() { return $this->os_version; -- 2.43.5 From 88c49582e2d2ef9668aec80f3bb358bc0695b9cc Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 30 Jun 2021 08:27:07 +0000 Subject: [PATCH 09/42] Fix error response for register. #591 --- src/Controller/ResqAPI/CustomerController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controller/ResqAPI/CustomerController.php b/src/Controller/ResqAPI/CustomerController.php index 5a934f39..464cb9a7 100644 --- a/src/Controller/ResqAPI/CustomerController.php +++ b/src/Controller/ResqAPI/CustomerController.php @@ -40,7 +40,7 @@ class CustomerController extends APIController $msg = $this->checkRequiredParameters($req, $required_params); if ($msg) - return new APIResponse(false, $error_message); + return new APIResponse(false, $msg); // get capi user to link to mobile user $user_id = $this->getUser()->getID(); -- 2.43.5 From edaa514f57aaab3f33ca1050a4821b1ec0abe33b Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 1 Jul 2021 08:26:36 +0000 Subject: [PATCH 10/42] Add index for capi user ID. Add checking if user already registered. #591 --- src/Controller/ResqAPI/CustomerController.php | 18 +++++++++++++++--- src/Entity/MobileUser.php | 5 ++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/Controller/ResqAPI/CustomerController.php b/src/Controller/ResqAPI/CustomerController.php index 464cb9a7..0cbdd37d 100644 --- a/src/Controller/ResqAPI/CustomerController.php +++ b/src/Controller/ResqAPI/CustomerController.php @@ -44,6 +44,12 @@ class CustomerController extends APIController // get capi user to link to mobile user $user_id = $this->getUser()->getID(); + + // check if capi user already has a mobile user + $mobile_user = $this->findMobileUser($user_id, $em); + if ($mobile_user != null) + return new APIResponse(false, 'User already registered'); + // retry until we get a unique id while (true) { @@ -82,9 +88,8 @@ class CustomerController extends APIController } // return data - // need to make sure the names returned to app are the same - // so we still use session_id name - // TODO: depending on what data type we return, this might need changes + // TODO: do we need to return the same names as before? + // right now, still usind the old names so we use session_id name $data = [ 'session_id' => $mobile_user->getID() ]; @@ -468,6 +473,13 @@ class CustomerController extends APIController return $res->getReturnResponse(); } + protected function findMobileUser($user_id, $em) + { + $mobile_user = $em->getRepository(MobileUser::class)->findBy(['capi_user_id' => $user_id]); + + return $mobile_user; + } + // TODO: this might not be needed if we use APIController's checkRequiredParameters // or we put this into a service? protected function checkMissingParameters(Request $req, $params = []) diff --git a/src/Entity/MobileUser.php b/src/Entity/MobileUser.php index 127ccb47..0e5e80e0 100644 --- a/src/Entity/MobileUser.php +++ b/src/Entity/MobileUser.php @@ -10,7 +10,10 @@ use DateTime; /** * @ORM\Entity - * @ORM\Table(name="mobile_user") + * @ORM\Table( + * name="mobile_user", + * indexes={@ORM\Index(name="capi_user_idx", columns={"capi_user_id"})} + * ) */ class MobileUser { -- 2.43.5 From f998187e8e75433abc850eb1516728504cdb8d64 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 1 Jul 2021 09:28:25 +0000 Subject: [PATCH 11/42] Modify confirmNumber and validateCode. #591 --- config/api_acl.yaml | 12 +- src/Controller/ResqAPI/CustomerController.php | 128 +++++++++++++----- 2 files changed, 99 insertions(+), 41 deletions(-) diff --git a/config/api_acl.yaml b/config/api_acl.yaml index 54363f6f..b104892c 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -68,8 +68,12 @@ access_keys: - id: dealer.list label: List - - id: mobile_customer - label: Mobile Customer + - id: mobile_user + label: Mobile User acls: - - id: mobile_customer.register - label: Register Mobile Customer + - id: mobile_user.register + label: Register Mobile User + - id: mobile_user.confirm.number + label: Confirm Number + - id: mobile_user.validate.code + label: Validate Code diff --git a/src/Controller/ResqAPI/CustomerController.php b/src/Controller/ResqAPI/CustomerController.php index 0cbdd37d..ceb66e17 100644 --- a/src/Controller/ResqAPI/CustomerController.php +++ b/src/Controller/ResqAPI/CustomerController.php @@ -13,11 +13,14 @@ use Catalyst\APIBundle\Controller\APIController; use Catalyst\APIBundle\Response\APIResponse; use App\Entity\MobileUser; +use App\Entity\Customer; use App\Service\RisingTideGateway; use Catalyst\APIBundle\Access\Generator as ACLGenerator; +use DateTime; + class CustomerController extends APIController { protected $acl_gen; @@ -29,7 +32,8 @@ class CustomerController extends APIController public function register(Request $req, EntityManagerInterface $em) { - // no need for access for register + $this->denyAccessUnlessGranted('mobile_user.register', null, 'No access.'); + // confirm parameters $required_params = [ 'phone_model', @@ -38,6 +42,7 @@ class CustomerController extends APIController 'phone_id' ]; + // check required parameters $msg = $this->checkRequiredParameters($req, $required_params); if ($msg) return new APIResponse(false, $msg); @@ -100,47 +105,54 @@ class CustomerController extends APIController public function confirmNumber(RisingTideGateway $rt, Request $req, EntityManagerInterface $em) { + $this->denyAccessUnlessGranted('mobile_user.confirm.number', null, 'No access.'); + // check parameters $required_params = [ 'phone_number', ]; - // check required parameters and api key - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + // check required parameters + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get mobile user + $user_id = $this->getUser()->getID(); + $mobile_user = $this->findMobileUser($user_id, $em); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); // phone number $phone_number = $req->request->get('phone_number'); // get otp_mode from .env $dotenv = new Dotenv(); - $dotenv->loadEnv(__DIR__.'/../../.env'); + $dotenv->loadEnv(__DIR__.'/../../../.env'); $otp_mode = $_ENV['OTP_MODE']; // check for hardcoded phone number for app store testing - if ($phone_number == '639991112233') + if ($phone_number == '9221111111') { $code = '123456'; - // TODO: mobile session no longer exists, use mobile_user - $this->session->setConfirmCode($code) + $mobile_user->setConfirmCode($code) ->setPhoneNumber($phone_number); $em->flush(); - return $res->getReturnResponse(); + return new APIResponse(true, 'Number confirmed.'); } // check if otp_mode is test if ($otp_mode == 'test') { $code = '123456'; - // TODO: mobile session no longer exists, use mobile_user - $this->session->setConfirmCode($code) + $mobile_user->setConfirmCode($code) ->setPhoneNumber($phone_number); $em->flush(); - return $res->getReturnResponse(); + return new APIResponse(true, 'Number confirmed.'); } // TODO: spam protection @@ -149,8 +161,7 @@ class CustomerController extends APIController // generate code and save $code = $this->generateConfirmCode(); - // TODO: mobile session no longer exists, use mobile_user - $this->session->setConfirmCode($code) + $mobile_user->setConfirmCode($code) ->setPhoneNumber($phone_number); $em->flush(); @@ -161,58 +172,61 @@ class CustomerController extends APIController } // response - return $res->getReturnResponse(); + return new APIResponse(true, 'Number confirmed.'); } - // TODO: needs to be modified for mobile user public function validateCode(Request $req, EntityManagerInterface $em) { + $this->denyAccessUnlessGranted('mobile_user.validate.code', null, 'No access.'); + // check parameters $required_params = [ 'code', ]; - // check required parameters and api key - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + // check required parameters + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get mobile user + $user_id = $this->getUser()->getID(); + $mobile_user = $this->findMobileUser($user_id, $em); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); // code is wrong $code = $req->request->get('code'); - if ($this->session->getConfirmCode() != $code) - { - $res->setError(true) - ->setErrorMessage('Wrong confirm code'); - return $res->getReturnResponse(); - } + if ($mobile_user->getConfirmCode() != $code) + return new APIResponse(false, 'Wrong confirm code'); // set confirm date $date = new DateTime(); - $this->session->setDateConfirmed($date) + $mobile_user->setDateConfirmed($date) ->setConfirmed(); - // TODO: check if we have the number registered before and merge - $dupe_sess = $this->findNumberSession($this->session->getPhoneNumber()); - if ($dupe_sess != null) + $dupe_user = $this->findNumberMobileUser($mobile_user->getPhoneNumber(), $em); + if ($dupe_user != null) { - $dupe_cust = $dupe_sess->getCustomer(); - $this->session->setCustomer($dupe_cust); + $dupe_cust = $dupe_user->getCustomer(); + $mobile_user->setCustomer($dupe_cust); } // TODO: check if mobile matches mobile of customer - $customer = $this->findCustomerByNumber($this->session->getPhoneNumber()); + $customer = $this->findCustomerByNumber($mobile_user->getPhoneNumber(), $em); if ($customer != null) { // TODO: if there is a dupe_sess, do we need to check if // dupe_cust is the same as the customer we found? - $this->session->setCustomer($customer); + $mobile_user->setCustomer($customer); } $em->flush(); // response - return $res->getReturnResponse(); + return new APIResponse(true, 'Code validated'); } // TODO: needs to be modified for mobile user @@ -475,11 +489,51 @@ class CustomerController extends APIController protected function findMobileUser($user_id, $em) { - $mobile_user = $em->getRepository(MobileUser::class)->findBy(['capi_user_id' => $user_id]); + $mobile_user = $em->getRepository(MobileUser::class)->findOneBy(['capi_user_id' => $user_id]); return $mobile_user; } + // TODO: find session customer by phone number + protected function findNumberMobileUser($number, $em) + { + $query = $em->getRepository(MobileUser::class)->createQueryBuilder('s') + ->where('s.phone_number = :number') + ->andWhere('s.customer is not null') + ->andWhere('s.confirm_flag = 1') + ->setParameter('number', $number) + ->setMaxResults(1) + ->getQuery(); + + // we just need one + $res = $query->getOneOrNullResult(); + + return $res; + } + + protected function findCustomerByNumber($number, $em) + { + $customers = $em->getRepository(Customer::class)->findBy(['phone_mobile' => $number]); + + // find the customer with the most number of cars + $car_count = 0; + $cust = null; + + foreach($customers as $customer) + { + $vehicles = $customer->getVehicles(); + if (count($vehicles) > $car_count) + { + $car_count = count($vehicles); + + // "save" customer object + $cust = $customer; + } + } + + return $cust; + } + // TODO: this might not be needed if we use APIController's checkRequiredParameters // or we put this into a service? protected function checkMissingParameters(Request $req, $params = []) -- 2.43.5 From 6d42f1dcc55e2d1e8178334770b5c8e7a8b1b429 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 1 Jul 2021 10:29:45 +0000 Subject: [PATCH 12/42] Fix CustomerController for CAPI. #591 --- config/api_acl.yaml | 14 + config/routes/resqapi.yaml | 2 +- src/Controller/ResqAPI/CustomerController.php | 263 ++++++++++-------- 3 files changed, 155 insertions(+), 124 deletions(-) diff --git a/config/api_acl.yaml b/config/api_acl.yaml index b104892c..5984f7d4 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -77,3 +77,17 @@ access_keys: label: Confirm Number - id: mobile_user.validate.code label: Validate Code + - id: mobile_user.get.info + label: Get Customer Info + - id: mobile_user.update.info + label: Update Customer Info + - id: mobile_user.get.status + label: Get Status + - id: mobile_user.resend.code + label: Resend Code + - id: mobile_user.version.check + label: Version Check + - id: mobile_user.update.deviceid + label: Update Device ID + - id: mobile_user.privacy.settings + label: Privacy Settings diff --git a/config/routes/resqapi.yaml b/config/routes/resqapi.yaml index bc92a595..b2edb7f8 100644 --- a/config/routes/resqapi.yaml +++ b/config/routes/resqapi.yaml @@ -39,7 +39,7 @@ resqapi_resend_code: resqapi_version_check: path: /resqapi/version_check controller: App\Controller\ResqAPI\CustomerController::versionCheck - methods: [GET] + methods: [POST] resqapi_device_id: path: /resqapi/device_id diff --git a/src/Controller/ResqAPI/CustomerController.php b/src/Controller/ResqAPI/CustomerController.php index ceb66e17..f6f8e5a9 100644 --- a/src/Controller/ResqAPI/CustomerController.php +++ b/src/Controller/ResqAPI/CustomerController.php @@ -14,9 +14,12 @@ use Catalyst\APIBundle\Response\APIResponse; use App\Entity\MobileUser; use App\Entity\Customer; +use App\Entity\PrivacyPolicy; use App\Service\RisingTideGateway; +use App\Ramcar\CustomerSource; + use Catalyst\APIBundle\Access\Generator as ACLGenerator; use DateTime; @@ -47,11 +50,8 @@ class CustomerController extends APIController if ($msg) return new APIResponse(false, $msg); - // get capi user to link to mobile user - $user_id = $this->getUser()->getID(); - // check if capi user already has a mobile user - $mobile_user = $this->findMobileUser($user_id, $em); + $mobile_user = $this->findMobileUser($em); if ($mobile_user != null) return new APIResponse(false, 'User already registered'); @@ -118,8 +118,7 @@ class CustomerController extends APIController return new APIResponse(false, $msg); // get mobile user - $user_id = $this->getUser()->getID(); - $mobile_user = $this->findMobileUser($user_id, $em); + $mobile_user = $this->findMobileUser($em); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -134,7 +133,7 @@ class CustomerController extends APIController $otp_mode = $_ENV['OTP_MODE']; // check for hardcoded phone number for app store testing - if ($phone_number == '9221111111') + if ($phone_number == '639221111111') { $code = '123456'; $mobile_user->setConfirmCode($code) @@ -190,8 +189,7 @@ class CustomerController extends APIController return new APIResponse(false, $msg); // get mobile user - $user_id = $this->getUser()->getID(); - $mobile_user = $this->findMobileUser($user_id, $em); + $mobile_user = $this->findMobileUser($em); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -229,17 +227,18 @@ class CustomerController extends APIController return new APIResponse(true, 'Code validated'); } - // TODO: needs to be modified for mobile user public function getInfo(Request $req, EntityManagerInterface $em) { - // check required parameters and api key - $required_params = []; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $this->denyAccessUnlessGranted('mobile_user.get.info', null, 'No access.'); + + // get mobile user + $mobile_user = $this->findMobileUser($em); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); // if no customer found - $cust = $this->session->getCustomer(); + $cust = $mobile_user->getCustomer(); if ($cust == null) { $data = [ @@ -248,9 +247,8 @@ class CustomerController extends APIController 'priv_third_party' => (bool) false, 'priv_promo' => (bool) false, ]; - $res->setData($data); - return $res->getReturnResponse(); + return new APIResponse(true, 'No customer info found', $data); } // send back customer details @@ -260,28 +258,36 @@ class CustomerController extends APIController 'priv_third_party' => (bool) $cust->getPrivacyThirdParty(), 'priv_promo' => (bool) $cust->getPrivacyPromo(), ]; - $res->setData($data); - return $res->getReturnResponse(); + return new APIResponse(true, 'Customer info found', $data); } - // TODO: needs to be modified for mobile user public function updateInfo(Request $req, EntityManagerInterface $em) { - // check required parameters and api key + $this->denyAccessUnlessGranted('mobile_user.update.info', null, 'No access.'); + + // check required parameters $required_params = [ 'first_name', 'last_name', ]; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); - $cust = $this->updateCustomerInfo($req, $em); + // check required parameters + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get mobile user + $mobile_user = $this->findMobileUser($em); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); + + $cust = $this->updateCustomerInfo($req, $em, $mobile_user); // get privacy policy for mobile $dotenv = new Dotenv(); - $dotenv->loadEnv(__DIR__.'/../../.env'); + $dotenv->loadEnv(__DIR__.'/../../../.env'); $policy_mobile_id = $_ENV['POLICY_MOBILE']; @@ -295,80 +301,73 @@ class CustomerController extends APIController $em->flush(); - return $res->getReturnResponse(); + return new APIResponse(true, 'Customer info updated'); } - // TODO: needs to be modified for mobile user public function getStatus(Request $req, EntityManagerInterface $em) { - // check required parameters and api key - $required_params = []; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $this->denyAccessUnlessGranted('mobile_user.get.status', null, 'No access.'); + + // get mobile user + $mobile_user = $this->findMobileUser($em); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); // set data $data = []; - if ($this->session->isConfirmed()) + if ($mobile_user->isConfirmed()) $data['status'] = 'confirmed'; else $data['status'] = 'unconfirmed'; - $res->setData($data); - return $res->getReturnResponse(); + return new APIResponse(true, 'Customer status', $data); } - // TODO: needs to be modified for mobile user public function resendCode(Request $req, RisingTideGateway $rt, EntityManagerInterface $em) { - $required_params = []; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $this->denyAccessUnlessGranted('mobile_user.resend.code', null, 'No access.'); + + // get mobile user + $mobile_user = $this->findMobileUser($em); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); // already confirmed - if ($this->session->isConfirmed()) - { - $res->setError(true) - ->setErrorMessage('User is already confirmed.'); - return $res->getReturnResponse(); - } + if ($mobile_user->isConfirmed()) + return new APIResponse(true, 'User is already confirmed'); // have sent code before - if ($this->session->getDateCodeSent() != null) - { - $res->setError(true) - ->setErrorMessage('Can only send confirm code every 5 mins.'); - return $res->getReturnResponse(); - } - + if ($mobile_session->getDateCodeSent() != null) + return new APIResponse(true, 'Can only send confirm code every 5 mins'); // TODO: send via sms - $phone_number = $this->session->getPhoneNumber(); - $code = $this->session->getConfirmCode(); + $phone_number = $mobile_user->getPhoneNumber(); + $code = $mobile_user->getConfirmCode(); $this->sendConfirmationCode($rt, $phone_number, $code); - - return $res->getReturnResponse(); + return new APIResponse(true, 'Code re-sent'); } - // TODO: modify the return or the result if we change what we return - public function versionCheck(Request $req) + public function versionCheck(Request $req, EntityManagerInterface $em) { - $res = new APIResult(); + $this->denyAccessUnlessGranted('mobile_user.version.check', null, 'No access.'); $required_params = [ 'version', ]; - $missing = $this->checkMissingParameters($req, $required_params); - if (count($missing) > 0) - { - $params = implode(', ', $missing); - $res->setError(true) - ->setErrorMessage('Missing parameter(s): ' . $params); - return $res->getReturnResponse(); - } + // check required parameters + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get mobile user + $mobile_user = $this->findMobileUser($em); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); $need_update = false; $msg = 'Version is up to date.'; @@ -381,11 +380,7 @@ class CustomerController extends APIController $app_v = explode('.', $app_version); if ($api_v[0] < $app_v[0]) - { - $res->setError(true) - ->setErrorMessage('Invalid application version: ' . $app_version); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'Invalid application version: ' . $app_version); if ($api_v[0] > $app_v[0]) { @@ -399,49 +394,61 @@ class CustomerController extends APIController 'message' => $msg, ]; - $res->setData($data); - - return $res->getReturnResponse(); + return new APIResponse(true, 'Version checked', $data); } - // TODO: needs to be modified for mobile user public function updateDeviceID(Request $req, EntityManagerInterface $em) { + $this->denyAccessUnlessGranted('mobile_user.update.deviceid', null, 'No access.'); + $required_params = [ 'device_id', ]; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + + // check required parameters + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get mobile user + $mobile_user = $this->findMobileUser($em); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); $device_id = $req->request->get('device_id'); - $this->session->setDevicePushID($device_id); + $mobile_user->setDevicePushID($device_id); $em->flush(); // response - return $res->getReturnResponse(); + return new APIResponse(true, 'Device ID updated'); } - // TODO: needs to be modified for mobile user public function privacySettings(Request $req, EntityManagerInterface $em) { + $this->denyAccessUnlessGranted('mobile_user.privacy.settings', null, 'No access.'); + $required_params = [ 'priv_third_party', // 'priv_promo', ]; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + + // check required parameters + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get mobile user + $mobile_user = $this->findMobileUser($em); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); // get customer - $cust = $this->session->getCustomer(); + $cust = $mobile_user->getCustomer(); if ($cust == null) - { - $res->setError(true) - ->setErrorMessage('No customer information found'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'No customer information found'); // set privacy settings $priv_promo = $req->request->get('priv_promo', false); @@ -451,7 +458,7 @@ class CustomerController extends APIController // get the policy ids from .env $dotenv = new Dotenv(); - $dotenv->loadEnv(__DIR__.'/../../.env'); + $dotenv->loadEnv(__DIR__.'/../../../.env'); $policy_promo_id = $_ENV['POLICY_PROMO']; $policy_third_party_id = $_ENV['POLICY_THIRD_PARTY']; @@ -484,11 +491,13 @@ class CustomerController extends APIController $em->flush(); - return $res->getReturnResponse(); + return new APIResponse(true, 'Privacy policy settings set'); } - protected function findMobileUser($user_id, $em) + protected function findMobileUser($em) { + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); $mobile_user = $em->getRepository(MobileUser::class)->findOneBy(['capi_user_id' => $user_id]); return $mobile_user; @@ -534,6 +543,40 @@ class CustomerController extends APIController return $cust; } + protected function updateCustomerInfo($req, $em, $mobile_user) + { + // create new customer if it's not there + $cust = $mobile_user->getCustomer(); + if ($cust == null) + { + $cust = new Customer(); + + // set customer source + $cust->setCreateSource(CustomerSource::MOBILE); + $em->persist($cust); + + $mobile_user->setCustomer($cust); + } + + $cust->setFirstName($req->request->get('first_name')) + ->setLastName($req->request->get('last_name')) + ->setEmail($req->request->get('email', '')) + ->setConfirmed($mobile_user->isConfirmed()); + + // update mobile phone of customer + $cust->setPhoneMobile(substr($mobile_user->getPhoneNumber(), 2)); + + return $cust; + } + + protected function sendConfirmationCode(RisingTideGateway $rt, $phone_number, $code) + { + // send sms to number + $message = "Your Resq confirmation code is $code."; + $rt->sendSMS($phone_number, 'MOTOLITE', $message); + } + + // TODO: this might not be needed if we use APIController's checkRequiredParameters // or we put this into a service? protected function checkMissingParameters(Request $req, $params = []) @@ -617,30 +660,4 @@ class CustomerController extends APIController return $m_user; } - - // TODO: needs to be modified for mobile user - protected function updateCustomerInfo($req, $em) - { - // create new customer if it's not there - $cust = $this->session->getCustomer(); - if ($cust == null) - { - $cust = new Customer(); - $em->persist($cust); - - $this->session->setCustomer($cust); - } - - $cust->setFirstName($req->request->get('first_name')) - ->setLastName($req->request->get('last_name')) - ->setEmail($req->request->get('email', '')) - ->setConfirmed($this->session->isConfirmed()); - - // update mobile phone of customer - $cust->setPhoneMobile(substr($this->session->getPhoneNumber(), 2)); - - return $cust; - } - - } -- 2.43.5 From 89a0acf380b2a8beda118ecb1acc584f7c9fc5b1 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 5 Jul 2021 07:50:43 +0000 Subject: [PATCH 13/42] Add service for mobile API common functions. Modify VehicleController. #591 --- config/api_acl.yaml | 12 +- config/services.yaml | 5 + src/Controller/ResqAPI/CustomerController.php | 82 ++++++---- src/Controller/ResqAPI/VehicleController.php | 146 +++++------------- src/Service/MobileAPIHandler.php | 26 ++++ 5 files changed, 134 insertions(+), 137 deletions(-) create mode 100644 src/Service/MobileAPIHandler.php diff --git a/config/api_acl.yaml b/config/api_acl.yaml index 5984f7d4..bae91221 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -69,7 +69,7 @@ access_keys: label: List - id: mobile_user - label: Mobile User + label: Mobile User Access acls: - id: mobile_user.register label: Register Mobile User @@ -91,3 +91,13 @@ access_keys: label: Update Device ID - id: mobile_user.privacy.settings label: Privacy Settings + - id: mobile_vmanufacturer + label: Mobile Vehicle Manufacturer Access + acls: + - id: mobile_vmanufacturer.list + label: List Vehicle Manufacturers + - id: mobile_vehicle + label: Mobile Vehicle Make Access + acls: + - id: mobile_vehicle.list + label: List Vehicle Makes diff --git a/config/services.yaml b/config/services.yaml index c4da052b..41bd65ab 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -299,3 +299,8 @@ services: App\Service\HubFilteringGeoChecker: arguments: $geofence_flag: "%env(HUB_GEOFENCE_ENABLE)%" + + # mobile api handler + App\Service\MobileAPIHandler: + arguments: + $em: "@doctrine.orm.entity_manager" diff --git a/src/Controller/ResqAPI/CustomerController.php b/src/Controller/ResqAPI/CustomerController.php index f6f8e5a9..215daf01 100644 --- a/src/Controller/ResqAPI/CustomerController.php +++ b/src/Controller/ResqAPI/CustomerController.php @@ -17,6 +17,7 @@ use App\Entity\Customer; use App\Entity\PrivacyPolicy; use App\Service\RisingTideGateway; +use App\Service\MobileAPIHandler; use App\Ramcar\CustomerSource; @@ -33,7 +34,7 @@ class CustomerController extends APIController $this->acl_gen = $acl_gen; } - public function register(Request $req, EntityManagerInterface $em) + public function register(Request $req, EntityManagerInterface $em, MobileAPIHandler $mah) { $this->denyAccessUnlessGranted('mobile_user.register', null, 'No access.'); @@ -50,8 +51,11 @@ class CustomerController extends APIController if ($msg) return new APIResponse(false, $msg); + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + // check if capi user already has a mobile user - $mobile_user = $this->findMobileUser($em); + $mobile_user = $mah->findMobileUser($em,$user_id); if ($mobile_user != null) return new APIResponse(false, 'User already registered'); @@ -103,7 +107,8 @@ class CustomerController extends APIController return new APIResponse(true, 'Mobile user created.', $data); } - public function confirmNumber(RisingTideGateway $rt, Request $req, EntityManagerInterface $em) + public function confirmNumber(RisingTideGateway $rt, Request $req, EntityManagerInterface $em, + MobileAPIHandler $mah) { $this->denyAccessUnlessGranted('mobile_user.confirm.number', null, 'No access.'); @@ -117,8 +122,11 @@ class CustomerController extends APIController if ($msg) return new APIResponse(false, $msg); + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + // get mobile user - $mobile_user = $this->findMobileUser($em); + $mobile_user = $mah->findMobileUser($em, $user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -174,7 +182,7 @@ class CustomerController extends APIController return new APIResponse(true, 'Number confirmed.'); } - public function validateCode(Request $req, EntityManagerInterface $em) + public function validateCode(Request $req, EntityManagerInterface $em, MobileAPIHandler $mah) { $this->denyAccessUnlessGranted('mobile_user.validate.code', null, 'No access.'); @@ -188,8 +196,11 @@ class CustomerController extends APIController if ($msg) return new APIResponse(false, $msg); + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + // get mobile user - $mobile_user = $this->findMobileUser($em); + $mobile_user = $mah->findMobileUser($em, $user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -227,12 +238,15 @@ class CustomerController extends APIController return new APIResponse(true, 'Code validated'); } - public function getInfo(Request $req, EntityManagerInterface $em) + public function getInfo(Request $req, EntityManagerInterface $em, MobileAPIHandler $mah) { $this->denyAccessUnlessGranted('mobile_user.get.info', null, 'No access.'); + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + // get mobile user - $mobile_user = $this->findMobileUser($em); + $mobile_user = $mah->findMobileUser($em, $user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -262,7 +276,7 @@ class CustomerController extends APIController return new APIResponse(true, 'Customer info found', $data); } - public function updateInfo(Request $req, EntityManagerInterface $em) + public function updateInfo(Request $req, EntityManagerInterface $em, MobileAPIHandler $mah) { $this->denyAccessUnlessGranted('mobile_user.update.info', null, 'No access.'); @@ -277,8 +291,11 @@ class CustomerController extends APIController if ($msg) return new APIResponse(false, $msg); + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + // get mobile user - $mobile_user = $this->findMobileUser($em); + $mobile_user = $mah->findMobileUser($em, $user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -304,12 +321,15 @@ class CustomerController extends APIController return new APIResponse(true, 'Customer info updated'); } - public function getStatus(Request $req, EntityManagerInterface $em) + public function getStatus(Request $req, EntityManagerInterface $em, MobileAPIHandler $mah) { $this->denyAccessUnlessGranted('mobile_user.get.status', null, 'No access.'); + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + // get mobile user - $mobile_user = $this->findMobileUser($em); + $mobile_user = $mah->findMobileUser($em, $user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -324,12 +344,16 @@ class CustomerController extends APIController return new APIResponse(true, 'Customer status', $data); } - public function resendCode(Request $req, RisingTideGateway $rt, EntityManagerInterface $em) + public function resendCode(Request $req, RisingTideGateway $rt, EntityManagerInterface $em, + MobileAPIHandler $mah) { $this->denyAccessUnlessGranted('mobile_user.resend.code', null, 'No access.'); + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + // get mobile user - $mobile_user = $this->findMobileUser($em); + $mobile_user = $mah->findMobileUser($em, $user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -350,7 +374,7 @@ class CustomerController extends APIController return new APIResponse(true, 'Code re-sent'); } - public function versionCheck(Request $req, EntityManagerInterface $em) + public function versionCheck(Request $req, EntityManagerInterface $em, MobileAPIHandler $mah) { $this->denyAccessUnlessGranted('mobile_user.version.check', null, 'No access.'); @@ -363,8 +387,11 @@ class CustomerController extends APIController if ($msg) return new APIResponse(false, $msg); + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + // get mobile user - $mobile_user = $this->findMobileUser($em); + $mobile_user = $mah->findMobileUser($em, $user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -397,7 +424,7 @@ class CustomerController extends APIController return new APIResponse(true, 'Version checked', $data); } - public function updateDeviceID(Request $req, EntityManagerInterface $em) + public function updateDeviceID(Request $req, EntityManagerInterface $em, MobileAPIHandler $mah) { $this->denyAccessUnlessGranted('mobile_user.update.deviceid', null, 'No access.'); @@ -410,8 +437,11 @@ class CustomerController extends APIController if ($msg) return new APIResponse(false, $msg); + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + // get mobile user - $mobile_user = $this->findMobileUser($em); + $mobile_user = $mah->findMobileUser($em, $user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -425,7 +455,7 @@ class CustomerController extends APIController return new APIResponse(true, 'Device ID updated'); } - public function privacySettings(Request $req, EntityManagerInterface $em) + public function privacySettings(Request $req, EntityManagerInterface $em, MobileAPIHandler $mah) { $this->denyAccessUnlessGranted('mobile_user.privacy.settings', null, 'No access.'); @@ -439,8 +469,11 @@ class CustomerController extends APIController if ($msg) return new APIResponse(false, $msg); + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + // get mobile user - $mobile_user = $this->findMobileUser($em); + $mobile_user = $mah->findMobileUser($em, $user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -494,15 +527,6 @@ class CustomerController extends APIController return new APIResponse(true, 'Privacy policy settings set'); } - protected function findMobileUser($em) - { - // get capi user to link to mobile user - $user_id = $this->getUser()->getID(); - $mobile_user = $em->getRepository(MobileUser::class)->findOneBy(['capi_user_id' => $user_id]); - - return $mobile_user; - } - // TODO: find session customer by phone number protected function findNumberMobileUser($number, $em) { diff --git a/src/Controller/ResqAPI/VehicleController.php b/src/Controller/ResqAPI/VehicleController.php index bbb8f5d0..eb67b1fd 100644 --- a/src/Controller/ResqAPI/VehicleController.php +++ b/src/Controller/ResqAPI/VehicleController.php @@ -9,14 +9,13 @@ use Doctrine\ORM\Query; use Doctrine\ORM\EntityManagerInterface; use Catalyst\APIBundle\Controller\APIController; -// TODO: what do we use for response? APIResponse or APIResult? -// APIResult is what is used by APIController. APIResponse is what is used by CAPI use Catalyst\APIBundle\Response\APIResponse; -use App\Ramcar\APIResult; use App\Entity\VehicleManufacturer; use App\Entity\Vehicle; +use App\Service\MobileAPIHandler; + use Catalyst\APIBundle\Access\Generator as ACLGenerator; class VehicleController extends APIController @@ -28,13 +27,25 @@ class VehicleController extends APIController $this->acl_gen = $acl_gen; } - public function listVehicleManufacturers(Request $req, EntityManagerInterface $em) + public function listVehicleManufacturers(Request $req, EntityManagerInterface $em, + MobileAPIHandler $mah) { - // check required parameters and api key + $this->denyAccessUnlessGranted('mobile_vmanufacturer.list', null, 'No access.'); + + // check required parameters $required_params = []; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($em, $user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); // get manufacturer list $mfgs = $em->getRepository(VehicleManufacturer::class)->findBy(['flag_mobile' => true], ['name' => 'asc']); @@ -50,27 +61,34 @@ class VehicleController extends APIController $data = [ 'manufacturers' => $mfg_list ]; - $res->setData($data); - return $res->getReturnResponse(); + return new APIResponse(true, 'Vehicle manufacturers listed.', $data); } - public function listVehicleMakes(Request $req, $mfg_id, EntityManagerInterface $em) + public function listVehicleMakes(Request $req, $mfg_id, EntityManagerInterface $em, + MobileAPIHandler $mah) { - // check required parameters and api key + $this->denyAccessUnlessGranted('mobile_vehicle.list', null, 'No access.'); + + // check required parameters $required_params = []; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($em, $user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); // get manufacturer $mfg = $em->getRepository(VehicleManufacturer::class)->find($mfg_id); if ($mfg == null) - { - $res->setError(true) - ->setErrorMessage('Invalid vehicle manufacturer id'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'Invalid vehicle manufacturer id'); // get makes $vehicles = $em->getRepository(Vehicle::class)->findBy( @@ -87,7 +105,6 @@ class VehicleController extends APIController $vlist[] = [ 'id' => $v->getID(), 'make' => trim($v->getMake() . ' ' . $v->getModelYearFormatted(false)), - // 'make' => $v->getMake() . ' ' . $v->getModelYearFrom() . '-' . $v->getModelYearTo(), ]; } @@ -99,92 +116,7 @@ class VehicleController extends APIController 'makes' => $vlist, ]; - $res->setData($data); - - return $res->getReturnResponse(); + return new APIResponse(true, 'Vehicle makes listed.', $data); } - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkParamsAndKey(Request $req, $em, $params) - { - // TODO: depends on what we decide to return - // returns APIResult object - $res = new APIResult(); - - // check for api_key in query string - $api_key = $req->query->get('api_key'); - if (empty($api_key)) - { - $res->setError(true) - ->setErrorMessage('Missing API key'); - return $res; - } - - // check missing parameters - $missing = $this->checkMissingParameters($req, $params); - if (count($missing) > 0) - { - $miss_string = implode(', ', $missing); - $res->setError(true) - ->setErrorMessage('Missing parameter(s): ' . $miss_string); - return $res; - } - - // check api key - $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); - if ($mobile_user == null) - { - $res->setError(true) - ->setErrorMessage('Invalid API Key'); - return $res; - } - - // store session - $this->session = $sess; - - return $res; - } - - // TODO: this might not be needed if we use APIController's checkRequiredParameters - // or we put this into a service? - protected function checkMissingParameters(Request $req, $params = []) - { - $missing = []; - - // check if parameters are there - foreach ($params as $param) - { - if ($req->getMethod() == 'GET') - { - $check = $req->query->get($param); - if (empty($check)) - $missing[] = $param; - } - else if ($req->getMethod() == 'POST') - { - $check = $req->request->get($param); - if (empty($check)) - $missing[] = $param; - } - else - return $params; - } - - return $missing; - } - - // TODO: type hint entity manager - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkAPIKey($em, $api_key) - { - // find the api key (session id) - // TODO: user validation needs to be changed - $m_user = $em->getRepository(MobileUser::class)->find($api_key); - if ($m_user == null) - return null; - - return $m_user; - } } diff --git a/src/Service/MobileAPIHandler.php b/src/Service/MobileAPIHandler.php new file mode 100644 index 00000000..534cec99 --- /dev/null +++ b/src/Service/MobileAPIHandler.php @@ -0,0 +1,26 @@ +em = $em; + } + + public function findMobileUser($em, $user_id) + { + // get capi user to link to mobile user + $mobile_user = $em->getRepository(MobileUser::class)->findOneBy(['capi_user_id' => $user_id]); + + return $mobile_user; + } + +} -- 2.43.5 From cd48858b9dbb268b50aa0d38cae432eb239b5642 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 5 Jul 2021 09:52:26 +0000 Subject: [PATCH 14/42] Modify CustomerVehicleController. #591 --- config/api_acl.yaml | 9 + .../ResqAPI/CustomerVehicleController.php | 294 +++++------------- src/Service/MobileAPIHandler.php | 63 ++++ 3 files changed, 150 insertions(+), 216 deletions(-) diff --git a/config/api_acl.yaml b/config/api_acl.yaml index bae91221..c6867ac3 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -101,3 +101,12 @@ access_keys: acls: - id: mobile_vehicle.list label: List Vehicle Makes + - id: mobile_customer_vehicle + label: Mobile customer Vehicle Access + acls: + - id: mobile_customer_vehicle.add + label: Add Mobile Customer Vehicle + - id: mobile_customer_vehicle.update + label: Update Mobile Customer Vehicle + - id: mobile_customer_vehicle.list + label: List Mobile Customer Vehicles diff --git a/src/Controller/ResqAPI/CustomerVehicleController.php b/src/Controller/ResqAPI/CustomerVehicleController.php index 36f8e12a..884b5142 100644 --- a/src/Controller/ResqAPI/CustomerVehicleController.php +++ b/src/Controller/ResqAPI/CustomerVehicleController.php @@ -9,15 +9,15 @@ use Doctrine\ORM\Query; use Doctrine\ORM\EntityManagerInterface; use Catalyst\APIBundle\Controller\APIController; -// TODO: what do we use for response? APIResponse or APIResult? -// APIResult is what is used by APIController. APIResponse is what is used by CAPI use Catalyst\APIBundle\Response\APIResponse; -use App\Ramcar\APIResult; +use App\Entity\MobileUser; use App\Entity\VehicleManufacturer; use App\Entity\Vehicle; use App\Entity\CustomerVehicle; +use App\Service\MobileAPIHandler; + use Catalyst\APIBundle\Access\Generator as ACLGenerator; class CustomerVehicleController extends APIController @@ -29,70 +29,92 @@ class CustomerVehicleController extends APIController $this->acl_gen = $acl_gen; } - public function addVehicle(Request $req, EntityManagerInterface $em) + public function addVehicle(Request $req, EntityManagerInterface $em, + MobileAPIHandler $mah) { + $this->denyAccessUnlessGranted('mobile_customer_vehicle.add', null, 'No access.'); + // check requirements - $res = $this->checkVehicleRequirements($req, $em); - if ($res->isError()) - return $res->getReturnResponse(); + $msg = $this->checkVehicleRequirements($req); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($em, $user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); // customer vehicle $cv = new CustomerVehicle(); - $res = $this->setCustomerVehicleObject($req, $res, $cv, $em); - - return $res->getReturnResponse(); + $res = $this->setCustomerVehicleObject($mobile_user, $req, $cv, $em); + if (isset($res['cv_id'])) + return new APIResponse(true, 'Customer vehicle added', $res); + else + return new APIResponse(false, $res); } - // TODO: needs to be modified for mobile user - public function updateVehicle(Request $req, $id, EntityManagerInterface $em) + public function updateVehicle(Request $req, $id, EntityManagerInterface $em, + MobileAPIHandler $mah) { + $this->denyAccessUnlessGranted('mobile_customer_vehicle.update', null, 'No access.'); + // check requirements - $res = $this->checkVehicleRequirements($req, $em); - if ($res->isError()) - return $res->getReturnResponse(); + $msg = $this->checkVehicleRequirements($req); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($em, $user_id); // get customer vehicle $cv = $em->getRepository(CustomerVehicle::class)->find($id); // check if it exists if ($cv == null) - { - $res->setError(true) - ->setErrorMessage('Vehicle does not exist'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'Vehicle does not exist'); // check if it's owned by customer - if ($cv->getCustomer()->getID() != $this->session->getCustomer()->getID()) - { - $res->setError(true) - ->setErrorMessage('Invalid vehicle'); - return $res->getReturnResponse(); - } + if ($cv->getCustomer()->getID() != $mobile_user->getCustomer()->getID()) + return new APIResponse(false, 'Invalid vehicle'); - $res = $this->setCustomerVehicleObject($req, $res, $cv, $em); + $res = $this->setCustomerVehicleObject($mobile_user, $req, $cv, $em); + if (isset($res['cv_id'])) + return new APIResponse(true, 'Customer vehicle updated', $res); + else + return new APIResponse(false, $res); - return $res->getReturnResponse(); } - // TODO: needs to be modified for mobile user - public function listVehicles(Request $req, EntityManagerInterface $em) + public function listVehicles(Request $req, EntityManagerInterface $em, MobileAPIHandler $mah) { - // check required parameters and api key - $required_params = []; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $this->denyAccessUnlessGranted('mobile_customer_vehicle.list', null, 'No access.'); - // customer - $cust = $this->session->getCustomer(); + // check required parameters + $required_params = []; + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($em, $user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); + + $cust = $mobile_user->getCustomer(); if ($cust == null) - { - $res->setError(true) - ->setErrorMessage('No customer information found'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'No customer information found'); // vehicles $cv_list = []; @@ -107,7 +129,7 @@ class CustomerVehicleController extends APIController if ($cv->getWarrantyExpiration() != null) $wty_ex = $cv->getWarrantyExpiration()->format('Y-m-d'); - $warranty = $this->findWarranty($cv->getPlateNumber(), $em); + $warranty = $mah->findWarranty($cv->getPlateNumber(), $em); $cv_name = ''; if ($cv->getName() != null) @@ -136,14 +158,13 @@ class CustomerVehicleController extends APIController $data = [ 'vehicles' => $cv_list ]; - $res->setData($data); - return $res->getReturnResponse(); + return new APIResponse(true, 'Customer vehicles listed', $data); } - protected function checkVehicleRequirements(Request $req, EntityManagerInterface $em) + protected function checkVehicleRequirements(Request $req) { - // check required parameters and api key + // check required parameters $required_params = [ 'make_id', 'name', @@ -153,9 +174,7 @@ class CustomerVehicleController extends APIController 'condition', 'fuel_type', ]; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res; + $msg = $this->checkRequiredParameters($req, $required_params); // TODO: check valid plate number // TODO: check valid fuel type (gas / diesel) @@ -165,28 +184,27 @@ class CustomerVehicleController extends APIController // TODO: check warranty expiration date (YYYYMMDD) // TODO: check model year coverage if it fits in between - return $res; + return $msg; } - protected function setCustomerVehicleObject(Request $req, APIResult $res, + protected function setCustomerVehicleObject(MobileUser $mobile_user, Request $req, CustomerVehicle $cv, EntityManagerInterface $em) { + $msg = ''; // check customer - $cust = $this->session->getCustomer(); + $cust = $mobile_user->getCustomer(); if ($cust == null) { - $res->setError(true) - ->setErrorMessage('No customer information found'); - return $res; + $msg = 'No customer information found'; + return $msg; } // get vehicle $vehicle = $em->getRepository(Vehicle::class)->find($req->request->get('make_id')); if ($vehicle == null) { - $res->setError(true) - ->setErrorMessage('Invalid vehicle make id'); - return $res; + $msg = 'Invalid vehicle make id'; + return $msg; } $cv->setCustomer($cust) @@ -227,163 +245,7 @@ class CustomerVehicleController extends APIController $data = [ 'cv_id' => $cv->getID() ]; - $res->setData($data); - return $res; - } - - // TODO: what to do with this? listVehicles calls this and so does getJOHistory in the JobOrderController - protected function findWarranty($plate_number, $em) - { - // NOTE: Modify the search for the latest warranty. This seems hacky. - // get latest warranty using plate number - $warranty_results = $em->getRepository(Warranty::class)->findBy(['plate_number' => $plate_number], - ['date_create' => 'desc']); - - $warr = []; - - // check if warranty_results is empty - if (empty($warranty_results)) - { - /* - $res->setError(true) - ->setErrorMessage('No warranty found for plate number'); - return $res->getReturnResponse(); - */ - - return $warr; - } - - // get first entry - $warranty = current($warranty_results); - - // check for null values for battery and date claim and date expire - $batt_model = ''; - $batt_size = ''; - $sap_batt = ''; - $claim_date = ''; - $expiry_date = ''; - - if (!(is_null($warranty->getBatteryModel()))) { - $batt_model = $warranty->getBatteryModel()->getName(); - } - if (!(is_null($warranty->getBatterySize()))) { - $batt_size = $warranty->getBatterySize()->getName(); - } - if (!(is_null($warranty->getSAPBattery()))) { - $sap_batt = $warranty->getSAPBattery()->getID(); - } - if (!(is_null($warranty->getDateClaim()))) { - $claim_date = $warranty->getDateClaim()->format("d M Y"); - } - if (!(is_null($warranty->getDateExpire()))) { - $expiry_date = $warranty->getDateExpire()->format("d M Y"); - } - - $warr[] = [ - 'id' => $warranty->getID(), - 'serial' => $warranty->getSerial(), - 'warranty_class' => $warranty->getWarrantyClass(), - 'plate_number' => $warranty->getPlateNumber(), - 'first_name' => $warranty->getFirstName(), - 'last_name' => $warranty->getLastName(), - 'mobile_number' => $warranty->getMobileNumber(), - 'battery_model' => $batt_model, - 'battery_size' => $batt_size, - 'sap_battery' => $sap_batt, - 'status' => $warranty->getStatus(), - 'date_create' => $warranty->getDateCreate()->format("d M Y g:i A"), - 'date_purchase' => $warranty->getDatePurchase()->format("d M Y"), - 'date_expire' => $expiry_date, - 'date_claim' => $claim_date, - 'claim_from' => $warranty->getClaimedFrom(), - 'is_activated' => $warranty->isActivated() ? 1 : 0, - ]; - - return $warr; - } - - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkParamsAndKey(Request $req, $em, $params) - { - // TODO: depends on what we decide to return - // returns APIResult object - $res = new APIResult(); - - // check for api_key in query string - $api_key = $req->query->get('api_key'); - if (empty($api_key)) - { - $res->setError(true) - ->setErrorMessage('Missing API key'); - return $res; - } - - // check missing parameters - $missing = $this->checkMissingParameters($req, $params); - if (count($missing) > 0) - { - $miss_string = implode(', ', $missing); - $res->setError(true) - ->setErrorMessage('Missing parameter(s): ' . $miss_string); - return $res; - } - - // check api key - $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); - if ($mobile_user == null) - { - $res->setError(true) - ->setErrorMessage('Invalid API Key'); - return $res; - } - - // store session - $this->session = $sess; - - return $res; - } - - // TODO: this might not be needed if we use APIController's checkRequiredParameters - // or we put this into a service? - protected function checkMissingParameters(Request $req, $params = []) - { - $missing = []; - - // check if parameters are there - foreach ($params as $param) - { - if ($req->getMethod() == 'GET') - { - $check = $req->query->get($param); - if (empty($check)) - $missing[] = $param; - } - else if ($req->getMethod() == 'POST') - { - $check = $req->request->get($param); - if (empty($check)) - $missing[] = $param; - } - else - return $params; - } - - return $missing; - } - - // TODO: type hint entity manager - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkAPIKey($em, $api_key) - { - // find the api key (session id) - // TODO: user validation needs to be changed - $m_user = $em->getRepository(MobileUser::class)->find($api_key); - if ($m_user == null) - return null; - - return $m_user; + return $data; } } diff --git a/src/Service/MobileAPIHandler.php b/src/Service/MobileAPIHandler.php index 534cec99..f95ef6ad 100644 --- a/src/Service/MobileAPIHandler.php +++ b/src/Service/MobileAPIHandler.php @@ -5,6 +5,7 @@ namespace App\Service; use Doctrine\ORM\EntityManagerInterface; use App\Entity\MobileUser; +use App\Entity\Warranty; class MobileAPIHandler { @@ -23,4 +24,66 @@ class MobileAPIHandler return $mobile_user; } + public function findWarranty($plate_number, $em) + { + // NOTE: Modify the search for the latest warranty. This seems hacky. + // get latest warranty using plate number + $warranty_results = $em->getRepository(Warranty::class)->findBy(['plate_number' => $plate_number], + ['date_create' => 'desc']); + + $warr = []; + + // check if warranty_results is empty + if (empty($warranty_results)) + return $warr; + + // get first entry + $warranty = current($warranty_results); + + // check for null values for battery and date claim and date expire + $batt_model = ''; + $batt_size = ''; + $sap_batt = ''; + $claim_date = ''; + $expiry_date = ''; + + if (!(is_null($warranty->getBatteryModel()))) { + $batt_model = $warranty->getBatteryModel()->getName(); + } + if (!(is_null($warranty->getBatterySize()))) { + $batt_size = $warranty->getBatterySize()->getName(); + } + if (!(is_null($warranty->getSAPBattery()))) { + $sap_batt = $warranty->getSAPBattery()->getID(); + } + if (!(is_null($warranty->getDateClaim()))) { + $claim_date = $warranty->getDateClaim()->format("d M Y"); + } + if (!(is_null($warranty->getDateExpire()))) { + $expiry_date = $warranty->getDateExpire()->format("d M Y"); + } + + $warr[] = [ + 'id' => $warranty->getID(), + 'serial' => $warranty->getSerial(), + 'warranty_class' => $warranty->getWarrantyClass(), + 'plate_number' => $warranty->getPlateNumber(), + 'first_name' => $warranty->getFirstName(), + 'last_name' => $warranty->getLastName(), + 'mobile_number' => $warranty->getMobileNumber(), + 'battery_model' => $batt_model, + 'battery_size' => $batt_size, + 'sap_battery' => $sap_batt, + 'status' => $warranty->getStatus(), + 'date_create' => $warranty->getDateCreate()->format("d M Y g:i A"), + 'date_purchase' => $warranty->getDatePurchase()->format("d M Y"), + 'date_expire' => $expiry_date, + 'date_claim' => $claim_date, + 'claim_from' => $warranty->getClaimedFrom(), + 'is_activated' => $warranty->isActivated() ? 1 : 0, + ]; + + return $warr; + } + } -- 2.43.5 From 2ce5f0588584e6fde6683f23f5fb192cd39d1bb4 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 5 Jul 2021 10:01:54 +0000 Subject: [PATCH 15/42] Modify PromoController. #591 --- config/api_acl.yaml | 5 ++ src/Controller/ResqAPI/PromoController.php | 99 ++-------------------- 2 files changed, 12 insertions(+), 92 deletions(-) diff --git a/config/api_acl.yaml b/config/api_acl.yaml index c6867ac3..9c951917 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -110,3 +110,8 @@ access_keys: label: Update Mobile Customer Vehicle - id: mobile_customer_vehicle.list label: List Mobile Customer Vehicles + - id: mobile_promo + label: Mobile Promo Access + acls: + - id: mobile_promo.list + label: List Mobile Promos diff --git a/src/Controller/ResqAPI/PromoController.php b/src/Controller/ResqAPI/PromoController.php index 75dc419c..74fdb850 100644 --- a/src/Controller/ResqAPI/PromoController.php +++ b/src/Controller/ResqAPI/PromoController.php @@ -9,10 +9,7 @@ use Doctrine\ORM\Query; use Doctrine\ORM\EntityManagerInterface; use Catalyst\APIBundle\Controller\APIController; -// TODO: what do we use for response? APIResponse or APIResult? -// APIResult is what is used by APIController. APIResponse is what is used by CAPI use Catalyst\APIBundle\Response\APIResponse; -use App\Ramcar\APIResult; use App\Entity\Promo; @@ -29,96 +26,14 @@ class PromoController extends APIController public function listPromos(Request $req, EntityManagerInterface $em) { - // check required parameters and api key + $this->denyAccessUnlessGranted('mobile_promo.list', null, 'No access.'); + + // check required parameters $required_params = []; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); - return $res->getReturnResponse(); - } - - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkParamsAndKey(Request $req, $em, $params) - { - // TODO: depends on what we decide to return - // returns APIResult object - $res = new APIResult(); - - // check for api_key in query string - $api_key = $req->query->get('api_key'); - if (empty($api_key)) - { - $res->setError(true) - ->setErrorMessage('Missing API key'); - return $res; - } - - // check missing parameters - $missing = $this->checkMissingParameters($req, $params); - if (count($missing) > 0) - { - $miss_string = implode(', ', $missing); - $res->setError(true) - ->setErrorMessage('Missing parameter(s): ' . $miss_string); - return $res; - } - - // check api key - $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); - if ($mobile_user == null) - { - $res->setError(true) - ->setErrorMessage('Invalid API Key'); - return $res; - } - - // store session - $this->session = $sess; - - return $res; - } - - // TODO: this might not be needed if we use APIController's checkRequiredParameters - // or we put this into a service? - protected function checkMissingParameters(Request $req, $params = []) - { - $missing = []; - - // check if parameters are there - foreach ($params as $param) - { - if ($req->getMethod() == 'GET') - { - $check = $req->query->get($param); - if (empty($check)) - $missing[] = $param; - } - else if ($req->getMethod() == 'POST') - { - $check = $req->request->get($param); - if (empty($check)) - $missing[] = $param; - } - else - return $params; - } - - return $missing; - } - - // TODO: type hint entity manager - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkAPIKey($em, $api_key) - { - // find the api key (session id) - // TODO: user validation needs to be changed - $m_user = $em->getRepository(MobileUser::class)->find($api_key); - if ($m_user == null) - return null; - - return $m_user; + return new APIResponse(true, 'Promos listed'); } } -- 2.43.5 From cfbda4efe0f5ac469e72e9a92912c893e349469a Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 6 Jul 2021 05:43:13 +0000 Subject: [PATCH 16/42] Modify BatteryController. #591 --- config/api_acl.yaml | 5 + src/Controller/ResqAPI/BatteryController.php | 124 ++++--------------- src/Service/MobileAPIHandler.php | 10 ++ 3 files changed, 40 insertions(+), 99 deletions(-) diff --git a/config/api_acl.yaml b/config/api_acl.yaml index 9c951917..09f6429c 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -115,3 +115,8 @@ access_keys: acls: - id: mobile_promo.list label: List Mobile Promos + - id: mobile_battery + label: Mobile Battery Access + acls: + - id: mobile_battery.list + label: List Compatible Batteries diff --git a/src/Controller/ResqAPI/BatteryController.php b/src/Controller/ResqAPI/BatteryController.php index 3f44294d..8f2e2ba6 100644 --- a/src/Controller/ResqAPI/BatteryController.php +++ b/src/Controller/ResqAPI/BatteryController.php @@ -9,13 +9,13 @@ use Doctrine\ORM\Query; use Doctrine\ORM\EntityManagerInterface; use Catalyst\APIBundle\Controller\APIController; -// TODO: what do we use for response? APIResponse or APIResult? -// APIResult is what is used by APIController. APIResponse is what is used by CAPI use Catalyst\APIBundle\Response\APIResponse; use App\Ramcar\APIResult; use App\Entity\Vehicle; +use App\Service\MobileAPIHandler; + use Catalyst\APIBundle\Access\Generator as ACLGenerator; class BatteryController extends APIController @@ -27,28 +27,39 @@ class BatteryController extends APIController $this->acl_gen = $acl_gen; } - public function getCompatibleBatteries(Request $req, $vid, EntityManagerInterface $em) + public function getCompatibleBatteries(Request $req, $vid, EntityManagerInterface $em, + MobileAPIHandler $mah) { - // check required parameters and api key + $this->denyAccessUnlessGranted('mobile_battery.list', null, 'No access.'); + + // check required parameters $required_params = []; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($em, $user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); // get vehicle $vehicle = $em->getRepository(Vehicle::class)->find($vid); if ($vehicle == null) - { - $res->setError(true) - ->setErrorMessage('Invalid vehicle'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'Invalid vehicle'); // batteries $batt_list = []; $batts = $vehicle->getBatteries(); foreach ($batts as $batt) { + // generate the url for image + $battery_image_url = $this->generateUrl('static_battery_image'); + // TODO: Add warranty_tnv to battery information $batt_list[] = [ 'id' => $batt->getID(), @@ -61,7 +72,7 @@ class BatteryController extends APIController 'price' => $batt->getSellingPrice(), 'wty_private' => $batt->getWarrantyPrivate(), 'wty_commercial' => $batt->getWarrantyCommercial(), - 'image_url' => $this->getBatteryImageURL($req, $batt), + 'image_url' => $mah->getBatteryImageURL($req, $batt, $battery_image_url), ]; } @@ -77,92 +88,7 @@ class BatteryController extends APIController ], 'batteries' => $batt_list, ]; - $res->setData($data); - return $res->getReturnResponse(); - } - - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkParamsAndKey(Request $req, $em, $params) - { - // TODO: depends on what we decide to return - // returns APIResult object - $res = new APIResult(); - - // check for api_key in query string - $api_key = $req->query->get('api_key'); - if (empty($api_key)) - { - $res->setError(true) - ->setErrorMessage('Missing API key'); - return $res; - } - - // check missing parameters - $missing = $this->checkMissingParameters($req, $params); - if (count($missing) > 0) - { - $miss_string = implode(', ', $missing); - $res->setError(true) - ->setErrorMessage('Missing parameter(s): ' . $miss_string); - return $res; - } - - // check api key - $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); - if ($mobile_user == null) - { - $res->setError(true) - ->setErrorMessage('Invalid API Key'); - return $res; - } - - // store session - $this->session = $sess; - - return $res; - } - - // TODO: this might not be needed if we use APIController's checkRequiredParameters - // or we put this into a service? - protected function checkMissingParameters(Request $req, $params = []) - { - $missing = []; - - // check if parameters are there - foreach ($params as $param) - { - if ($req->getMethod() == 'GET') - { - $check = $req->query->get($param); - if (empty($check)) - $missing[] = $param; - } - else if ($req->getMethod() == 'POST') - { - $check = $req->request->get($param); - if (empty($check)) - $missing[] = $param; - } - else - return $params; - } - - return $missing; - } - - // TODO: type hint entity manager - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkAPIKey($em, $api_key) - { - // find the api key (session id) - // TODO: user validation needs to be changed - $m_user = $em->getRepository(MobileUser::class)->find($api_key); - if ($m_user == null) - return null; - - return $m_user; + return new APIResponse(true, 'Compatible batteries found', $data); } } diff --git a/src/Service/MobileAPIHandler.php b/src/Service/MobileAPIHandler.php index f95ef6ad..4563eeff 100644 --- a/src/Service/MobileAPIHandler.php +++ b/src/Service/MobileAPIHandler.php @@ -86,4 +86,14 @@ class MobileAPIHandler return $warr; } + public function getBatteryImageURL($req, $batt, $battery_image_url) + { + // TODO: workaround for now, we get static image of battery based on model name + $filename = trim(strtolower($batt->getModel()->getName())) . '_mobile.jpg'; + $file_path = $req->getSchemeAndHttpHost() . $battery_image_url . '/' . $filename; + + return $file_path; + } + + } -- 2.43.5 From dbcf2266828cd7858509625a4d54515242df33e4 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 6 Jul 2021 05:53:56 +0000 Subject: [PATCH 17/42] Modify ServiceController. #591 --- config/api_acl.yaml | 5 + src/Controller/ResqAPI/ServiceController.php | 141 +++---------------- 2 files changed, 27 insertions(+), 119 deletions(-) diff --git a/config/api_acl.yaml b/config/api_acl.yaml index 09f6429c..759d3816 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -120,3 +120,8 @@ access_keys: acls: - id: mobile_battery.list label: List Compatible Batteries + - id: mobile_service + label: Mobile Service Access + acls: + - id: mobile_service.list + label: List Mobile Services diff --git a/src/Controller/ResqAPI/ServiceController.php b/src/Controller/ResqAPI/ServiceController.php index 0c47867e..855aea92 100644 --- a/src/Controller/ResqAPI/ServiceController.php +++ b/src/Controller/ResqAPI/ServiceController.php @@ -9,13 +9,12 @@ use Doctrine\ORM\Query; use Doctrine\ORM\EntityManagerInterface; use Catalyst\APIBundle\Controller\APIController; -// TODO: what do we use for response? APIResponse or APIResult? -// APIResult is what is used by APIController. APIResponse is what is used by CAPI use Catalyst\APIBundle\Response\APIResponse; -use App\Ramcar\APIResult; use App\Entity\Service; +use App\Service\MobileAPIHandler; + use Catalyst\APIBundle\Access\Generator as ACLGenerator; class ServiceController extends APIController @@ -27,138 +26,42 @@ class ServiceController extends APIController $this->acl_gen = $acl_gen; } - public function listServices(Request $req, EntityManagerInterface $em) + public function listServices(Request $req, EntityManagerInterface $em, + MobileAPIHandler $mah) { - $required_params = []; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $this->denyAccessUnlessGranted('mobile_service.list', null, 'No access.'); + // check required parameters + $required_params = []; + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($em, $user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); + // services $results = $em->getRepository(Service::class)->findAll(); if (empty($results)) - { - $res->setError(true) - ->setErrorMessage('No services available.'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'No services available'); $services = []; foreach ($results as $result) { - /* - // get partners - $partners = []; - $service_partners = $result->getPartners(); - foreach($service_partners as $sp) - { - $partners[] = [ - 'id' => $sp->getID(), - 'name' => $sp->getName(), - 'branch' => $sp->getBranch(), - 'address' => $sp->getAddress(), - 'contact_nums' => $sp->getContactNumbers(), - 'time_open' => $sp->getTimeOpen()->format("g:i A"), - 'time_close' => $sp->getTimeClose()->format("g:i A"), - ]; - } - */ - $services[] = [ 'id' => $result->getID(), 'name' => $result->getName(), - // 'partners' => $partners, ]; } $data['services'] = $services; - $res->setData($data); - - return $res->getReturnResponse(); - } - - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkParamsAndKey(Request $req, $em, $params) - { - // TODO: depends on what we decide to return - // returns APIResult object - $res = new APIResult(); - - // check for api_key in query string - $api_key = $req->query->get('api_key'); - if (empty($api_key)) - { - $res->setError(true) - ->setErrorMessage('Missing API key'); - return $res; - } - - // check missing parameters - $missing = $this->checkMissingParameters($req, $params); - if (count($missing) > 0) - { - $miss_string = implode(', ', $missing); - $res->setError(true) - ->setErrorMessage('Missing parameter(s): ' . $miss_string); - return $res; - } - - // check api key - $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); - if ($mobile_user == null) - { - $res->setError(true) - ->setErrorMessage('Invalid API Key'); - return $res; - } - - // store session - $this->session = $sess; - - return $res; - } - - // TODO: this might not be needed if we use APIController's checkRequiredParameters - // or we put this into a service? - protected function checkMissingParameters(Request $req, $params = []) - { - $missing = []; - - // check if parameters are there - foreach ($params as $param) - { - if ($req->getMethod() == 'GET') - { - $check = $req->query->get($param); - if (empty($check)) - $missing[] = $param; - } - else if ($req->getMethod() == 'POST') - { - $check = $req->request->get($param); - if (empty($check)) - $missing[] = $param; - } - else - return $params; - } - - return $missing; - } - - // TODO: type hint entity manager - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkAPIKey($em, $api_key) - { - // find the api key (session id) - // TODO: user validation needs to be changed - $m_user = $em->getRepository(MobileUser::class)->find($api_key); - if ($m_user == null) - return null; - - return $m_user; + return new APIResponse(true, 'Services found', $data); } } -- 2.43.5 From 41f200270150400b8de419b5ef8f45715b5f1ccc Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 6 Jul 2021 09:26:13 +0000 Subject: [PATCH 18/42] Modify PartnerController. #591 --- config/api_acl.yaml | 15 +- config/routes/resqapi.yaml | 2 +- src/Controller/ResqAPI/CustomerController.php | 2 +- src/Controller/ResqAPI/PartnerController.php | 186 ++++++------------ src/Entity/MobileUser.php | 4 +- src/Entity/Review.php | 18 ++ 6 files changed, 96 insertions(+), 131 deletions(-) diff --git a/config/api_acl.yaml b/config/api_acl.yaml index 759d3816..c9cc42bf 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -102,7 +102,7 @@ access_keys: - id: mobile_vehicle.list label: List Vehicle Makes - id: mobile_customer_vehicle - label: Mobile customer Vehicle Access + label: Mobile Customer Vehicle Access acls: - id: mobile_customer_vehicle.add label: Add Mobile Customer Vehicle @@ -114,7 +114,7 @@ access_keys: label: Mobile Promo Access acls: - id: mobile_promo.list - label: List Mobile Promos + label: List Promos - id: mobile_battery label: Mobile Battery Access acls: @@ -124,4 +124,13 @@ access_keys: label: Mobile Service Access acls: - id: mobile_service.list - label: List Mobile Services + label: List Services + - id: mobile_partner + label: Mobile Partner Access + acls: + - id: mobile_partner.list + label: List Mobile Partners + - id: mobile_partner.info + label: Get Partner Info + - id: mobile_partner.review + label: Add Partner Review diff --git a/config/routes/resqapi.yaml b/config/routes/resqapi.yaml index b2edb7f8..354440d2 100644 --- a/config/routes/resqapi.yaml +++ b/config/routes/resqapi.yaml @@ -105,7 +105,7 @@ resqapi_partner_info: resqapi_partner: path: /resqapi/partners controller: App\Controller\ResqAPI\PartnerController:getClosestPartners - methods: [GET] + methods: [POST] resqapi_partner_review: path: /resqapi/partners/{pid}/review diff --git a/src/Controller/ResqAPI/CustomerController.php b/src/Controller/ResqAPI/CustomerController.php index 215daf01..c47daf55 100644 --- a/src/Controller/ResqAPI/CustomerController.php +++ b/src/Controller/ResqAPI/CustomerController.php @@ -401,7 +401,7 @@ class CustomerController extends APIController $api_version = $this->getParameter('api_version'); - $app_version = $req->query->get('version'); + $app_version = $req->request->get('version'); $api_v = explode('.', $api_version); $app_v = explode('.', $app_version); diff --git a/src/Controller/ResqAPI/PartnerController.php b/src/Controller/ResqAPI/PartnerController.php index e6bc0157..3a124427 100644 --- a/src/Controller/ResqAPI/PartnerController.php +++ b/src/Controller/ResqAPI/PartnerController.php @@ -9,14 +9,13 @@ use Doctrine\ORM\Query; use Doctrine\ORM\EntityManagerInterface; use Catalyst\APIBundle\Controller\APIController; -// TODO: what do we use for response? APIResponse or APIResult? -// APIResult is what is used by APIController. APIResponse is what is used by CAPI use Catalyst\APIBundle\Response\APIResponse; -use App\Ramcar\APIResult; use App\Entity\Partner; use App\Entity\Review; +use App\Service\MobileAPIHandler; + use Catalyst\APIBundle\Access\Generator as ACLGenerator; class PartnerController extends APIController @@ -28,22 +27,35 @@ class PartnerController extends APIController $this->acl_gen = $acl_gen; } - public function getClosestPartners(Request $req, EntityManagerInterface $em) + public function getClosestPartners(Request $req, EntityManagerInterface $em, + MobileAPIHandler $mah) { + $this->denyAccessUnlessGranted('mobile_partner.list', null, 'No access.'); + + // check required parameters $required_params = [ 'longitude', 'latitude', 'service_id', 'limit', ]; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); - $long = $req->query->get('longitude'); - $lat = $req->query->get('latitude'); - $service_id = $req->query->get('service_id'); - $limit = $req->query->get('limit'); + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($em, $user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); + + $long = $req->request->get('longitude'); + $lat = $req->request->get('latitude'); + $service_id = $req->request->get('service_id'); + $limit = $req->request->get('limit'); // get partners within range $query = $em->createQuery('SELECT p, st_distance(p.coordinates, point(:lng, :lat)) as dist FROM App\Entity\Partner p @@ -55,10 +67,10 @@ class PartnerController extends APIController $query->setMaxResults($limit); $result = $query->getResult(); - $data = []; $partners = []; foreach($result as $row) { + error_log($row[0]->getID()); $partners[] = [ 'id' => $row[0]->getID(), 'name' => $row[0]->getName(), @@ -75,26 +87,33 @@ class PartnerController extends APIController $data['partners'] = $partners; - $res->setData($data); - - return $res->getReturnResponse(); + return new APIResponse(true, 'Partners found', $data); } - public function getPartnerInformation(Request $req, $pid, EntityManagerInterface $em) + public function getPartnerInformation(Request $req, $pid, EntityManagerInterface $em, + MobileAPIHandler $mah) { + $this->denyAccessUnlessGranted('mobile_partner.info', null, 'No access.'); + + // check required parameters $required_params = []; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($em, $user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); // get partner $partner = $em->getRepository(Partner::class)->findOneBy(['id' => $pid]); if ($partner == null) - { - $res->setError(true) - ->setErrorMessage('No partner found.'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'No partner found.'); // get reviews for partner $reviews = $em->getRepository(Review::class)->findBy(['partner' => $partner]); @@ -125,21 +144,31 @@ class PartnerController extends APIController 'average_rating' => $average_rating, ]; - $res->setData($data); - - return $res->getReturnResponse(); + return new APIResponse(true, 'Partner information found', $data); } - public function reviewPartner($pid, Request $req, EntityManagerInterface $em) + public function reviewPartner($pid, Request $req, EntityManagerInterface $em, + MobileAPIHandler $mah) { + $this->denyAccessUnlessGranted('mobile_partner.review', null, 'No access.'); + $required_params = [ 'rating', 'message', ]; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($em, $user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); $rating = $req->request->get('rating'); $msg = $req->request->get('message'); @@ -149,11 +178,7 @@ class PartnerController extends APIController // check if partner exists $partner = $em->getRepository(Partner::class)->find($pid); if ($partner == null) - { - $res->setError(true) - ->setErrorMessage('No partner found.'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'No partner found.'); $rev = new Review(); $rev->setRating($rating) @@ -165,93 +190,6 @@ class PartnerController extends APIController $em->persist($rev); $em->flush(); - $data = []; - $res->setData($data); - - return $res->getReturnResponse(); - } - - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkParamsAndKey(Request $req, $em, $params) - { - // TODO: depends on what we decide to return - // returns APIResult object - $res = new APIResult(); - - // check for api_key in query string - $api_key = $req->query->get('api_key'); - if (empty($api_key)) - { - $res->setError(true) - ->setErrorMessage('Missing API key'); - return $res; - } - - // check missing parameters - $missing = $this->checkMissingParameters($req, $params); - if (count($missing) > 0) - { - $miss_string = implode(', ', $missing); - $res->setError(true) - ->setErrorMessage('Missing parameter(s): ' . $miss_string); - return $res; - } - - // check api key - $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); - if ($mobile_user == null) - { - $res->setError(true) - ->setErrorMessage('Invalid API Key'); - return $res; - } - - // store session - $this->session = $sess; - - return $res; - } - - // TODO: this might not be needed if we use APIController's checkRequiredParameters - // or we put this into a service? - protected function checkMissingParameters(Request $req, $params = []) - { - $missing = []; - - // check if parameters are there - foreach ($params as $param) - { - if ($req->getMethod() == 'GET') - { - $check = $req->query->get($param); - if (empty($check)) - $missing[] = $param; - } - else if ($req->getMethod() == 'POST') - { - $check = $req->request->get($param); - if (empty($check)) - $missing[] = $param; - } - else - return $params; - } - - return $missing; - } - - // TODO: type hint entity manager - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkAPIKey($em, $api_key) - { - // find the api key (session id) - // TODO: user validation needs to be changed - $m_user = $em->getRepository(MobileUser::class)->find($api_key); - if ($m_user == null) - return null; - - return $m_user; + return new APIResponse(true, 'Review added'); } } diff --git a/src/Entity/MobileUser.php b/src/Entity/MobileUser.php index 0e5e80e0..f31a04fb 100644 --- a/src/Entity/MobileUser.php +++ b/src/Entity/MobileUser.php @@ -97,9 +97,9 @@ class MobileUser */ protected $date_code_sent; - // reviews made by mobile session + // reviews made by mobile user /** - * @ORM\OneToMany(targetEntity="Review", mappedBy="mobile_session") + * @ORM\OneToMany(targetEntity="Review", mappedBy="mobile_user") */ protected $reviews; diff --git a/src/Entity/Review.php b/src/Entity/Review.php index 9903784e..efb8314a 100644 --- a/src/Entity/Review.php +++ b/src/Entity/Review.php @@ -52,6 +52,13 @@ class Review */ protected $mobile_session; + // mobile user that sent review + /** + * @ORM\ManyToOne(targetEntity="MobileUser", inversedBy="reviews") + * @ORM\JoinColumn(name="mobile_user_id", referencedColumnName="id") + */ + protected $mobile_user; + public function __construct() { $this->date_create = new DateTime(); @@ -114,4 +121,15 @@ class Review return $this->mobile_session; } + public function setMobileUser(MobileUser $mobile_user) + { + $this->mobile_user = $mobile_user; + return $this; + } + + public function getMobileUser() + { + return $this->mobile_user; + } + } -- 2.43.5 From 8408c1e96a9887456596fdb87c31a3edd4289d4b Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Fri, 9 Jul 2021 03:07:41 +0000 Subject: [PATCH 19/42] Modify PartnerController. #591 --- src/Controller/ResqAPI/PartnerController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controller/ResqAPI/PartnerController.php b/src/Controller/ResqAPI/PartnerController.php index 3a124427..ab9faa13 100644 --- a/src/Controller/ResqAPI/PartnerController.php +++ b/src/Controller/ResqAPI/PartnerController.php @@ -184,7 +184,7 @@ class PartnerController extends APIController $rev->setRating($rating) ->setMessage($msg) ->setPartner($partner) - ->setMobileSession($this->session); + ->setMobileUser($mobile_user); // save to db $em->persist($rev); -- 2.43.5 From fb63fd80aceb2fc8a8b0294bb8711b109c39903f Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Fri, 9 Jul 2021 07:33:23 +0000 Subject: [PATCH 20/42] Modify RiderController. Fix calls to MobileAPIHandler. #591 --- config/api_acl.yaml | 7 + src/Controller/ResqAPI/BatteryController.php | 2 +- src/Controller/ResqAPI/CustomerController.php | 21 +- .../ResqAPI/CustomerVehicleController.php | 8 +- src/Controller/ResqAPI/PartnerController.php | 6 +- src/Controller/ResqAPI/RiderController.php | 221 +++++------------- src/Controller/ResqAPI/ServiceController.php | 2 +- src/Controller/ResqAPI/VehicleController.php | 4 +- src/Service/MobileAPIHandler.php | 19 +- 9 files changed, 107 insertions(+), 183 deletions(-) diff --git a/config/api_acl.yaml b/config/api_acl.yaml index c9cc42bf..2499e003 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -134,3 +134,10 @@ access_keys: label: Get Partner Info - id: mobile_partner.review label: Add Partner Review + - id: mobile_rider + label: Mobile Rider Access + acls: + - id: mobile_rider.status.get + label: Get Rider Status + - id: mobile_rider.rating.add + label: Add Rider Rating diff --git a/src/Controller/ResqAPI/BatteryController.php b/src/Controller/ResqAPI/BatteryController.php index 8f2e2ba6..d1517838 100644 --- a/src/Controller/ResqAPI/BatteryController.php +++ b/src/Controller/ResqAPI/BatteryController.php @@ -42,7 +42,7 @@ class BatteryController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); diff --git a/src/Controller/ResqAPI/CustomerController.php b/src/Controller/ResqAPI/CustomerController.php index c47daf55..287fd082 100644 --- a/src/Controller/ResqAPI/CustomerController.php +++ b/src/Controller/ResqAPI/CustomerController.php @@ -55,7 +55,7 @@ class CustomerController extends APIController $user_id = $this->getUser()->getID(); // check if capi user already has a mobile user - $mobile_user = $mah->findMobileUser($em,$user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user != null) return new APIResponse(false, 'User already registered'); @@ -126,7 +126,7 @@ class CustomerController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -140,6 +140,7 @@ class CustomerController extends APIController $otp_mode = $_ENV['OTP_MODE']; + $data = []; // check for hardcoded phone number for app store testing if ($phone_number == '639221111111') { @@ -200,7 +201,7 @@ class CustomerController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -246,7 +247,7 @@ class CustomerController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -295,7 +296,7 @@ class CustomerController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -329,7 +330,7 @@ class CustomerController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -353,7 +354,7 @@ class CustomerController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -391,7 +392,7 @@ class CustomerController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -441,7 +442,7 @@ class CustomerController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -473,7 +474,7 @@ class CustomerController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); diff --git a/src/Controller/ResqAPI/CustomerVehicleController.php b/src/Controller/ResqAPI/CustomerVehicleController.php index 884b5142..fdbba8e0 100644 --- a/src/Controller/ResqAPI/CustomerVehicleController.php +++ b/src/Controller/ResqAPI/CustomerVehicleController.php @@ -43,7 +43,7 @@ class CustomerVehicleController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -72,7 +72,7 @@ class CustomerVehicleController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); // get customer vehicle $cv = $em->getRepository(CustomerVehicle::class)->find($id); @@ -107,7 +107,7 @@ class CustomerVehicleController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -129,7 +129,7 @@ class CustomerVehicleController extends APIController if ($cv->getWarrantyExpiration() != null) $wty_ex = $cv->getWarrantyExpiration()->format('Y-m-d'); - $warranty = $mah->findWarranty($cv->getPlateNumber(), $em); + $warranty = $mah->findWarranty($cv->getPlateNumber()); $cv_name = ''; if ($cv->getName() != null) diff --git a/src/Controller/ResqAPI/PartnerController.php b/src/Controller/ResqAPI/PartnerController.php index ab9faa13..ff3c76eb 100644 --- a/src/Controller/ResqAPI/PartnerController.php +++ b/src/Controller/ResqAPI/PartnerController.php @@ -47,7 +47,7 @@ class PartnerController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -105,7 +105,7 @@ class PartnerController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -165,7 +165,7 @@ class PartnerController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); diff --git a/src/Controller/ResqAPI/RiderController.php b/src/Controller/ResqAPI/RiderController.php index b7f97783..875ec545 100644 --- a/src/Controller/ResqAPI/RiderController.php +++ b/src/Controller/ResqAPI/RiderController.php @@ -9,15 +9,14 @@ use Doctrine\ORM\Query; use Doctrine\ORM\EntityManagerInterface; use Catalyst\APIBundle\Controller\APIController; -// TODO: what do we use for response? APIResponse or APIResult? -// APIResult is what is used by APIController. APIResponse is what is used by CAPI use Catalyst\APIBundle\Response\APIResponse; -use App\Ramcar\APIResult; use App\Entity\Rider; use App\Entity\JobOrder; +use App\Entity\RiderRating; use App\Service\RiderTracker; +use App\Service\MobileAPIHandler; use App\Ramcar\JOStatus; use App\Ramcar\APIRiderStatus; @@ -33,25 +32,33 @@ class RiderController extends APIController $this->acl_gen = $acl_gen; } - // TODO: needs to be modified for mobile user - public function getRiderStatus(Request $req, RiderTracker $rt, EntityManagerInterface $em) + public function getRiderStatus(Request $req, RiderTracker $rt, EntityManagerInterface $em, + MobileAPIHandler $mah) { + $this->denyAccessUnlessGranted('mobile_rider.status.get', null, 'No access.'); + $required_params = []; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); // get customer - $cust = $this->session->getCustomer(); + $cust = $mobile_user->getCustomer(); if ($cust == null) - { - $res->setError(true) - ->setErrorMessage('No customer information found'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'No customer information found'); - $ongoing_jos = $this->getOngoingJobOrders($cust, $em); + $ongoing_jos = $mah->getOngoingJobOrders($cust); + $data = []; if (count($ongoing_jos) <= 0) { try @@ -68,10 +75,10 @@ class RiderController extends APIController catch (Exception $e) { // no pending - $res->setData([ - 'status' => APIRiderStatus::NO_PENDING_JO - ]); - return $res->getReturnResponse(); + $data[] = [ + 'status' => APIRiderStatus::NO_PENDING_JO, + ]; + return new APIResponse(true, 'No pending job order', $data); } // we got a recently fulfilled job order @@ -82,7 +89,7 @@ class RiderController extends APIController { $dest = $fulfill_jo->getCoordinates(); - $data = [ + $data[] = [ 'jo_id' => $fulfill_jo->getID(), 'service_type' => $fulfill_jo->getServiceType(), 'destination' => [ @@ -101,7 +108,9 @@ class RiderController extends APIController if ($rider->getImageFile() != null) $image_url = $url_prefix . '/uploads/' . $rider->getImageFile(); - $data['status'] = APIRiderStatus::RIDER_RATING; + $data[] = [ + 'status' => APIRiderStatus::RIDER_RATING + ]; // default rider location to hub $data['rider'] = [ 'id' => $rider->getID(), @@ -110,16 +119,15 @@ class RiderController extends APIController 'contact_num' => $rider->getContactNumber(), 'image_url' => $image_url, ]; - $res->setData($data); - return $res->getReturnResponse(); + return new APIResponse(true, 'Rider status found', $data); } } // no pending - $res->setData([ - 'status' => APIRiderStatus::NO_PENDING_JO - ]); - return $res->getReturnResponse(); + $data[] = [ + 'status' => APIRiderStatus::NO_PENDING_JO, + ]; + return new APIResponse(true, 'No pending job order', $data); } // get first jo that's pending @@ -174,77 +182,70 @@ class RiderController extends APIController 'lat' => $coord->getLatitude() ] ]; - $res->setData($data); - return $res->getReturnResponse(); + + return new APIResponse(true, 'Rider status found', $data); } - $res->setData($data); - - return $res->getReturnResponse(); + return new APIResponse(true, 'Rider status found', $data); } - // TODO: needs to be modified for mobile user - public function addRiderRating(Request $req, EntityManagerInterface $em) + public function addRiderRating(Request $req, EntityManagerInterface $em, + MobileAPIHandler $mah) { + $this->denyAccessUnlessGranted('mobile_rider.rating.add', null, 'No access.'); + $required_params = [ 'jo_id', 'rating', ]; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); // get customer - $cust = $this->session->getCustomer(); + $cust = $mobile_user->getCustomer(); if ($cust == null) - { - $res->setError(true) - ->setErrorMessage('No customer information found'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'No customer information found'); // get job order $jo_id = $req->request->get('jo_id'); $jo = $em->getRepository(JobOrder::class)->find($jo_id); if ($jo == null) - { - $res->setError(true) - ->setErrorMessage('No job order found'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'No job order found'); // get rider $rider = $jo->getRider(); if ($rider == null) - { - $res->setError(true) - ->setErrorMessage('No rider found'); - return $res->getReturnResponse(); - } + 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()) - { - $res->setError(true) - ->setErrorMessage('Job order was not initiated by customer'); - return $res->getReturnResponse(); - } + 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); + $data = []; // if rating is -1 if ($rating_num == -1) { $jo->setHasRiderRating(); $em->flush(); - $res->setData([]); - - return $res->getReturnResponse(); + return new APIResponse(false, 'No rider rating', $data); } @@ -267,102 +268,6 @@ class RiderController extends APIController // TODO: set average rating in rider entity - $res->setData([]); - - return $res->getReturnResponse(); - } - - protected function getOngoingJobOrders($cust, $em) - { - $ongoing_jos = $em->getRepository(JobOrder::class)->findBy([ - 'customer' => $cust, - 'status' => [JOStatus::PENDING, JOStatus::RIDER_ASSIGN, JOStatus::IN_TRANSIT, JOStatus::ASSIGNED, JOStatus::IN_PROGRESS], - ]); - - return $ongoing_jos; - } - - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkParamsAndKey(Request $req, $em, $params) - { - // TODO: depends on what we decide to return - // returns APIResult object - $res = new APIResult(); - - // check for api_key in query string - $api_key = $req->query->get('api_key'); - if (empty($api_key)) - { - $res->setError(true) - ->setErrorMessage('Missing API key'); - return $res; - } - - // check missing parameters - $missing = $this->checkMissingParameters($req, $params); - if (count($missing) > 0) - { - $miss_string = implode(', ', $missing); - $res->setError(true) - ->setErrorMessage('Missing parameter(s): ' . $miss_string); - return $res; - } - - // check api key - $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); - if ($mobile_user == null) - { - $res->setError(true) - ->setErrorMessage('Invalid API Key'); - return $res; - } - - // store session - $this->session = $sess; - - return $res; - } - - // TODO: this might not be needed if we use APIController's checkRequiredParameters - // or we put this into a service? - protected function checkMissingParameters(Request $req, $params = []) - { - $missing = []; - - // check if parameters are there - foreach ($params as $param) - { - if ($req->getMethod() == 'GET') - { - $check = $req->query->get($param); - if (empty($check)) - $missing[] = $param; - } - else if ($req->getMethod() == 'POST') - { - $check = $req->request->get($param); - if (empty($check)) - $missing[] = $param; - } - else - return $params; - } - - return $missing; - } - - // TODO: type hint entity manager - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkAPIKey($em, $api_key) - { - // find the api key (session id) - // TODO: user validation needs to be changed - $m_user = $em->getRepository(MobileUser::class)->find($api_key); - if ($m_user == null) - return null; - - return $m_user; + return new APIResponse(true, 'Rider rating added', $data); } } diff --git a/src/Controller/ResqAPI/ServiceController.php b/src/Controller/ResqAPI/ServiceController.php index 855aea92..e1b45dfa 100644 --- a/src/Controller/ResqAPI/ServiceController.php +++ b/src/Controller/ResqAPI/ServiceController.php @@ -41,7 +41,7 @@ class ServiceController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); diff --git a/src/Controller/ResqAPI/VehicleController.php b/src/Controller/ResqAPI/VehicleController.php index eb67b1fd..3f949aec 100644 --- a/src/Controller/ResqAPI/VehicleController.php +++ b/src/Controller/ResqAPI/VehicleController.php @@ -42,7 +42,7 @@ class VehicleController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); @@ -80,7 +80,7 @@ class VehicleController extends APIController $user_id = $this->getUser()->getID(); // get mobile user - $mobile_user = $mah->findMobileUser($em, $user_id); + $mobile_user = $mah->findMobileUser($user_id); if ($mobile_user == null) return new APIResponse(false, 'No mobile user found.'); diff --git a/src/Service/MobileAPIHandler.php b/src/Service/MobileAPIHandler.php index 4563eeff..124e4bfc 100644 --- a/src/Service/MobileAPIHandler.php +++ b/src/Service/MobileAPIHandler.php @@ -6,6 +6,9 @@ use Doctrine\ORM\EntityManagerInterface; use App\Entity\MobileUser; use App\Entity\Warranty; +use App\Entity\JobOrder; + +use App\Ramcar\JOStatus; class MobileAPIHandler { @@ -16,19 +19,19 @@ class MobileAPIHandler $this->em = $em; } - public function findMobileUser($em, $user_id) + public function findMobileUser($user_id) { // get capi user to link to mobile user - $mobile_user = $em->getRepository(MobileUser::class)->findOneBy(['capi_user_id' => $user_id]); + $mobile_user = $this->em->getRepository(MobileUser::class)->findOneBy(['capi_user_id' => $user_id]); return $mobile_user; } - public function findWarranty($plate_number, $em) + public function findWarranty($plate_number) { // NOTE: Modify the search for the latest warranty. This seems hacky. // get latest warranty using plate number - $warranty_results = $em->getRepository(Warranty::class)->findBy(['plate_number' => $plate_number], + $warranty_results = $this->em->getRepository(Warranty::class)->findBy(['plate_number' => $plate_number], ['date_create' => 'desc']); $warr = []; @@ -95,5 +98,13 @@ class MobileAPIHandler return $file_path; } + public function getOngoingJobOrders($cust) + { + $ongoing_jos = $this->em->getRepository(JobOrder::class)->findBy([ + 'customer' => $cust, + 'status' => [JOStatus::PENDING, JOStatus::RIDER_ASSIGN, JOStatus::IN_TRANSIT, JOStatus::ASSIGNED, JOStatus::IN_PROGRESS], + ]); + return $ongoing_jos; + } } -- 2.43.5 From bfc2ee089055d8e37aa6a92ba16096aa457ee737 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Fri, 9 Jul 2021 11:00:57 +0000 Subject: [PATCH 21/42] Modify JobOrderController. #591 --- config/api_acl.yaml | 5 + src/Controller/ResqAPI/JobOrderController.php | 622 +++++++++--------- 2 files changed, 298 insertions(+), 329 deletions(-) diff --git a/config/api_acl.yaml b/config/api_acl.yaml index 2499e003..9f280586 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -141,3 +141,8 @@ access_keys: label: Get Rider Status - id: mobile_rider.rating.add label: Add Rider Rating + - id: job_order + label: Mobile Job Order Access + acls: + - id: mobile_jo.request + label: Request Job Order diff --git a/src/Controller/ResqAPI/JobOrderController.php b/src/Controller/ResqAPI/JobOrderController.php index 1035c986..e22bd13b 100644 --- a/src/Controller/ResqAPI/JobOrderController.php +++ b/src/Controller/ResqAPI/JobOrderController.php @@ -11,10 +11,7 @@ use Doctrine\ORM\EntityManagerInterface; use CrEOF\Spatial\PHP\Types\Geometry\Point; use Catalyst\APIBundle\Controller\APIController; -// TODO: what do we use for response? APIResponse or APIResult? -// APIResult is what is used by APIController. APIResponse is what is used by CAPI use Catalyst\APIBundle\Response\APIResponse; -use App\Ramcar\APIResult; use App\Ramcar\WarrantyClass; use App\Ramcar\JOStatus; use App\Ramcar\AutoAssignStatus; @@ -37,6 +34,7 @@ use App\Service\HubDistributor; use App\Service\HubFilterLogger; use App\Service\HubFilteringGeoChecker; use App\Service\MapTools; +use App\Service\MobileAPIHandler; use App\Entity\JobOrder; use App\Entity\CustomerVehicle; @@ -55,15 +53,15 @@ class JobOrderController extends APIController $this->acl_gen = $acl_gen; } - // TODO: modify for MobileUser - // break this down into smaller functions - // do we still use this? public function requestJobOrder(Request $req, InvoiceGeneratorInterface $ic, GeofenceTracker $geo, InventoryManager $im, MQTTClient $mclient, RiderAssignmentHandlerInterface $rah, PromoLogger $promo_logger, EntityManagerInterface $em, HubSelector $hub_select, - HubDistributor $hub_dist, HubFilterLogger $hub_filter_logger, HubFilteringGeoChecker $hub_geofence) + HubDistributor $hub_dist, HubFilterLogger $hub_filter_logger, HubFilteringGeoChecker $hub_geofence, + MobileAPIHandler $mah) { - // check required parameters and api key + $this->denyAccessUnlessGranted('mobile_jo.request', null, 'No access.'); + + // check required parameters $required_params = [ 'service_type', 'cv_id', @@ -74,267 +72,59 @@ class JobOrderController extends APIController 'warranty', 'mode_of_payment', ]; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); - // trade in type - $trade_in = $req->request->get('trade_in'); + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); - // address - $address = $req->request->get('delivery_address', 'Set by mobile application'); + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); - // instructions - $instructions = $req->request->get('delivery_instructions', ''); + // get mobile user + $mobile_user = $mah->findMobileUser($user_id); - // longitude and latitude - $long = $req->request->get('long'); - $lat = $req->request->get('lat'); + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); - // 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(); - } + // validate request + $msg = $this->validateJORequest($req); + if ($msg) + return new APIResponse(false, $msg); $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')); + $this->setJOObject($jo, $req); // customer - $cust = $this->session->getCustomer(); + $cust = $mobile_user->getCustomer(); if ($cust == null) - { - $res->setError(true) - ->setErrorMessage('No customer information found'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'No customer information found'); + $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); + $msg = $this->setInvoiceCriteria($em, $icrit, $req, $cust, $jo); + if ($msg != null) + return new APIResponse(false, $msg); // send to invoice generator $invoice = $ic->generateInvoice($icrit); $jo->setInvoice($invoice); - // set more hub criteria fields + // set hub criteria details $hub_criteria = new HubCriteria(); - $hub_criteria->setPoint($jo->getCoordinates()); - - if ($hub_geofence->isCovered($long, $lat)) - { - // TODO: set this properly, since the other flags - // are on default values. - // if true, set other values for HubCriteria - // error_log('Area is covered by hub filtering'); - $hub_criteria->setJoType($jo->getServiceType()) - ->setPaymentMethod($jo->getModeOfPayment()) - ->setRoundRobin(true); - } - - // add battery to items - $sku = $batt->getSAPCode(); - if (!empty($sku)) - $hub_criteria->addItem($batt->getSAPCode(), 1); + $this->setHubCriteria($em, $hub_geofence, $hub_criteria, $jo); // find nearest hubs $nearest_hubs = $hub_select->find($hub_criteria); if (!empty($nearest_hubs)) - { - // go through the hub list, find the nearest hub - // with an available rider - //error_log('found nearest hub ' . $nearest_hub->getID()); - foreach ($nearest_hubs as $nearest_hub) - { - $available_riders = $nearest_hub['hub']->getAvailableRiders(); - if (count($available_riders) >= 1) - { - $assigned_rider = null; - if (count($available_riders) == 1) - { - $assigned_rider = $available_riders[0]; - } - else - { - // 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); - } - - $jo->setHub($nearest_hub['hub']); - $jo->setRider($assigned_rider); - $jo->setStatus(JOStatus::ASSIGNED); - $jo->setStatusAutoAssign(AutoAssignStatus::HUB_AND_RIDER_ASSIGNED); - - $assigned_rider->setAvailable(false); - - // update redis hub_jo_count for hub - $hub_dist->incrementJoCountForHub($nearest_hub['hub']); - - // break out of loop - break; - } - else - { - // log hub into hub_filter_log - $hub_filter_logger->logFilteredHub($nearest_hub['hub'], 'no_available_rider'); - // continue to go through list to find hub with an available rider - } - } - } + $this->assignRider($nearest_hubs, $jo, $hub_filter_logger); $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()); - } + $this->processEvents($em, $jo, $rah, $mclient); $em->flush(); @@ -364,40 +154,9 @@ class JobOrderController extends APIController 'invoice' => $invoice_data ]; - // check service type - if ($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) - { - $customer = $cv->getCustomer(); - $customer_tags = $customer->getCustomerTagObjects(); - if (!empty($customer_tags)) - { - foreach ($customer_tags as $customer_tag) - { - if ($customer_tag->getID() == $invoice->getUsedCustomerTagId()) - { - // remove associated entity - $customer->removeCustomerTag($customer_tag); + $this->removeCustomerTag($jo, $cv, $promo_logger, $mobile_user->getID()); - // log the availment of promo from customer - $created_by = $req->query->get('api_key');; - $cust_id = $jo->getCustomer()->getID(); - $cust_fname = $jo->getCustomer()->getFirstName(); - $cust_lname = $jo->getCustomer()->getLastName(); - $jo_id = $jo->getID(); - $invoice_id = $jo->getInvoice()->getID(); - // TODO: check if we store total price of invoice or just the discounted amount - $amount = $jo->getInvoice()->getTotalPrice(); - $promo_logger->logPromoInfo($created_by, $cust_id, $cust_fname, $cust_lname, $jo_id, - $invoice_id, $amount); - } - } - } - } - - // set data - $res->setData($data); - - return $res->getReturnResponse(); + return new APIResponse(true, 'Job order creatd', $data); } // TODO: modify for MobileUser @@ -1644,87 +1403,292 @@ class JobOrderController extends APIController return $time_selected; } - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkParamsAndKey(Request $req, $em, $params) + protected function validateJORequest(Request $req) { - // TODO: depends on what we decide to return - // returns APIResult object - $res = new APIResult(); - - // check for api_key in query string - $api_key = $req->query->get('api_key'); - if (empty($api_key)) + // geofence + $is_covered = $geo->isCovered($long, $lat); + if (!$is_covered) { - $res->setError(true) - ->setErrorMessage('Missing API key'); - return $res; + // TODO: put geofence error message in config file somewhere + $msg = '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 $msg; } - // check missing parameters - $missing = $this->checkMissingParameters($req, $params); - if (count($missing) > 0) + // validate service type + $stype = $req->request->get('service_type'); + if (!ServiceType::validate($stype)) { - $miss_string = implode(', ', $missing); - $res->setError(true) - ->setErrorMessage('Missing parameter(s): ' . $miss_string); - return $res; + $msg = 'Invalid service type'; + return $msg; } - // check api key - $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); - if ($mobile_user == null) + // validate warranty + $warr = $req->request->get('warranty'); + if (!WarrantyClass::validate($warr)) { - $res->setError(true) - ->setErrorMessage('Invalid API Key'); - return $res; + $msg = 'Invalid warranty class'; + return $msg; } - // store session - $this->session = $sess; + // validate payment method + $payment_method = $req->request->get('mode_of_payment'); + if (!ModeOfPayment::validate($payment_method)) + { + $msg = 'Invalid payment method'; + return $msg; + } - return $res; + return null; } - // TODO: this might not be needed if we use APIController's checkRequiredParameters - // or we put this into a service? - protected function checkMissingParameters(Request $req, $params = []) + protected function setJOObject(JobOrder $jo, Request $req) { - $missing = []; + // longitude and latitude + $long = $req->request->get('long'); + $lat = $req->request->get('lat'); - // check if parameters are there - foreach ($params as $param) + $point = new Point($long, $lat); + + $jo->setSource(TransactionOrigin::MOBILE_APP) + ->setStatus(JOStatus::PENDING) + ->setDeliveryInstructions('') + ->setTier1Notes('') + ->setTier2Notes('') + ->setDeliveryAddress($req->request->get('delivery_address', 'Set by mobile application')) + ->setTradeInType($req->request->get('trade_in')) + ->setDeliveryInstructions($req->request->get('delivery_instructions', '')) + ->setModeOfPayment($req->request->get('mode_of_payment')) + ->setServiceType($req->request->get('service_type')) + ->setWarrantyClass($req->request->get('warranty')) + ->setCoordinates($point); + } + + protected function setInvoiceCriteria(EntityManagerInterface $em, InvoiceCriteria $icrit, Request $req, + Customer $cust, JobOrder $jo) + { + $icrit->setServiceType($req->request->get('service_type')); + + // check promo + $promo_id = $req->request->get('promo_id'); + if (!empty($promo_id)) { - if ($req->getMethod() == 'GET') + $promo = $em->getRepository(Promo::class)->find($promo_id); + if ($promo == null) { - $check = $req->query->get($param); - if (empty($check)) - $missing[] = $param; + $msg = 'Invalid promo id'; + return $msg; } - else if ($req->getMethod() == 'POST') + + // put in criteria + $icrit->addPromo($promo); + } + + // check customer vehicle + $cv = $em->getRepository(CustomerVehicle::class)->find($req->request->get('cv_id')); + if ($cv == null) + { + $msg = 'Invalid customer vehicle id'; + return $msg; + } + $icrit->setCustomerVehicle($cv); + $jo->setCustomerVehicle($cv); + + // check if customer owns vehicle + if ($cust->getID() != $cv->getCustomer()->getID()) + { + $msg = 'Customer does not own vehicle'; + return $msg; + } + + // check battery + $batt_id = $req->request->get('batt_id'); + if ($batt_id != null) + { + $batt = $em->getRepository(Battery::class)->find($batt_id); + if ($batt == null) { - $check = $req->request->get($param); - if (empty($check)) - $missing[] = $param; + $msg = 'Invalid battery id'); + return $msg; + } + } + 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); + + return null; + } + + protected function setHubCriteria(EntityManagerInterface $em, HubFilteringGeoChecker $hub_geofence, + HubCriteria $hub_criteria, JobOrder $jo) + { + $hub_criteria->setPoint($jo->getCoordinates()); + $long = $jo->getCoordinates()->getLongitude(); + $lat = $jo->getCoordinates()->getLatitude(); + + if ($hub_geofence->isCovered($long, $lat)) + { + // TODO: set this properly, since the other flags + // are on default values. + // if true, set other values for HubCriteria + // error_log('Area is covered by hub filtering'); + $hub_criteria->setJoType($jo->getServiceType()) + ->setPaymentMethod($jo->getModeOfPayment()) + ->setRoundRobin(true); + } + + $batt_id = $req->request->get('batt_id'); + if ($batt_id != null) + { + $batt = $em->getRepository(Battery::class)->find($batt_id); + if ($batt != null) + { + // add battery to items + $sku = $batt->getSAPCode(); + if (!empty($sku)) + $hub_criteria->addItem($batt->getSAPCode(), 1); + } + } + } + + protected function assignRider($nearest_hubs, JobOrder $jo, HubFilterLogger $hub_filter_logger) + { + // try to assin rider + // go through the hub list, find the nearest hub + // with an available rider + //error_log('found nearest hub ' . $nearest_hub->getID()); + foreach ($nearest_hubs as $nearest_hub) + { + $available_riders = $nearest_hub['hub']->getAvailableRiders(); + if (count($available_riders) >= 1) + { + $assigned_rider = null; + if (count($available_riders) == 1) + { + $assigned_rider = $available_riders[0]; + } + else + { + // 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); + } + + $jo->setHub($nearest_hub['hub']); + $jo->setRider($assigned_rider); + $jo->setStatus(JOStatus::ASSIGNED); + $jo->setStatusAutoAssign(AutoAssignStatus::HUB_AND_RIDER_ASSIGNED); + + $assigned_rider->setAvailable(false); + + // update redis hub_jo_count for hub + $hub_dist->incrementJoCountForHub($nearest_hub['hub']); + + // break out of loop + break; } else - return $params; + { + // log hub into hub_filter_log + $hub_filter_logger->logFilteredHub($nearest_hub['hub'], 'no_available_rider'); + // continue to go through list to find hub with an available rider + } } - - return $missing; } - // TODO: type hint entity manager - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkAPIKey($em, $api_key) + protected function processEvents(EntityManagerInterface $em, JobOrder $jo, + RiderAssignmentHandlerInterface $rah, MQTTClient $mclient) { - // find the api key (session id) - // TODO: user validation needs to be changed - $m_user = $em->getRepository(MobileUser::class)->find($api_key); - if ($m_user == null) - return null; + // add event log for JO + $event = new JOEvent(); + $event->setDateHappen(new DateTime()) + ->setTypeID(JOEventType::CREATE) + ->setJobOrder($jo); + $em->persist($event); - return $m_user; + // 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()); + } + } + + protected function removeCustomerTag(JobOrder $jo, CustomerVehicle $cv, PromoLogger $promo_logger, $mobile_user_id) + { + // check service type + if ($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) + { + $customer = $cv->getCustomer(); + $customer_tags = $customer->getCustomerTagObjects(); + if (!empty($customer_tags)) + { + foreach ($customer_tags as $customer_tag) + { + if ($customer_tag->getID() == $invoice->getUsedCustomerTagId()) + { + // remove associated entity + $customer->removeCustomerTag($customer_tag); + + // log the availment of promo from customer + $created_by = $mobile_user_id; + $cust_id = $jo->getCustomer()->getID(); + $cust_fname = $jo->getCustomer()->getFirstName(); + $cust_lname = $jo->getCustomer()->getLastName(); + $jo_id = $jo->getID(); + $invoice_id = $jo->getInvoice()->getID(); + // TODO: check if we store total price of invoice or just the discounted amount + $amount = $jo->getInvoice()->getTotalPrice(); + $promo_logger->logPromoInfo($created_by, $cust_id, $cust_fname, $cust_lname, $jo_id, + $invoice_id, $amount); + } + } + } + } } } -- 2.43.5 From 782a0493fc069dbdb2b3e221a57709cda2e54577 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 12 Jul 2021 04:25:14 +0000 Subject: [PATCH 22/42] Break down requestJobOrder into smaller functions. #591 --- src/Controller/ResqAPI/JobOrderController.php | 26 ++++++++++++------- .../InvoiceGenerator/ResqInvoiceGenerator.php | 4 ++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/Controller/ResqAPI/JobOrderController.php b/src/Controller/ResqAPI/JobOrderController.php index e22bd13b..1aa4b0fc 100644 --- a/src/Controller/ResqAPI/JobOrderController.php +++ b/src/Controller/ResqAPI/JobOrderController.php @@ -21,6 +21,7 @@ use App\Ramcar\TransactionOrigin; use App\Ramcar\TradeInType; use App\Ramcar\JOEventType; use App\Ramcar\HubCriteria; +use App\Ramcar\ModeOfPayment; use App\Service\InvoiceGeneratorInterface; use App\Service\RisingTideGateway; @@ -41,9 +42,12 @@ use App\Entity\CustomerVehicle; use App\Entity\Promo; use App\Entity\Battery; use App\Entity\JOEvent; +use App\Entity\Customer; use Catalyst\APIBundle\Access\Generator as ACLGenerator; +use DateTime; + class JobOrderController extends APIController { protected $acl_gen; @@ -87,7 +91,7 @@ class JobOrderController extends APIController return new APIResponse(false, 'No mobile user found.'); // validate request - $msg = $this->validateJORequest($req); + $msg = $this->validateJORequest($req, $geo); if ($msg) return new APIResponse(false, $msg); @@ -113,13 +117,13 @@ class JobOrderController extends APIController // set hub criteria details $hub_criteria = new HubCriteria(); - $this->setHubCriteria($em, $hub_geofence, $hub_criteria, $jo); + $this->setHubCriteria($em, $hub_geofence, $hub_criteria, $jo, $req); // find nearest hubs $nearest_hubs = $hub_select->find($hub_criteria); if (!empty($nearest_hubs)) - $this->assignRider($nearest_hubs, $jo, $hub_filter_logger); + $this->assignRider($nearest_hubs, $jo, $hub_filter_logger, $hub_dist); $em->persist($jo); $em->persist($invoice); @@ -154,7 +158,7 @@ class JobOrderController extends APIController 'invoice' => $invoice_data ]; - $this->removeCustomerTag($jo, $cv, $promo_logger, $mobile_user->getID()); + $this->removeCustomerTag($jo, $jo->getCustomerVehicle(), $promo_logger, $mobile_user->getID()); return new APIResponse(true, 'Job order creatd', $data); } @@ -1403,9 +1407,11 @@ class JobOrderController extends APIController return $time_selected; } - protected function validateJORequest(Request $req) + protected function validateJORequest(Request $req, GeofenceTracker $geo) { // geofence + $long = $req->request->get('long'); + $lat = $req->request->get('lat'); $is_covered = $geo->isCovered($long, $lat); if (!$is_covered) { @@ -1507,7 +1513,7 @@ class JobOrderController extends APIController $batt = $em->getRepository(Battery::class)->find($batt_id); if ($batt == null) { - $msg = 'Invalid battery id'); + $msg = 'Invalid battery id'; return $msg; } } @@ -1521,6 +1527,7 @@ class JobOrderController extends APIController // check trade-in // only allow motolite, other, none + $trade_in = $req->request->get('trade_in'); switch ($trade_in) { case TradeInType::MOTOLITE: @@ -1538,7 +1545,7 @@ class JobOrderController extends APIController } protected function setHubCriteria(EntityManagerInterface $em, HubFilteringGeoChecker $hub_geofence, - HubCriteria $hub_criteria, JobOrder $jo) + HubCriteria $hub_criteria, JobOrder $jo, Request $req) { $hub_criteria->setPoint($jo->getCoordinates()); $long = $jo->getCoordinates()->getLongitude(); @@ -1569,7 +1576,8 @@ class JobOrderController extends APIController } } - protected function assignRider($nearest_hubs, JobOrder $jo, HubFilterLogger $hub_filter_logger) + protected function assignRider($nearest_hubs, JobOrder $jo, HubFilterLogger $hub_filter_logger, + HubDistributor $hub_dist) { // try to assin rider // go through the hub list, find the nearest hub @@ -1615,7 +1623,7 @@ class JobOrderController extends APIController else { // log hub into hub_filter_log - $hub_filter_logger->logFilteredHub($nearest_hub['hub'], 'no_available_rider'); + $hub_filter_logger->logFilteredHub($nearest_hub['hub'], 'no_available_rider', $jo->getID(), $jo->getCustomer()->getID()); // continue to go through list to find hub with an available rider } } diff --git a/src/Service/InvoiceGenerator/ResqInvoiceGenerator.php b/src/Service/InvoiceGenerator/ResqInvoiceGenerator.php index 47d8728e..d3e3e4cc 100644 --- a/src/Service/InvoiceGenerator/ResqInvoiceGenerator.php +++ b/src/Service/InvoiceGenerator/ResqInvoiceGenerator.php @@ -123,7 +123,9 @@ class ResqInvoiceGenerator implements InvoiceGeneratorInterface // get current user $user = $this->security->getUser(); - if ($user != null) + // check if user is User or APIUser + //if ($user != null) + if ($user instanceof User) { $invoice->setCreatedBy($user); } -- 2.43.5 From 518d5bb9d5c0b82e246e9a389b8c6b357cdfd327 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 12 Jul 2021 06:26:25 +0000 Subject: [PATCH 23/42] Break down newRequestJobOrder into smaller functions. #591 --- src/Controller/ResqAPI/JobOrderController.php | 389 ++++-------------- 1 file changed, 78 insertions(+), 311 deletions(-) diff --git a/src/Controller/ResqAPI/JobOrderController.php b/src/Controller/ResqAPI/JobOrderController.php index 1aa4b0fc..1302bf21 100644 --- a/src/Controller/ResqAPI/JobOrderController.php +++ b/src/Controller/ResqAPI/JobOrderController.php @@ -14,6 +14,7 @@ use Catalyst\APIBundle\Controller\APIController; use Catalyst\APIBundle\Response\APIResponse; use App\Ramcar\WarrantyClass; use App\Ramcar\JOStatus; +use App\Ramcar\AdvanceOrderSlot; use App\Ramcar\AutoAssignStatus; use App\Ramcar\InvoiceCriteria; use App\Ramcar\ServiceType; @@ -43,6 +44,7 @@ use App\Entity\Promo; use App\Entity\Battery; use App\Entity\JOEvent; use App\Entity\Customer; +use App\Entity\Hub; use Catalyst\APIBundle\Access\Generator as ACLGenerator; @@ -96,7 +98,7 @@ class JobOrderController extends APIController return new APIResponse(false, $msg); $jo = new JobOrder(); - $this->setJOObject($jo, $req); + $this->setJOObject($jo, $req, $em); // customer $cust = $mobile_user->getCustomer(); @@ -160,19 +162,19 @@ class JobOrderController extends APIController $this->removeCustomerTag($jo, $jo->getCustomerVehicle(), $promo_logger, $mobile_user->getID()); - return new APIResponse(true, 'Job order creatd', $data); + return new APIResponse(true, 'Job order created', $data); } - // TODO: modify for MobileUser - // break this down into smaller functions - // do we still use this? public function newRequestJobOrder(Request $req, InvoiceGeneratorInterface $ic, GeofenceTracker $geo, MapTools $map_tools, InventoryManager $im, MQTTClient $mclient, RiderAssignmentHandlerInterface $rah, PromoLogger $promo_logger, HubSelector $hub_select, HubDistributor $hub_dist, HubFilterLogger $hub_filter_logger, - HubFilteringGeoChecker $hub_geofence, EntityManagerInterface $em) + HubFilteringGeoChecker $hub_geofence, EntityManagerInterface $em, + MobileAPIHandler $mah) { - // check required parameters and api key + $this->denyAccessUnlessGranted('mobile_jo.request', null, 'No access.'); + + // check required parameters $required_params = [ 'service_type', 'cv_id', @@ -182,168 +184,40 @@ class JobOrderController extends APIController 'warranty', 'mode_of_payment', ]; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); - // trade in type - $trade_in = $req->request->get('trade_in'); + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); - // address - $address = $req->request->get('delivery_address', 'Set by mobile application'); + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); - // instructions - $instructions = $req->request->get('delivery_instructions', ''); + // get mobile user + $mobile_user = $mah->findMobileUser($user_id); - // longitude and latitude - $long = $req->request->get('long'); - $lat = $req->request->get('lat'); + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); - // 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'); - // check for 'false' text - if ($advance_order === false || $advance_order === 0 || $advance_order === '0' || $advance_order == 'false') - $flag_advance_order = false; - else - $flag_advance_order = true; + // validate request + $msg = $this->validateJORequest($req, $geo); + if ($msg) + return new APIResponse(false, $msg); $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) - ->setStatusAutoAssign(AutoAssignStatus::NOT_ASSIGNED); + $this->setJOObject($jo, $req, $em); // customer - $cust = $this->session->getCustomer(); + $cust = $mobile_user->getCustomer(); if ($cust == null) - { - $res->setError(true) - ->setErrorMessage('No customer information found'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'No customer information found'); + $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); + $msg = $this->setInvoiceCriteria($em, $icrit, $req, $cust, $jo); + if ($msg != null) + return new APIResponse(false, $msg); // send to invoice generator $invoice = $ic->generateInvoice($icrit); @@ -351,84 +225,24 @@ class JobOrderController extends APIController // assign hub and rider // check if hub is null - if ($hub == null) + if ($jo->getHub() == null) { + // set hub criteria details $hub_criteria = new HubCriteria(); - $hub_criteria->setPoint($jo->getCoordinates()); - - if ($hub_geofence->isCovered($long, $lat)) - { - // if true, set other values for HubCriteria - // TODO: set this properly, since the other flags - // are on default values - // error_log('Area is covered by hub filtering'); - $hub_criteria->setJoType($jo->getServiceType()) - ->setPaymentMethod($jo->getModeOfPayment()) - ->setRoundRobin(true); - } - - // add battery to items - $sku = $batt->getSAPCode(); - if (!empty($sku)) - $hub_criteria->addItem($batt->getSAPCode(), 1); + $this->setHubCriteria($em, $hub_geofence, $hub_criteria, $jo, $req); // find nearest hubs $nearest_hubs = $hub_select->find($hub_criteria); if (!empty($nearest_hubs)) - { - // go through the hub list, find the nearest hub - // with an available rider - //error_log('found nearest hub ' . $nearest_hub->getID()); - foreach ($nearest_hubs as $nearest_hub) - { - $available_riders = $nearest_hub['hub']->getAvailableRiders(); - if (count($available_riders) >= 1) - { - $assigned_rider = null; - if (count($available_riders) == 1) - { - $assigned_rider = $available_riders[0]; - } - else - { - // 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); - } - - $jo->setHub($nearest_hub['hub']); - $jo->setRider($assigned_rider); - $jo->setStatus(JOStatus::ASSIGNED); - $jo->setStatusAutoAssign(AutoAssignStatus::HUB_AND_RIDER_ASSIGNED); - - $assigned_rider->setAvailable(false); - - // update redis hub_jo_count for hub - $hub_dist->incrementJoCountForHub($nearest_hub['hub']); - - // break out of loop - break; - } - else - { - // log hub into hub_filter_log - $hub_filter_logger->logFilteredHub($nearest_hub['hub'], 'no_available_rider'); - // continue to go through list to find hub with an available rider - } - } - } + $this->assignRider($nearest_hubs, $jo, $hub_filter_logger, $hub_dist); } else { + $schedule_date = $req->request->get('date_schedule'); + $slot_id = $req->request->get('slot_id'); $date_schedule = null; + if ((strlen($schedule_date) > 0) && (strlen($slot_id) > 0)) { $time_schedule = $this->getTimeFromSlot($slot_id); @@ -436,11 +250,10 @@ class JobOrderController extends APIController { $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')); + error_log($date_schedule->format('Y-m-d H:i')); } } - $jo->setHub($hub); $jo->setStatus(JOStatus::RIDER_ASSIGN); $jo->setStatusAutoAssign(AutoAssignStatus::HUB_ASSIGNED); @@ -448,62 +261,13 @@ class JobOrderController extends APIController $jo->setDateSchedule($date_schedule); // update redis hub_jo_count for hub - $hub_dist->incrementJoCountForHub($hub); + $hub_dist->incrementJoCountForHub($jo->getHub()); } $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); - } + $this->processEvents($em, $jo, $rah, $mclient); $em->flush(); @@ -533,41 +297,9 @@ class JobOrderController extends APIController 'invoice' => $invoice_data ]; - // need to check for customer tag/promo - // check service type - if ($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) - { - $customer = $cv->getCustomer(); - $customer_tags = $customer->getCustomerTagObjects(); - if (!empty($customer_tags)) - { - foreach ($customer_tags as $customer_tag) - { - if ($customer_tag->getID() == $invoice->getUsedCustomerTagId()) - { - // remove associated entity - $customer->removeCustomerTag($customer_tag); + $this->removeCustomerTag($jo, $jo->getCustomerVehicle(), $promo_logger, $mobile_user->getID()); - // log the availment of promo from customer - $created_by = $req->query->get('api_key');; - $cust_id = $jo->getCustomer()->getID(); - $cust_fname = $jo->getCustomer()->getFirstName(); - $cust_lname = $jo->getCustomer()->getLastName(); - $jo_id = $jo->getID(); - $invoice_id = $jo->getInvoice()->getID(); - // TODO: check if we store total price of invoice or just the discounted amount - $amount = $jo->getInvoice()->getTotalPrice(); - $promo_logger->logPromoInfo($created_by, $cust_id, $cust_fname, $cust_lname, $jo_id, - $invoice_id, $amount); - } - } - } - } - - // set data - $res->setData($data); - - return $res->getReturnResponse(); + return new APIResponse(true, 'Job order created', $data); } // TODO: modify for MobileUser @@ -1447,7 +1179,7 @@ class JobOrderController extends APIController return null; } - protected function setJOObject(JobOrder $jo, Request $req) + protected function setJOObject(JobOrder $jo, Request $req, EntityManagerInterface $em) { // longitude and latitude $long = $req->request->get('long'); @@ -1455,6 +1187,23 @@ class JobOrderController extends APIController $point = new Point($long, $lat); + // check for hub + $hub = null; + $hub_id = $req->request->get('hub_id'); + if (strlen($hub_id) > 0) + { + $hub = $em->getRepository(Hub::class)->find($hub_id); + $jo->setHub($hub); + } + + // check if advance order + $advance_order = $req->request->get('flag_advance_order'); + // check for 'false' text + if ($advance_order === false || $advance_order === 0 || $advance_order === '0' || $advance_order == 'false') + $flag_advance_order = false; + else + $flag_advance_order = true; + $jo->setSource(TransactionOrigin::MOBILE_APP) ->setStatus(JOStatus::PENDING) ->setDeliveryInstructions('') @@ -1466,7 +1215,9 @@ class JobOrderController extends APIController ->setModeOfPayment($req->request->get('mode_of_payment')) ->setServiceType($req->request->get('service_type')) ->setWarrantyClass($req->request->get('warranty')) - ->setCoordinates($point); + ->setCoordinates($point) + ->setAdvanceOrder($flag_advance_order) + ->setStatusAutoAssign(AutoAssignStatus::NOT_ASSIGNED); } protected function setInvoiceCriteria(EntityManagerInterface $em, InvoiceCriteria $icrit, Request $req, @@ -1665,6 +1416,22 @@ class JobOrderController extends APIController $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); + } } protected function removeCustomerTag(JobOrder $jo, CustomerVehicle $cv, PromoLogger $promo_logger, $mobile_user_id) -- 2.43.5 From f45f7fd411dbf2b980911a10f967c70a917a87e7 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 12 Jul 2021 07:08:59 +0000 Subject: [PATCH 24/42] Modify getEstimate. #591 --- config/api_acl.yaml | 2 + src/Controller/ResqAPI/JobOrderController.php | 220 +++++------------- 2 files changed, 66 insertions(+), 156 deletions(-) diff --git a/config/api_acl.yaml b/config/api_acl.yaml index 9f280586..eae96849 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -146,3 +146,5 @@ access_keys: acls: - id: mobile_jo.request label: Request Job Order + - id: mobile_jo.get.estimate + label: Get Estimate diff --git a/src/Controller/ResqAPI/JobOrderController.php b/src/Controller/ResqAPI/JobOrderController.php index 1302bf21..3c7e2ea1 100644 --- a/src/Controller/ResqAPI/JobOrderController.php +++ b/src/Controller/ResqAPI/JobOrderController.php @@ -134,25 +134,7 @@ class JobOrderController extends APIController $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; + $invoice_data = $this->makeInvoiceData($invoice, $mah, $req); // make job order data $data = [ @@ -272,24 +254,7 @@ class JobOrderController extends APIController $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; + $invoice_data = $this->makeInvoiceData($invoice, $mah, $req); // make job order data $data = [ @@ -302,143 +267,50 @@ class JobOrderController extends APIController return new APIResponse(true, 'Job order created', $data); } - // TODO: modify for MobileUser - public function getEstimate(Request $req, InvoiceGeneratorInterface $ic, EntityManagerInterface $em) + public function getEstimate(Request $req, InvoiceGeneratorInterface $ic, EntityManagerInterface $em, + MobileAPIHandler $mah) { - // $this->debugRequest($req); + $this->denyAccessUnlessGranted('mobile_jo.get.estimate', null, 'No access.'); - // check required parameters and api key + // check required parameters $required_params = [ 'service_type', 'cv_id', // 'batt_id', 'trade_in', ]; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); // customer - $cust = $this->session->getCustomer(); + $cust = $mobile_user->getCustomer(); if ($cust == null) - { - $res->setError(true) - ->setErrorMessage('No customer information found'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'No customer information found'); // make invoice criteria $icrit = new InvoiceCriteria(); - $icrit->setServiceType($req->request->get('service_type')); - - // 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); - - // 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 - $trade_in = $req->request->get('trade_in'); - switch ($trade_in) - { - case TradeInType::MOTOLITE: - case TradeInType::OTHER: - break; - - default: - $trade_in = ''; - break; - } - - $icrit->addEntry($batt, $trade_in, 1); + $msg = $this->setInvoiceCriteria($em, $icrit, $req, $cust, null); + if ($msg != null) + return new APIResponse(false, $msg); // send to invoice generator $invoice = $ic->generateInvoice($icrit); // make invoice json data - $data = [ - 'total_price' => (float) $invoice->getTotalPrice(), - 'vat_ex_price' => (float) $invoice->getVATExclusivePrice(), - 'vat' => (float) $invoice->getVAT(), - 'discount' => (float) $invoice->getDiscount(), - 'trade_in' => (float) $invoice->getTradeIn(), - ]; - $items = $invoice->getItems(); - $items_data = []; - foreach ($items as $item) - { - $my_data = [ - 'title' => $item->getTitle(), - 'qty' => (int) $item->getQuantity() + 0, - 'price' => (float) $item->getPrice() + 0.0, - ]; + $invoice_data = $this->makeInvoiceData($invoice, $mah, $req); - $item_batt = $item->getBattery(); - if ($item_batt != null) - { - $my_data['image_url'] = $this->getBatteryImageURL($req, $item_batt); - } - - $items_data[] = $my_data; - } - - $data['items'] = $items_data; - - // error_log(print_r($data, true)); - - // set data - $res->setData($data); - - return $res->getReturnResponse(); + return new APIResponse(true, 'Estimate found', $invoice_data); } // TODO: modify for MobileUser @@ -1221,7 +1093,7 @@ class JobOrderController extends APIController } protected function setInvoiceCriteria(EntityManagerInterface $em, InvoiceCriteria $icrit, Request $req, - Customer $cust, JobOrder $jo) + Customer $cust, $jo) { $icrit->setServiceType($req->request->get('service_type')); @@ -1248,7 +1120,8 @@ class JobOrderController extends APIController return $msg; } $icrit->setCustomerVehicle($cv); - $jo->setCustomerVehicle($cv); + if ($jo != null) + $jo->setCustomerVehicle($cv); // check if customer owns vehicle if ($cust->getID() != $cv->getCustomer()->getID()) @@ -1434,6 +1307,41 @@ class JobOrderController extends APIController } } + protected function makeInvoiceData($invoice, $mah, $req) + { + // 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) + { + $my_data = [ + 'title' => $item->getTitle(), + 'qty' => (int) $item->getQuantity() + 0, + 'price' => (float) $item->getPrice() + 0.0, + ]; + + $item_batt = $item->getBattery(); + if ($item_batt != null) + { + // generate the url for image + $battery_image_url = $this->generateUrl('static_battery_image'); + $my_data['image_url'] = $mah->getBatteryImageURL($req, $item_batt, $battery_image_url); + } + + $items_data[] = $my_data; + } + + $invoice_data['items'] = $items_data; + return $invoice_data; + } + protected function removeCustomerTag(JobOrder $jo, CustomerVehicle $cv, PromoLogger $promo_logger, $mobile_user_id) { // check service type -- 2.43.5 From 3ebf6b6c96f86e2561d4dcd7fcc179236dbec9b3 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 12 Jul 2021 08:47:48 +0000 Subject: [PATCH 25/42] Modify JobOrderController. Separate sending of MQTT events from creation of JO events. #591 --- config/api_acl.yaml | 4 + src/Controller/ResqAPI/JobOrderController.php | 159 ++++++++++-------- 2 files changed, 89 insertions(+), 74 deletions(-) diff --git a/config/api_acl.yaml b/config/api_acl.yaml index eae96849..199e34c8 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -148,3 +148,7 @@ access_keys: label: Request Job Order - id: mobile_jo.get.estimate label: Get Estimate + - id: mobile_jo.get.ongoing + label: Get Ongoing Job Order + - id: mobile_jo.cancel + label: Cancel Job Order diff --git a/src/Controller/ResqAPI/JobOrderController.php b/src/Controller/ResqAPI/JobOrderController.php index 3c7e2ea1..4352901f 100644 --- a/src/Controller/ResqAPI/JobOrderController.php +++ b/src/Controller/ResqAPI/JobOrderController.php @@ -12,6 +12,7 @@ use CrEOF\Spatial\PHP\Types\Geometry\Point; use Catalyst\APIBundle\Controller\APIController; use Catalyst\APIBundle\Response\APIResponse; + use App\Ramcar\WarrantyClass; use App\Ramcar\JOStatus; use App\Ramcar\AdvanceOrderSlot; @@ -130,7 +131,14 @@ class JobOrderController extends APIController $em->persist($jo); $em->persist($invoice); - $this->processEvents($em, $jo, $rah, $mclient); + // create JO event logs + $this->processEvents($em, $jo, $rah, $mclient, JOEventType::CREATE); + + // send mqtt events + $payload = [ + 'event' => 'outlet_assign' + ]; + $this->processMQTTEvents($jo, $payload, $mclient, $rah); $em->flush(); @@ -249,7 +257,14 @@ class JobOrderController extends APIController $em->persist($jo); $em->persist($invoice); - $this->processEvents($em, $jo, $rah, $mclient); + // create JO event logs + $this->processEvents($em, $jo, $rah, $mclient, JOEventType::CREATE); + + // send mqtt events + $payload = [ + 'event' => 'outlet_assign' + ]; + $this->processMQTTEvents($jo, $payload, $mclient, $rah); $em->flush(); @@ -313,31 +328,30 @@ class JobOrderController extends APIController return new APIResponse(true, 'Estimate found', $invoice_data); } - // TODO: modify for MobileUser - public function getOngoing(Request $req, EntityManagerInterface $em) + public function getOngoing(Request $req, EntityManagerInterface $em, MobileAPIHandler $mah) { + $this->denyAccessUnlessGranted('mobile_jo.get.ongoing', null, 'No access.'); + $required_params = []; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); - // get customer - $cust = $this->session->getCustomer(); + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); + + // customer + $cust = $mobile_user->getCustomer(); if ($cust == null) - { - $res->setError(true) - ->setErrorMessage('No customer information found'); - return $res->getReturnResponse(); - } + 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, $em); + $ongoing_jos = $mah->getOngoingJobOrders($cust); // initialize data $data = []; @@ -356,76 +370,68 @@ class JobOrderController extends APIController ]; } - $res->setData($data); - - return $res->getReturnResponse(); + return new APIResponse(true, 'Ongoing job orders found.', $data); } - // TODO: modify for MobileUser - public function cancelJobOrder(Request $req, MQTTClient $mclient, EntityManagerInterface $em) + public function cancelJobOrder(Request $req, MQTTClient $mclient, EntityManagerInterface $em, + MobileAPIHandler $mah, RiderAssignmentHandlerInterface $rah) { + $this->denyAccessUnlessGranted('mobile_jo.cancel', null, 'No access.'); + $required_params = [ 'jo_id', 'reason' ]; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); // get job order $jo_id = $req->request->get('jo_id'); $jo = $em->getRepository(JobOrder::class)->find($jo_id); if ($jo == null) - { - $res->setError(true) - ->setErrorMessage('No job order found'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'No job order found'); // get customer - $cust = $this->session->getCustomer(); + $cust = $mobile_user->getCustomer(); if ($cust == null) - { - $res->setError(true) - ->setErrorMessage('No customer information found'); - return $res->getReturnResponse(); - } + new APIResponse(false, 'No customer information found'); // check that the customer owns the job order $jo_cust = $jo->getCustomer(); if ($jo_cust->getID() != $cust->getID()) - { - $res->setError(true) - ->setErrorMessage('Job order was not initiated by customer'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'Job order was not initiated by customer'); // TODO: check job order status, if it's cancellable - $cancel_reason = $req->request->get('reason'); + $cancel_reason = $req->request->get('reason'); $jo->cancel($cancel_reason); - // add event log - $event = new JOEvent(); - $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::CANCEL) - ->setJobOrder($jo); - $em->persist($event); + // create event logs + $this->processEvents($em, $jo, $rah, $mclient, JOEventType::CANCEL); - $em->flush(); - - // send mobile app event + // send mqtt events $payload = [ 'event' => 'cancelled', 'reason' => $cancel_reason, 'jo_id' => $jo->getID(), ]; - // $mclient->sendEvent($jo, $payload); - $mclient->sendRiderEvent($jo, $payload); + $this->processMQTTEvents($jo, $payload, $mclient, $rah); - $res->setData([]); + $em->flush(); - return $res->getReturnResponse(); + $data = []; + return new APIResponse(true, 'Job order cancelled', $data); } // TODO: modify for MobileUser @@ -1254,12 +1260,13 @@ class JobOrderController extends APIController } protected function processEvents(EntityManagerInterface $em, JobOrder $jo, - RiderAssignmentHandlerInterface $rah, MQTTClient $mclient) + RiderAssignmentHandlerInterface $rah, MQTTClient $mclient, + $jo_event_type) { // add event log for JO $event = new JOEvent(); $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::CREATE) + ->setTypeID($jo_event_type) ->setJobOrder($jo); $em->persist($event); @@ -1280,14 +1287,6 @@ class JobOrderController extends APIController ->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) { @@ -1298,12 +1297,24 @@ class JobOrderController extends APIController ->setJobOrder($jo); $em->persist($hub_assign_event); + } + } - // user mqtt event - $payload = [ - 'event' => 'outlet_assign' - ]; + protected function processMQTTEvents($jo, $payload, $mclient, $rah) + { + // check JO status + if ($jo->getStatus() == JOStatus::ASSIGNED) + { $mclient->sendEvent($jo, $payload); + $rah->assignJobOrder($jo, $jo->getRider()); + } + if ($jo->getStatus() == JOStatus::RIDER_ASSIGN) + { + $mclient->sendEvent($jo, $payload); + } + if ($jo->getStatus() == JOStatus::CANCELLED) + { + $mclient->sendRiderEvent($jo, $payload); } } -- 2.43.5 From baaa8327941883ca42dd15c4a51e13985acb7cdc Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 12 Jul 2021 09:26:28 +0000 Subject: [PATCH 26/42] Modify getJOHIstory in JobOrderController . #591 --- config/api_acl.yaml | 2 + src/Controller/ResqAPI/JobOrderController.php | 217 +++++++++++------- 2 files changed, 140 insertions(+), 79 deletions(-) diff --git a/config/api_acl.yaml b/config/api_acl.yaml index 199e34c8..fb2c8e5d 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -152,3 +152,5 @@ access_keys: label: Get Ongoing Job Order - id: mobile_jo.cancel label: Cancel Job Order + - id: mobile_jo.get.history + label: Get Job Order History diff --git a/src/Controller/ResqAPI/JobOrderController.php b/src/Controller/ResqAPI/JobOrderController.php index 4352901f..0daa1fc8 100644 --- a/src/Controller/ResqAPI/JobOrderController.php +++ b/src/Controller/ResqAPI/JobOrderController.php @@ -24,6 +24,7 @@ use App\Ramcar\TradeInType; use App\Ramcar\JOEventType; use App\Ramcar\HubCriteria; use App\Ramcar\ModeOfPayment; +use App\Ramcar\APIRiderStatus; use App\Service\InvoiceGeneratorInterface; use App\Service\RisingTideGateway; @@ -38,6 +39,7 @@ use App\Service\HubFilterLogger; use App\Service\HubFilteringGeoChecker; use App\Service\MapTools; use App\Service\MobileAPIHandler; +use App\Service\RiderTracker; use App\Entity\JobOrder; use App\Entity\CustomerVehicle; @@ -434,99 +436,44 @@ class JobOrderController extends APIController return new APIResponse(true, 'Job order cancelled', $data); } - // TODO: modify for MobileUser - public function getJOHistory(Request $req, EntityManagerInterface $em) + public function getJOHistory(Request $req, EntityManagerInterface $em, MobileAPIHandler $mah, + RiderTracker $rt) { - $res = $this->checkParamsAndKey($req, $em, []); - if ($res->isError()) - return $res->getReturnResponse(); + $this->denyAccessUnlessGranted('mobile_jo.get.history', null, 'No access.'); - // get customer - $cust = $this->session->getCustomer(); + $required_params = []; + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); + + // customer + $cust = $mobile_user->getCustomer(); if ($cust == null) - { - $res->setError(true) - ->setErrorMessage('No customer information found'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'No customer information found'); // get job orders $all_jo_data = []; $jos = $cust->getJobOrders(); foreach ($jos as $jo) { - $status = $jo->getStatus(); - - $jo_data = [ - 'id' => $jo->getID(), - 'date_create' => $jo->getDateCreate()->format('M d, Y'), - 'service_type' => $jo->getServiceType(), - 'status' => $status, - ]; - - // 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, - ]; - - // rider - $rider = $jo->getRider(); - if ($rider != null) - { - $jo_data['rider'] = $rider->getFullName(); - } - - // 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; - } - - $all_jo_data[] = $jo_data; + $all_jo_data[] = $this->generateJobOrderData($req, $jo, $rt, $mah); } // return data $data = [ 'job_orders' => $all_jo_data ]; - $res->setData($data); - // response - return $res->getReturnResponse(); + return new APIResponse(true, 'Job order history found', $data); } // TODO: modify for MobileUser @@ -1300,7 +1247,8 @@ class JobOrderController extends APIController } } - protected function processMQTTEvents($jo, $payload, $mclient, $rah) + protected function processMQTTEvents(JobOrder $jo, $payload, MQTTClient $mclient, + RiderAssignmentHandlerInterface$rah) { // check JO status if ($jo->getStatus() == JOStatus::ASSIGNED) @@ -1318,7 +1266,7 @@ class JobOrderController extends APIController } } - protected function makeInvoiceData($invoice, $mah, $req) + protected function makeInvoiceData(Invoice $invoice, MobileAPIHandler$mah, Request $req) { // make invoice json data $invoice_data = [ @@ -1385,4 +1333,115 @@ class JobOrderController extends APIController } } } + + protected function generateJobOrderData($req, $jo, $rt, $mah) + { + $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), + ]; + + // customer vehicle and warranty + $cv = $jo->getCustomerVehicle(); + + // get latest warranty using plate number + $warranty = $mah->findWarranty($cv->getPlateNumber()); + + $jo_data['customer_vehicle'] = [ + 'id' => $cv->getID(), + 'plate_number' => $cv->getPlateNumber(), + 'warranty' => $warranty, + ]; + + // 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; + } + + protected function generateAPIRiderStatus($status) + { + switch ($status) + { + case JOStatus::PENDING: + return APIRiderStatus::OUTLET_ASSIGN; + case JOStatus::RIDER_ASSIGN: + return APIRiderStatus::RIDER_ASSIGN; + case JOStatus::ASSIGNED: + case JOStatus::IN_TRANSIT: + case JOStatus::IN_PROGRESS: + return APIRiderStatus::RIDER_PICK_UP; + } + return 'unknown'; + } } -- 2.43.5 From bfbd4d4045044f3af81acd2574331c4202786de1 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 12 Jul 2021 09:44:46 +0000 Subject: [PATCH 27/42] Modify location support. #591 --- config/api_acl.yaml | 8 ++ config/routes/resqapi.yaml | 2 +- src/Controller/ResqAPI/JobOrderController.php | 105 +++++++----------- 3 files changed, 48 insertions(+), 67 deletions(-) diff --git a/config/api_acl.yaml b/config/api_acl.yaml index fb2c8e5d..cd1f9ae0 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -154,3 +154,11 @@ access_keys: label: Cancel Job Order - id: mobile_jo.get.history label: Get Job Order History + - id: mobile_jo.get.invoice + label: Get Job Order Invoice + - id: mobile_jo.location.support + label: Check Location Support + - id: mobile_jo.nearest_hub.get + label: Get Nearest Hub and Slots + - id: mobile_jo.schedule_option.status + label: Schedule Option Status diff --git a/config/routes/resqapi.yaml b/config/routes/resqapi.yaml index 354440d2..43b2c45e 100644 --- a/config/routes/resqapi.yaml +++ b/config/routes/resqapi.yaml @@ -157,7 +157,7 @@ resqapi_jo_invoice: resqapi_location_support: path: /resqapi/location_support controller: App\Controller\ResqAPI\JobOrderController:locationSupport - methods: [GET] + methods: [POST] resqapi_nearest_hub_slots: path: /resqapi/hub_slots diff --git a/src/Controller/ResqAPI/JobOrderController.php b/src/Controller/ResqAPI/JobOrderController.php index 0daa1fc8..8a0fd4b7 100644 --- a/src/Controller/ResqAPI/JobOrderController.php +++ b/src/Controller/ResqAPI/JobOrderController.php @@ -476,93 +476,67 @@ class JobOrderController extends APIController return new APIResponse(true, 'Job order history found', $data); } - // TODO: modify for MobileUser - public function getJOInvoice(Request $req, EntityManagerInterface $em) + public function getJOInvoice(Request $req, EntityManagerInterface $em, MobileAPIHandler $mah) { + $this->denyAccessUnlessGranted('mobile_jo.get.invoice', null, 'No access.'); + $required_params = [ 'jo_id', ]; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); - // get job order - $jo_id = $req->query->get('jo_id'); - $jo = $em->getRepository(JobOrder::class)->find($jo_id); - if ($jo == null) - { - $res->setError(true) - ->setErrorMessage('No job order found'); - return $res->getReturnResponse(); - } + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); - // get customer - $cust = $this->session->getCustomer(); + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); + + // customer + $cust = $mobile_user->getCustomer(); if ($cust == null) - { - $res->setError(true) - ->setErrorMessage('No customer information found'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'No customer information found'); // check that the customer owns the job order $jo_cust = $jo->getCustomer(); if ($jo_cust->getID() != $cust->getID()) - { - $res->setError(true) - ->setErrorMessage('Job order was not initiated by customer'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'Job order was not initiated by customer'); $invoice = $jo->getInvoice(); - // make invoice json data - $data = [ - 'total_price' => (float) $invoice->getTotalPrice(), - 'vat_ex_price' => (float) $invoice->getVATExclusivePrice(), - 'vat' => (float) $invoice->getVAT(), - 'discount' => (float) $invoice->getDiscount(), - 'trade_in' => (float) $invoice->getTradeIn(), - ]; - $items = $invoice->getItems(); - $items_data = []; - foreach ($items as $item) - { - $my_data = [ - 'title' => $item->getTitle(), - 'qty' => (int) $item->getQuantity() + 0, - 'price' => (float) $item->getPrice() + 0.0, - ]; + $data = $this->makeInvoiceData($invoice, $mah, $req); - $item_batt = $item->getBattery(); - if ($item_batt != null) - { - $my_data['image_url'] = $this->getBatteryImageURL($req, $item_batt); - } - - $items_data[] = $my_data; - } - - $data['items'] = $items_data; - - // set data - $res->setData($data); - - return $res->getReturnResponse(); + return new APIResponse(true, 'Job order invoice found', $data); } - public function locationSupport(Request $req, GeofenceTracker $geo, EntityManagerInterface $em) + public function locationSupport(Request $req, GeofenceTracker $geo, EntityManagerInterface $em, + MobileAPIHandler $mah) { $required_params = [ 'longitude', 'latitude', ]; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); - $long = $req->query->get('longitude'); - $lat = $req->query->get('latitude'); + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); + + $long = $req->request->get('longitude'); + $lat = $req->request->get('latitude'); // geofence $is_covered = $geo->isCovered($long, $lat); @@ -572,9 +546,8 @@ class JobOrderController extends APIController 'latitude' => $lat, 'supported' => $is_covered, ]; - $res->setData($data); - return $res->getReturnResponse(); + return new APIResponse(true, 'Location checked', $data); } // TODO: do we make this use the HubCriteria and HubSelector? YES? -- 2.43.5 From d51e052a7254f07362c6d868e592ff566eff9218 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 12 Jul 2021 10:22:06 +0000 Subject: [PATCH 28/42] Modify getNearestHubAndSlots. #591 --- config/routes/resqapi.yaml | 2 +- src/Controller/ResqAPI/JobOrderController.php | 146 ++++-------------- 2 files changed, 35 insertions(+), 113 deletions(-) diff --git a/config/routes/resqapi.yaml b/config/routes/resqapi.yaml index 43b2c45e..df45f624 100644 --- a/config/routes/resqapi.yaml +++ b/config/routes/resqapi.yaml @@ -162,7 +162,7 @@ resqapi_location_support: resqapi_nearest_hub_slots: path: /resqapi/hub_slots controller: App\Controller\ResqAPI\JobOrderController::getNearestHubAndSlots - methods: [GET] + methods: [POST] resqapi_new_jo_request: path: /resqapi/new_job_order diff --git a/src/Controller/ResqAPI/JobOrderController.php b/src/Controller/ResqAPI/JobOrderController.php index 8a0fd4b7..5fa7a992 100644 --- a/src/Controller/ResqAPI/JobOrderController.php +++ b/src/Controller/ResqAPI/JobOrderController.php @@ -52,6 +52,7 @@ use App\Entity\Hub; use Catalyst\APIBundle\Access\Generator as ACLGenerator; use DateTime; +use DateInterval; class JobOrderController extends APIController { @@ -550,28 +551,45 @@ class JobOrderController extends APIController return new APIResponse(true, 'Location checked', $data); } - // TODO: do we make this use the HubCriteria and HubSelector? YES? public function getNearestHubAndSlots(Request $req, EntityManagerInterface $em, - MapTools $map_tools) + MobileAPIHandler $mah, HubSelector $hub_select) { + $this->denyAccessUnlessGranted('mobile_jo.nearest_hub.get', null, 'No access.'); + $required_params = [ 'longitude', 'latitude', ]; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); - $coordinates = new Point($req->query->get('longitude'), $req->query->get('latitude')); - $nearest_hub_slots = $this->findAdvanceNearestHubAndSlots($coordinates, $em, $map_tools); + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); + + $coordinates = new Point($req->request->get('longitude'), $req->request->get('latitude')); + + $hub_criteria = new HubCriteria(); + // get the nearest 10 hubs + // TODO: do we need to check for inventory? if so, we need battery id + $hub_criteria->setPoint($coordinates) + ->setLimitResults(10); + + // find nearest hubs + $nearest_hubs = $hub_select->find($hub_criteria); + + // get the nearest hub and slots + $nearest_hub_slots = $this->findAdvanceNearestHubAndSlots($nearest_hubs, $em); if (empty($nearest_hub_slots['hub'])) - { - $res->setError(true) - ->setErrorMessage('Thank you for reaching out to us. Due to the General Community Quarantine, our Operations are from 8AM to 6PM only. Please expect a call from us tomorrow and we will assist you with your request. Thank you and stay safe!'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'Thank you for reaching out to us. Due to the General Community Quarantine, our Operations are from 8AM to 6PM only. Please expect a call from us tomorrow and we will assist you with your request. Thank you and stay safe!'); // make hub data $data = [ @@ -579,10 +597,7 @@ class JobOrderController extends APIController 'hub_slots' => $nearest_hub_slots['slots'], ]; - $res->setData($data); - - return $res->getReturnResponse(); - + return new APIResponse(true, 'Hub and slot found', $data); } public function scheduleOptionStatus(Request $req, EntityManagerInterface $em) @@ -614,87 +629,6 @@ class JobOrderController extends APIController return $res->getReturnResponse(); } - protected function getOngoingJobOrders($cust, $em) - { - $ongoing_jos = $em->getRepository(JobOrder::class)->findBy([ - 'customer' => $cust, - 'status' => [JOStatus::PENDING, JOStatus::RIDER_ASSIGN, JOStatus::IN_TRANSIT, JOStatus::ASSIGNED, JOStatus::IN_PROGRESS], - ]); - - return $ongoing_jos; - } - - // TODO: what to do with this? listVehicles in CustomerVehicleController als calls this - protected function findWarranty($plate_number, $em) - { - // NOTE: Modify the search for the latest warranty. This seems hacky. - // get latest warranty using plate number - $warranty_results = $em->getRepository(Warranty::class)->findBy(['plate_number' => $plate_number], - ['date_create' => 'desc']); - - $warr = []; - - // check if warranty_results is empty - if (empty($warranty_results)) - { - /* - $res->setError(true) - ->setErrorMessage('No warranty found for plate number'); - return $res->getReturnResponse(); - */ - - return $warr; - } - - // get first entry - $warranty = current($warranty_results); - - // check for null values for battery and date claim and date expire - $batt_model = ''; - $batt_size = ''; - $sap_batt = ''; - $claim_date = ''; - $expiry_date = ''; - - if (!(is_null($warranty->getBatteryModel()))) { - $batt_model = $warranty->getBatteryModel()->getName(); - } - if (!(is_null($warranty->getBatterySize()))) { - $batt_size = $warranty->getBatterySize()->getName(); - } - if (!(is_null($warranty->getSAPBattery()))) { - $sap_batt = $warranty->getSAPBattery()->getID(); - } - if (!(is_null($warranty->getDateClaim()))) { - $claim_date = $warranty->getDateClaim()->format("d M Y"); - } - if (!(is_null($warranty->getDateExpire()))) { - $expiry_date = $warranty->getDateExpire()->format("d M Y"); - } - - $warr[] = [ - 'id' => $warranty->getID(), - 'serial' => $warranty->getSerial(), - 'warranty_class' => $warranty->getWarrantyClass(), - 'plate_number' => $warranty->getPlateNumber(), - 'first_name' => $warranty->getFirstName(), - 'last_name' => $warranty->getLastName(), - 'mobile_number' => $warranty->getMobileNumber(), - 'battery_model' => $batt_model, - 'battery_size' => $batt_size, - 'sap_battery' => $sap_batt, - 'status' => $warranty->getStatus(), - 'date_create' => $warranty->getDateCreate()->format("d M Y g:i A"), - 'date_purchase' => $warranty->getDatePurchase()->format("d M Y"), - 'date_expire' => $expiry_date, - 'date_claim' => $claim_date, - 'claim_from' => $warranty->getClaimedFrom(), - 'is_activated' => $warranty->isActivated() ? 1 : 0, - ]; - - return $warr; - } - protected function randomizeRider($riders) { // TODO: get redis to track the sales per rider per day @@ -707,26 +641,14 @@ class JobOrderController extends APIController return $selected_rider; } - // TODO: this might become irrelevant if we use HubCriteria (which I think we should, my blooper) - protected function findAdvanceNearestHubAndSlots(Point $coordinates, EntityManagerInterface $em, MapTools $map_tools) + protected function findAdvanceNearestHubAndSlots($nearest_hubs, EntityManagerInterface $em) { - // get the nearest 10 hubs - $hub_data = []; - $nearest_hubs_with_distance = []; - $hubs = $map_tools->getClosestOpenHubs($coordinates, 10); - - foreach ($hubs as $hub) - { - $nearest_hubs_with_distance[] = $hub; - // TODO: insert checking for branch code here when inventory manager is up - } - $nearest = null; $slot_found = false; // find the nearest hub - if (!empty($nearest_hubs_with_distance)) + if (!empty($nearest_hubs)) { - foreach ($nearest_hubs_with_distance as $nhd) + foreach ($nearest_hubs as $nhd) { if (empty($nearest)) $nearest = $nhd; -- 2.43.5 From 003b5f2aa1bbf5c3dc59985da41cfe29da499514 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 12 Jul 2021 10:28:06 +0000 Subject: [PATCH 29/42] Modify ScheduleOptionStatus. #591 --- src/Controller/ResqAPI/JobOrderController.php | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/Controller/ResqAPI/JobOrderController.php b/src/Controller/ResqAPI/JobOrderController.php index 5fa7a992..73c7d835 100644 --- a/src/Controller/ResqAPI/JobOrderController.php +++ b/src/Controller/ResqAPI/JobOrderController.php @@ -37,7 +37,6 @@ use App\Service\HubSelector; use App\Service\HubDistributor; use App\Service\HubFilterLogger; use App\Service\HubFilteringGeoChecker; -use App\Service\MapTools; use App\Service\MobileAPIHandler; use App\Service\RiderTracker; @@ -159,7 +158,7 @@ class JobOrderController extends APIController } public function newRequestJobOrder(Request $req, InvoiceGeneratorInterface $ic, GeofenceTracker $geo, - MapTools $map_tools, InventoryManager $im, MQTTClient $mclient, + InventoryManager $im, MQTTClient $mclient, RiderAssignmentHandlerInterface $rah, PromoLogger $promo_logger, HubSelector $hub_select, HubDistributor $hub_dist, HubFilterLogger $hub_filter_logger, HubFilteringGeoChecker $hub_geofence, EntityManagerInterface $em, @@ -600,13 +599,24 @@ class JobOrderController extends APIController return new APIResponse(true, 'Hub and slot found', $data); } - public function scheduleOptionStatus(Request $req, EntityManagerInterface $em) + public function scheduleOptionStatus(Request $req, EntityManagerInterface $em, MobileAPIHandler $mah) { + $this->denyAccessUnlessGranted('mobile_jo.schedule_option.status', null, 'No access.'); + // check required parameters and api key $required_params = []; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); $schedule_choice = true; @@ -624,9 +634,8 @@ class JobOrderController extends APIController $data = [ 'display_schedule_choice' => $schedule_choice, ]; - $res->setData($data); - return $res->getReturnResponse(); + return new APIResponse(true, 'Schedule option status check', $data); } protected function randomizeRider($riders) -- 2.43.5 From 2cdc51e8788cf784810441f41692af1bbded885e Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 13 Jul 2021 09:15:06 +0000 Subject: [PATCH 30/42] Modify WarrantyController. #591 --- config/api_acl.yaml | 9 ++ src/Controller/ResqAPI/WarrantyController.php | 93 ++++++++++--------- 2 files changed, 58 insertions(+), 44 deletions(-) diff --git a/config/api_acl.yaml b/config/api_acl.yaml index cd1f9ae0..2da7b9df 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -162,3 +162,12 @@ access_keys: label: Get Nearest Hub and Slots - id: mobile_jo.schedule_option.status label: Schedule Option Status + - id: mobile_warranty + label: Mobile Warranty Access + acls: + - id: mobile_warranty.register.serial + label: Register Warranty Serial + - id: mobile_warranty.check + label: Check Warranty Serial + - id: mobile_warranty.activate + label: Activate Warranty diff --git a/src/Controller/ResqAPI/WarrantyController.php b/src/Controller/ResqAPI/WarrantyController.php index 95322264..10c17a14 100644 --- a/src/Controller/ResqAPI/WarrantyController.php +++ b/src/Controller/ResqAPI/WarrantyController.php @@ -11,10 +11,8 @@ use Doctrine\ORM\Query; use Doctrine\ORM\EntityManagerInterface; use Catalyst\APIBundle\Controller\APIController; -// TODO: what do we use for response? APIResponse or APIResult? -// APIResult is what is used by APIController. APIResponse is what is used by CAPI use Catalyst\APIBundle\Response\APIResponse; -use App\Ramcar\APIResult; + use App\Ramcar\WarrantySource; use App\Entity\Warranty; @@ -24,6 +22,7 @@ use App\Entity\CustomerVehicle; use App\Service\RisingTideGateway; use App\Service\WarrantyAPILogger; +use App\Service\MobileAPIHandler; use Catalyst\APIBundle\Access\Generator as ACLGenerator; @@ -39,9 +38,11 @@ class WarrantyController extends APIController } public function warrantyRegister($serial, EntityManagerInterface $em, Request $req, KernelInterface $kernel, RisingTideGateway $rt, - TranslatorInterface $trans, WarrantyAPILogger $logger) + TranslatorInterface $trans, WarrantyAPILogger $logger, MobileAPIHandler $mah) { - // check required parameters and api key + $this->denyAccessUnlessGranted('mobile_jo.request', null, 'No access.'); + + // check required parameters $required_params = [ 'first_name', 'last_name', @@ -61,7 +62,16 @@ class WarrantyController extends APIController $inv_filename = $this->handlePictureUpload($invoice, $upload_dir, $serial, 'invoice'); $wcard_filename = $this->handlePictureUpload($warr_card, $upload_dir, $serial, 'wcard'); - $user_id = $req->query->get('api_key'); + // get capi user to link to mobile user + $capi_user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($capi_user_id); + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); + + $user_id = $mobile_user->getID(); + $log_data = [ 'plate_number' => $req->request->get('plate_num'), 'first_name' => $req->request->get('first_name'), @@ -71,27 +81,29 @@ class WarrantyController extends APIController $action = 'create'; $source = WarrantySource::MOBILE; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) { - $logger->logWarrantyInfo($log_data, $res->getErrorMessage(), $user_id, $action, $source); - return $res->getReturnResponse(); + $logger->logWarrantyInfo($log_data, $msg, $user_id, $action, $source); + return new APIResponse(false, $msg); } // update customer information // $cust = $this->updateCustomerInfo($req, $em); // update warranty - $res = $this->updateWarranty($res, $em, $rt, $trans, $req, $serial, $inv_filename, $wcard_filename, - $logger, $log_data, $user_id, $action, $source); + $data = []; + $msg = $this->updateWarranty($data, $em, $rt, $trans, $req, $serial, $inv_filename, $wcard_filename, + $logger, $log_data, $user_id, $action, $source, $mobile_user); + if ($msg != null) + return new APIResponse(false, $msg); $em->flush(); - return $res->getReturnResponse(); + return new APIResponse(true, 'Warranty registered', $data); } - // TODO: needs to be modified for mobile user - public function warrantyCheck($serial, EntityManagerInterface $em, Request $req) + public function warrantyCheck($serial, EntityManagerInterface $em, Request $req, MobileAPIHandler $mah) { // check required parameters and api key $required_params = []; @@ -332,18 +344,16 @@ class WarrantyController extends APIController return $serial . '/' . $filename; } - // TODO: needs to be modified for mobile user - protected function updateWarranty($res, $em, $rt, $trans, $req, $serial, $inv_filename = null, $wcard_filename = null, - $logger, $log_data, $user_id, $action, $source) + protected function updateWarranty($data, $em, $rt, $trans, $req, $serial, $inv_filename = null, $wcard_filename = null, + $logger, $log_data, $user_id, $action, $source, $mobile_user) { // get serial $warr_serial = $em->getRepository(WarrantySerial::class)->find($serial); if ($warr_serial == null) { - $res->setError(true) - ->setErrorMessage('Invalid warranty serial code.'); - $logger->logWarrantyInfo($log_data, $res->getErrorMessage(), $user_id, $action, $source); - return $res; + $msg = 'Invalid warranty serial code.'; + $logger->logWarrantyInfo($log_data, $msg, $user_id, $action, $source); + return $msg; } // check if warranty exists already @@ -361,15 +371,14 @@ class WarrantyController extends APIController // check if warranty is registered to a serial owned by customer $warr_plate = $warr->getPlateNumber(); - $cust = $this->session->getCustomer(); + $cust = $mobile_user->getCustomer(); $is_customer_warranty = $this->checkCustomerPlateNumber($warr_plate, $cust); if (!$is_customer_warranty) { - $res->setError(true) - ->setErrorMessage('Warranty registered to a vehicle not in your list of vehicles.'); - $logger->logWarrantyInfo($log_data, $res->getErrorMessage(), $user_id, $action, $source); - return $res; + $msg = 'Warranty registered to a vehicle not in your list of vehicles.'; + $logger->logWarrantyInfo($log_data, $msg, $user_id, $action, $source); + return $msg; } $sms_msg = $trans->trans('warranty_update_confirm'); @@ -391,10 +400,9 @@ class WarrantyController extends APIController $sap_bty = $em->getRepository(SAPBattery::class)->find($sku); if ($sap_bty == null) { - $res->setError(true) - ->setErrorMessage('Could not find battery entry for warranty.'); - $logger->logWarrantyInfo($log_data, $res->getErrorMessage(), $user_id, $action, $source); - return $res; + $msg = 'Could not find battery entry for warranty.'; + $logger->logWarrantyInfo($log_data, $msg, $user_id, $action, $source); + return $msg; } } @@ -406,13 +414,12 @@ class WarrantyController extends APIController $date_pur_cust = DateTime::createFromFormat('Y-m-d', $req->request->get('date_purchase')); if (!$date_pur_cust) { - $res->setError(true) - ->setErrorMessage('Invalid date format for date of purchase.'); - $logger->logWarrantyInfo($log_data, $res->getErrorMessage(), $user_id, $action, $source); - return $res; + $msg = 'Invalid date format for date of purchase.'; + $logger->logWarrantyInfo($log_data, $msg, $user_id, $action, $source); + return $msg; } - $customer = $this->session->getCustomer(); + $customer = $mobile_user->getCustomer(); if ($customer != null) { $warr->setCustomer($customer); @@ -437,7 +444,7 @@ class WarrantyController extends APIController // ->setBatterySize() // ->setBatteryModel() ->setSAPBattery($sap_bty) - ->setMobileNumber(substr($this->session->getPhoneNumber(), 2)) + ->setMobileNumber(substr($mobile_user->getPhoneNumber(), 2)) ->setActivated(true) // files @@ -457,19 +464,17 @@ class WarrantyController extends APIController $em->persist($warr); - // TODO: check if we need to do anyting else + // TODO: check if we need to do anything else + // TODO: put warranty data into data $data = []; - // set data to retrun to user - $res->setData($data); - $logger->logWarrantyInfo($log_data, '', $user_id, $action, $source); // send sms - error_log('sending sms to - ' . $this->session->getPhoneNumber()); - $rt->sendSMS($this->session->getPhoneNumber(), 'MOTOLITE', $sms_msg); + error_log('sending sms to - ' . $mobile_user->getPhoneNumber()); + $rt->sendSMS($mobile_user->getPhoneNumber(), 'MOTOLITE', $sms_msg); - return $res; + return $data; } protected function findCustomerVehicle($em, $customer, $plate_number) -- 2.43.5 From b040fe95a47f99362b49b4f62d81bf8b6f420962 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 14 Jul 2021 07:20:49 +0000 Subject: [PATCH 31/42] Modify WarrantyController. #591 --- src/Controller/ResqAPI/WarrantyController.php | 150 +++++------------- 1 file changed, 39 insertions(+), 111 deletions(-) diff --git a/src/Controller/ResqAPI/WarrantyController.php b/src/Controller/ResqAPI/WarrantyController.php index 10c17a14..f20ac15c 100644 --- a/src/Controller/ResqAPI/WarrantyController.php +++ b/src/Controller/ResqAPI/WarrantyController.php @@ -72,14 +72,15 @@ class WarrantyController extends APIController $user_id = $mobile_user->getID(); + // prepare logging data + $action = 'create'; + $source = WarrantySource::MOBILE; $log_data = [ 'plate_number' => $req->request->get('plate_num'), 'first_name' => $req->request->get('first_name'), 'last_name' => $req->request->get('last_name'), 'date_purchase' => $req->request->get('date_purchase'), ]; - $action = 'create'; - $source = WarrantySource::MOBILE; $msg = $this->checkRequiredParameters($req, $required_params); if ($msg) @@ -105,25 +106,31 @@ class WarrantyController extends APIController public function warrantyCheck($serial, EntityManagerInterface $em, Request $req, MobileAPIHandler $mah) { - // check required parameters and api key + $this->denyAccessUnlessGranted('mobile_warranty.check', null, 'No access.'); + + // check required parameters $required_params = []; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); // check if warranty serial is there $warr_serial = $em->getRepository(WarrantySerial::class)->find($serial); + if ($warr_serial == null) + return new APIResponse(false, 'Invalid warranty serial code'); + $warr = $em->getRepository(Warranty::class)->findOneBy(['serial' => $serial]); $batt = null; $is_registered = false; - - if ($warr_serial == null) - { - $res->setError(true) - ->setErrorMessage('Invalid warranty serial code.'); - return $res->getReturnResponse(); - } - $today = new DateTime(); // if we have a warranty entry for the serial already @@ -134,7 +141,7 @@ class WarrantyController extends APIController $is_customer_warranty = false; // check if the warranty is registered to a car owned by the customer - $cust = $this->session->getCustomer(); + $cust = $mobile_user->getCustomer(); $is_customer_warranty = $this->checkCustomerPlateNumber($warr_plate, $cust); // null mobile number should be blank string instead @@ -277,17 +284,26 @@ class WarrantyController extends APIController ], ]; - $res->setData($data); - - return $res->getReturnResponse(); + return new APIResponse(true, 'Warranty checked', $data); } public function activateWarranty(Request $req, EntityManagerInterface $em) { + $this->denyAccessUnlessGranted('mobile_warranty.activate', null, 'No access.'); + $required_params = ['plate_number']; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); + + // get capi user to link to mobile user + $user_id = $this->getUser()->getID(); + + // get mobile user + $mobile_user = $mah->findMobileUser($user_id); + + if ($mobile_user == null) + return new APIResponse(false, 'No mobile user found.'); $plate_number = $req->request->get('plate_number'); @@ -297,11 +313,7 @@ class WarrantyController extends APIController // check if warranty_results is empty if (empty($warranty_results)) - { - $res->setError(true) - ->setErrorMessage('No warranty found for plate number'); - return $res->getReturnResponse(); - } + return new APIResponse(false, 'No warranty found for plate number'); // activate all entries foreach ($warranty_results as $warranty) @@ -311,7 +323,7 @@ class WarrantyController extends APIController $em->flush(); - return $res->getReturnResponse(); + return new APIResponse(true, 'Warranty activated'); } protected function handlePictureUpload($file, $target_dir, $serial, $name) @@ -518,88 +530,4 @@ class WarrantyController extends APIController return false; } - - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkParamsAndKey(Request $req, $em, $params) - { - // TODO: depends on what we decide to return - // returns APIResult object - $res = new APIResult(); - - // check for api_key in query string - $api_key = $req->query->get('api_key'); - if (empty($api_key)) - { - $res->setError(true) - ->setErrorMessage('Missing API key'); - return $res; - } - - // check missing parameters - $missing = $this->checkMissingParameters($req, $params); - if (count($missing) > 0) - { - $miss_string = implode(', ', $missing); - $res->setError(true) - ->setErrorMessage('Missing parameter(s): ' . $miss_string); - return $res; - } - - // check api key - $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); - if ($mobile_user == null) - { - $res->setError(true) - ->setErrorMessage('Invalid API Key'); - return $res; - } - - // store session - $this->session = $sess; - - return $res; - } - - // TODO: this might not be needed if we use APIController's checkRequiredParameters - // or we put this into a service? - protected function checkMissingParameters(Request $req, $params = []) - { - $missing = []; - - // check if parameters are there - foreach ($params as $param) - { - if ($req->getMethod() == 'GET') - { - $check = $req->query->get($param); - if (empty($check)) - $missing[] = $param; - } - else if ($req->getMethod() == 'POST') - { - $check = $req->request->get($param); - if (empty($check)) - $missing[] = $param; - } - else - return $params; - } - - return $missing; - } - - // TODO: type hint entity manager - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkAPIKey($em, $api_key) - { - // find the api key (session id) - // TODO: user validation needs to be changed - $m_user = $em->getRepository(MobileUser::class)->find($api_key); - if ($m_user == null) - return null; - - return $m_user; - } } -- 2.43.5 From deaad1dbc1e7909626c2981e6fb53105d1b8d0d4 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 14 Jul 2021 09:41:11 +0000 Subject: [PATCH 32/42] Add data fields to responses where necessary. #591 --- src/Controller/ResqAPI/CustomerController.php | 106 +++--------------- 1 file changed, 18 insertions(+), 88 deletions(-) diff --git a/src/Controller/ResqAPI/CustomerController.php b/src/Controller/ResqAPI/CustomerController.php index 287fd082..595da8a3 100644 --- a/src/Controller/ResqAPI/CustomerController.php +++ b/src/Controller/ResqAPI/CustomerController.php @@ -98,9 +98,12 @@ class CustomerController extends APIController // return data // TODO: do we need to return the same names as before? - // right now, still usind the old names so we use session_id name + // right now, still using the old names so we use session_id name $data = [ - 'session_id' => $mobile_user->getID() + 'session_id' => $mobile_user->getID(), + 'phone_model' => $mobile_user->getPhoneModel(), + 'os_version' => $mobile_user->getOSVersion(), + 'phone_id' => $mobile_user->getPhoneID(), ]; // response @@ -225,6 +228,8 @@ class CustomerController extends APIController } // TODO: check if mobile matches mobile of customer + // need to "clean" the mobile number. Mobile user stores the number with the area code prepended + // Customer stores the number without the area code $customer = $this->findCustomerByNumber($mobile_user->getPhoneNumber(), $em); if ($customer != null) { @@ -319,6 +324,11 @@ class CustomerController extends APIController $em->flush(); + $data = [ + 'first_name' => $cust->getFirstName(), + 'last_name' => $cust->getLastName(), + ]; + return new APIResponse(true, 'Customer info updated'); } @@ -452,8 +462,12 @@ class CustomerController extends APIController $em->flush(); + $data = [ + 'device_id' => $mobile_user->getDevicePushID(), + ]; + // response - return new APIResponse(true, 'Device ID updated'); + return new APIResponse(true, 'Device ID updated', $data); } public function privacySettings(Request $req, EntityManagerInterface $em, MobileAPIHandler $mah) @@ -555,6 +569,7 @@ class CustomerController extends APIController foreach($customers as $customer) { + error_log('no customer?'); $vehicles = $customer->getVehicles(); if (count($vehicles) > $car_count) { @@ -600,89 +615,4 @@ class CustomerController extends APIController $message = "Your Resq confirmation code is $code."; $rt->sendSMS($phone_number, 'MOTOLITE', $message); } - - - // TODO: this might not be needed if we use APIController's checkRequiredParameters - // or we put this into a service? - protected function checkMissingParameters(Request $req, $params = []) - { - $missing = []; - - // check if parameters are there - foreach ($params as $param) - { - if ($req->getMethod() == 'GET') - { - $check = $req->query->get($param); - if (empty($check)) - $missing[] = $param; - } - else if ($req->getMethod() == 'POST') - { - $check = $req->request->get($param); - if (empty($check)) - $missing[] = $param; - } - else - return $params; - } - - return $missing; - } - - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkParamsAndKey(Request $req, $em, $params) - { - // TODO: depends on what we decide to return - // returns APIResult object - $res = new APIResult(); - - // check for api_key in query string - $api_key = $req->query->get('api_key'); - if (empty($api_key)) - { - $res->setError(true) - ->setErrorMessage('Missing API key'); - return $res; - } - - // check missing parameters - $missing = $this->checkMissingParameters($req, $params); - if (count($missing) > 0) - { - $miss_string = implode(', ', $missing); - $res->setError(true) - ->setErrorMessage('Missing parameter(s): ' . $miss_string); - return $res; - } - - // check api key - $mobile_user = $this->checkAPIKey($em, $req->query->get('api_key')); - if ($mobile_user == null) - { - $res->setError(true) - ->setErrorMessage('Invalid API Key'); - return $res; - } - - // store session - $this->session = $sess; - - return $res; - } - - // TODO: type hint entity manager - // TODO: since we broke the functions into separate files, we need - // to figure out how to make this accessible to all ResqAPI controllers - protected function checkAPIKey($em, $api_key) - { - // find the api key (session id) - // TODO: user validation needs to be changed - $m_user = $em->getRepository(MobileUser::class)->find($api_key); - if ($m_user == null) - return null; - - return $m_user; - } } -- 2.43.5 From 8c53b9ba750477dea361c0d5d11798d763a385ed Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 14 Jul 2021 10:27:14 +0000 Subject: [PATCH 33/42] Add data fields to responses where necessary. #591 --- src/Controller/ResqAPI/CustomerController.php | 5 +---- src/Controller/ResqAPI/PartnerController.php | 7 ++++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Controller/ResqAPI/CustomerController.php b/src/Controller/ResqAPI/CustomerController.php index 595da8a3..ecece983 100644 --- a/src/Controller/ResqAPI/CustomerController.php +++ b/src/Controller/ResqAPI/CustomerController.php @@ -101,9 +101,6 @@ class CustomerController extends APIController // right now, still using the old names so we use session_id name $data = [ 'session_id' => $mobile_user->getID(), - 'phone_model' => $mobile_user->getPhoneModel(), - 'os_version' => $mobile_user->getOSVersion(), - 'phone_id' => $mobile_user->getPhoneID(), ]; // response @@ -228,7 +225,7 @@ class CustomerController extends APIController } // TODO: check if mobile matches mobile of customer - // need to "clean" the mobile number. Mobile user stores the number with the area code prepended + // TODO: need to "clean" the mobile number. Mobile user stores the number with the area code prepended // Customer stores the number without the area code $customer = $this->findCustomerByNumber($mobile_user->getPhoneNumber(), $em); if ($customer != null) diff --git a/src/Controller/ResqAPI/PartnerController.php b/src/Controller/ResqAPI/PartnerController.php index ff3c76eb..01c3609b 100644 --- a/src/Controller/ResqAPI/PartnerController.php +++ b/src/Controller/ResqAPI/PartnerController.php @@ -190,6 +190,11 @@ class PartnerController extends APIController $em->persist($rev); $em->flush(); - return new APIResponse(true, 'Review added'); + $data = [ + 'rating' => $rev->getRating(), + 'message' => $rev->getMessage(), + ]; + + return new APIResponse(true, 'Review added', $data); } } -- 2.43.5 From e162de90217b6778ef8ba94b5df92db6310a2d88 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 15 Jul 2021 07:13:38 +0000 Subject: [PATCH 34/42] Add data to responses. #591 --- src/Controller/ResqAPI/RiderController.php | 6 +++- src/Controller/ResqAPI/WarrantyController.php | 36 ++++++++++++++++--- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/Controller/ResqAPI/RiderController.php b/src/Controller/ResqAPI/RiderController.php index 875ec545..8422db81 100644 --- a/src/Controller/ResqAPI/RiderController.php +++ b/src/Controller/ResqAPI/RiderController.php @@ -238,7 +238,6 @@ class RiderController extends APIController // add rider rating $rating_num = $req->request->get('rating', -1); - $data = []; // if rating is -1 if ($rating_num == -1) { @@ -266,6 +265,11 @@ class RiderController extends APIController $em->persist($rating); $em->flush(); + $data = [ + 'rating' => $rating->getRating(), + 'comment' => $rating->getComment(), + ]; + // TODO: set average rating in rider entity return new APIResponse(true, 'Rider rating added', $data); diff --git a/src/Controller/ResqAPI/WarrantyController.php b/src/Controller/ResqAPI/WarrantyController.php index f20ac15c..4d9d83c8 100644 --- a/src/Controller/ResqAPI/WarrantyController.php +++ b/src/Controller/ResqAPI/WarrantyController.php @@ -356,7 +356,7 @@ class WarrantyController extends APIController return $serial . '/' . $filename; } - protected function updateWarranty($data, $em, $rt, $trans, $req, $serial, $inv_filename = null, $wcard_filename = null, + protected function updateWarranty(&$data, $em, $rt, $trans, $req, $serial, $inv_filename = null, $wcard_filename = null, $logger, $log_data, $user_id, $action, $source, $mobile_user) { // get serial @@ -478,15 +478,13 @@ class WarrantyController extends APIController // TODO: check if we need to do anything else // TODO: put warranty data into data - $data = []; + $data = $this->generateWarrantyData($warr); $logger->logWarrantyInfo($log_data, '', $user_id, $action, $source); // send sms error_log('sending sms to - ' . $mobile_user->getPhoneNumber()); $rt->sendSMS($mobile_user->getPhoneNumber(), 'MOTOLITE', $sms_msg); - - return $data; } protected function findCustomerVehicle($em, $customer, $plate_number) @@ -530,4 +528,34 @@ class WarrantyController extends APIController return false; } + + protected function generateWarrantyData($warranty) + { + $sap_bty_name = ''; + if ($warranty->getSAPBAttery() != null) + $sap_bty_name = $warranty->getSAPBattery()->getID(); + + $data = [ + 'serial' => $warranty->getSerial(), + 'first_name' => $warranty->getFirstName(), + 'last_name' => $warranty->getLastName(), + 'email' => $warranty->getEmail() ?? '', + 'plate_number' => $warranty->getPlateNumber(), + 'date_purchase' => $warranty->getDatePurchase()->format('Y-m-d'), + 'sap_battery' => $sap_bty_name, + 'mobile_number' => $warranty->getMobileNumber() ?? '', + 'activated' => (boolean) $warranty->isActivated(), + 'invoice_file' => $warranty->getFileInvoice() ?? '', + 'warranty_card_file' => $warranty->getFileWarrantyCard() ?? '', + 'odometer' => $warranty->getOdometer() ?? 0, + 'date_purchase_customer' => $warranty->getDatePurchaseCustomer()->format('Y-m-d'), + 'contact_number' => $warranty->getContactNumber() ?? '', + 'customer_address' => $warranty->getCustomerAddress() ?? '', + 'dealer_name' => $warranty->getDealerName() ?? '', + 'dealer_address' => $warranty->getDealerAddress() ?? '', + 'validated' => (boolean) $warranty->isValidated(), + ]; + + return $data; + } } -- 2.43.5 From f067a6ddadf1d41cc6dafc4896aff4fcdf61aacb Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 15 Jul 2021 07:59:32 +0000 Subject: [PATCH 35/42] Fix activateWarranty. #591 --- src/Controller/ResqAPI/WarrantyController.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Controller/ResqAPI/WarrantyController.php b/src/Controller/ResqAPI/WarrantyController.php index 4d9d83c8..8198098f 100644 --- a/src/Controller/ResqAPI/WarrantyController.php +++ b/src/Controller/ResqAPI/WarrantyController.php @@ -287,7 +287,7 @@ class WarrantyController extends APIController return new APIResponse(true, 'Warranty checked', $data); } - public function activateWarranty(Request $req, EntityManagerInterface $em) + public function activateWarranty(Request $req, EntityManagerInterface $em, MobileAPIHandler $mah) { $this->denyAccessUnlessGranted('mobile_warranty.activate', null, 'No access.'); @@ -323,7 +323,9 @@ class WarrantyController extends APIController $em->flush(); - return new APIResponse(true, 'Warranty activated'); + $data = $this->generateWarrantyData($warranty); + + return new APIResponse(true, 'Warranty activated', $data); } protected function handlePictureUpload($file, $target_dir, $serial, $name) -- 2.43.5 From b0c04984abc54cc1509f3a2e1612679ff67452a2 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 15 Jul 2021 08:54:26 +0000 Subject: [PATCH 36/42] Remove CMB code. #591 --- config/acl.yaml | 8 - config/cmb.menu.yaml | 179 ------------- config/cmb.services.yaml | 235 ----------------- config/routes/job_order.yaml | 40 --- src/Controller/CustomerController.php | 4 +- src/Controller/JobOrderController.php | 181 +------------ .../JobOrderHandler/ResqJobOrderHandler.php | 239 ------------------ src/Service/JobOrderHandlerInterface.php | 9 - 8 files changed, 2 insertions(+), 893 deletions(-) delete mode 100644 config/cmb.menu.yaml delete mode 100644 config/cmb.services.yaml diff --git a/config/acl.yaml b/config/acl.yaml index fb623290..838d46dd 100644 --- a/config/acl.yaml +++ b/config/acl.yaml @@ -258,14 +258,6 @@ access_keys: label: Edit - id: joborder.cancel label: Cancel - - id: jo_onestep.form - label: One-step Process - - id: jo_onestep.edit - label: One-step Process Edit - - id: jo_walkin.form - label: Walk-in - - id: jo_walkin.edit - label: Walk-in Edit - id: jo_autoassign.test label: Autoassign Test - id: jo_hub.list diff --git a/config/cmb.menu.yaml b/config/cmb.menu.yaml deleted file mode 100644 index 9f28b315..00000000 --- a/config/cmb.menu.yaml +++ /dev/null @@ -1,179 +0,0 @@ -main_menu: - - id: home - acl: dashboard.menu - label: Dashboard - icon: flaticon-line-graph - - id: user - acl: user.menu - label: User - icon: flaticon-users - - id: user_list - acl: user.list - label: Users - parent: user - - id: role_list - acl: role.list - label: Roles - parent: user - - - id: apiuser - acl: apiuser.menu - label: API User - icon: flaticon-users - - id: api_user_list - acl: apiuser.list - label: API Users - parent: apiuser - - id: api_role_list - acl: apirole.list - label: API Roles - parent: apiuser - - - id: logistics - acl: logistics.menu - label: Logistics - icon: fa fa-truck - - id: rider_list - acl: rider.list - label: Riders - parent: logistics - - id: service_charge_list - acl: service_charge.list - label: Service Charges - parent: logistics - - - id: battery - acl: battery.menu - label: Battery - icon: fa fa-battery-3 - - id: battery_list - acl: battery.list - label: Batteries - parent: battery - - id: bmfg_list - acl: bmfg.list - label: Manufacturers - parent: battery - - id: bmodel_list - acl: bmodel.list - label: Models - parent: battery - - id: bsize_list - acl: bsize.list - label: Sizes - parent: battery - - id: promo_list - acl: promo.list - label: Promos - parent: battery - - - id: vehicle - acl: vehicle.menu - label: Vehicle - icon: fa fa-car - - id: vehicle_list - acl: vehicle.list - label: Vehicles - parent: vehicle - - id: vmfg_list - acl: vmfg.list - label: Manufacturers - parent: vehicle - - - id: location - acl: location.menu - label: Location - icon: fa fa-home - - id: outlet_list - acl: outlet.menu - label: Outlet - parent: location - - id: hub_list - acl: hub.menu - label: Hub - parent: location - - id: geofence_list - acl: geofence.menu - label: Geofence - parent: location - - - - id: joborder - acl: joborder.menu - label: Job Order - icon: flaticon-calendar-3 - - id: jo_onestep_form - acl: jo_onestep.form - label: One-step Process - parent: joborder - - id: jo_walkin_form - acl: jo_walkin.form - label: Walk-in - parent: joborder - - id: jo_open - acl: jo_open.list - label: Open - parent: joborder - - id: jo_all - acl: jo_all.list - label: View All - parent: joborder - - - id: support - acl: support.menu - label: Customer Support - icon: flaticon-support - - id: customer_list - acl: customer.list - label: Customers - parent: support - - id: ticket_list - acl: ticket.list - label: Tickets - parent: support - - id: general_search - acl: general.search - label: Search - parent: support - - id: warranty_search - acl: warranty.search - label: Customer Battery Search - parent: support - - id: privacy_policy_list - acl: privacy_policy.list - label: Privacy Policy - parent: support - - id: warranty_list - acl: warranty.list - label: Warranty - parent: support - - id: warranty_upload - acl: warranty.upload - label: Warranty Upload - parent: support - - id: static_content_list - acl: static_content.list - label: Static Content - parent: support - - - id: service - acl: service.menu - label: Other Services - icon: flaticon-squares - - id: service_list - acl: service.list - label: Services - parent: service - - - id: partner - acl: partner.menu - label: Partners - icon: flaticon-network - - id: partner_list - acl: partner.list - label: Partners - parent: partner - - id: review_list - acl: review.list - label: Reviews - parent: partner diff --git a/config/cmb.services.yaml b/config/cmb.services.yaml deleted file mode 100644 index 5f24e525..00000000 --- a/config/cmb.services.yaml +++ /dev/null @@ -1,235 +0,0 @@ -# Put parameters here that don't need to change on each machine where the app is deployed -# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration -parameters: - map_default: - latitude: 14.6091 - longitude: 121.0223 - image_upload_directory: '%kernel.project_dir%/public/uploads' - job_order_refresh_interval: 300000 - api_acl_file: 'api_acl.yaml' - api_access_key: 'api_access_keys' - app_acl_file: 'acl.yaml' - app_access_key: 'access_keys' - cvu_brand_id: "%env(CVU_BRAND_ID)%" - country_code: "%env(COUNTRY_CODE)%" - -services: - # default configuration for services in *this* file - _defaults: - autowire: true # Automatically injects dependencies in your services. - autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. - public: false # Allows optimizing the container by removing unused services; this also means - # fetching services directly from the container via $container->get() won't work. - # The best practice is to be explicit about your dependencies anyway. - - # makes classes in src/ available to be used as services - # this creates a service per class whose id is the fully-qualified class name - App\: - resource: '../src/*' - exclude: '../src/{Entity,Migrations,Tests,Menu,Access}' - - # controllers are imported separately to make sure services can be injected - # as action arguments even if you don't extend any base controller class - App\Controller\: - resource: '../src/Controller' - tags: ['controller.service_arguments'] - - # add more service definitions when explicit configuration is needed - # please note that last definitions always *replace* previous ones - App\Menu\Generator: - arguments: - $router: "@router.default" - $cache_dir: "%kernel.cache_dir%" - $config_dir: "%kernel.root_dir%/../config" - - Catalyst\AuthBundle\Service\ACLGenerator: - arguments: - $router: "@router.default" - $cache_dir: "%kernel.cache_dir%" - $config_dir: "%kernel.root_dir%/../config" - $acl_file: "%app_acl_file%" - - Catalyst\AuthBundle\Service\ACLVoter: - arguments: - $user_class: "App\\Entity\\User" - tags: ['security.voter'] - - Catalyst\AuthBundle\Service\UserChecker: - - App\Service\FileUploader: - arguments: - $target_dir: '%image_upload_directory%' - - App\Service\MapTools: - arguments: - $em: "@doctrine.orm.entity_manager" - $gmaps_api_key: "%env(GMAPS_API_KEY)%" - $cust_dist_limit: "%env(CUST_DISTANCE_LIMIT)%" - - App\Service\RisingTideGateway: - arguments: - $em: "@doctrine.orm.entity_manager" - $user: "%env(RT_USER)%" - $pass: "%env(RT_PASS)%" - $usage_type: "%env(RT_USAGE_TYPE)%" - $shortcode: "%env(RT_SHORTCODE)%" - - App\Service\MQTTClient: - arguments: - $redis_client: "@App\\Service\\RedisClientProvider" - $key: "mqtt_events" - - App\Service\APNSClient: - arguments: - $redis_client: "@App\\Service\\RedisClientProvider" - - App\Service\RedisClientProvider: - arguments: - $scheme: "%env(REDIS_CLIENT_SCHEME)%" - $host: "%env(REDIS_CLIENT_HOST)%" - $port: "%env(REDIS_CLIENT_PORT)%" - $password: "%env(REDIS_CLIENT_PASSWORD)%" - - App\Service\GeofenceTracker: - arguments: - $geofence_flag: "%env(GEOFENCE_ENABLE)%" - - App\Service\WarrantyHandler: - arguments: - $em: "@doctrine.orm.entity_manager" - - App\Command\SetCustomerPrivacyPolicyCommand: - arguments: - $policy_promo: "%env(POLICY_PROMO)%" - $policy_third_party: "%env(POLICY_THIRD_PARTY)%" - $policy_mobile: "%env(POLICY_MOBILE)%" - - App\Command\CreateCustomerFromWarrantyCommand: - arguments: - $cvu_mfg_id: "%env(CVU_MFG_ID)%" - $cvu_brand_id: "%env(CVU_BRAND_ID)%" - - # rider tracker service - App\Service\RiderTracker: - arguments: - $redis_client: "@App\\Service\\RedisClientProvider" - - Catalyst\APIBundle\Security\APIKeyUserProvider: - arguments: - $em: "@doctrine.orm.entity_manager" - - Catalyst\APIBundle\Security\APIKeyAuthenticator: - arguments: - $em: "@doctrine.orm.entity_manager" - - Catalyst\APIBundle\Command\UserCreateCommand: - arguments: - $em: "@doctrine.orm.entity_manager" - tags: ['console.command'] - - Catalyst\APIBundle\Command\TestCommand: - tags: ['console.command'] - - Catalyst\APIBundle\Command\TestAPICommand: - tags: ['console.command'] - - Catalyst\APIBundle\Access\Voter: - arguments: - $acl_gen: "@Catalyst\\APIBundle\\Access\\Generator" - $user_class: "Catalyst\\APIBundle\\Entity\\User" - tags: ['security.voter'] - - Catalyst\APIBundle\Access\Generator: - arguments: - $router: "@router.default" - $cache_dir: "%kernel.cache_dir%" - $config_dir: "%kernel.root_dir%/../config" - $acl_file: "%api_acl_file%" - - Catalyst\MenuBundle\Menu\Generator: - arguments: - $router: "@router.default" - $cache_dir: "%kernel.cache_dir%" - $config_dir: "%kernel.root_dir%/../config" - - Catalyst\MenuBundle\Listener\MenuAnnotationListener: - arguments: - $menu_name: "main_menu" - tags: - - { name: kernel.event_listener, event: kernel.controller, method: onKernelController } - - # invoice generator - App\Service\InvoiceGenerator\CMBInvoiceGenerator: ~ - - # invoice generator interface - App\Service\InvoiceGeneratorInterface: "@App\\Service\\InvoiceGenerator\\CMBInvoiceGenerator" - - # job order generator - App\Service\JobOrderHandler\CMBJobOrderHandler: - arguments: - $country_code: "%env(COUNTRY_CODE)%" - - #job order generator interface - App\Service\JobOrderHandlerInterface: "@App\\Service\\JobOrderHandler\\CMBJobOrderHandler" - - # customer generator - App\Service\CustomerHandler\CMBCustomerHandler: - arguments: - $country_code: "%env(COUNTRY_CODE)%" - - # customer generator interface - App\Service\CustomerHandlerInterface: "@App\\Service\\CustomerHandler\\CMBCustomerHandler" - - # rider assignment - App\Service\RiderAssignmentHandler\CMBRiderAssignmentHandler: ~ - - # rider assignment interface - App\Service\RiderAssignmentHandlerInterface: "@App\\Service\\RiderAssignmentHandler\\CMBRiderAssignmentHandler" - - # rider API service - App\Service\RiderAPIHandler\CMBRiderAPIHandler: - arguments: - $country_code: "%env(COUNTRY_CODE)%" - - # rider API interface - App\Service\RiderAPIHandlerInterface: "@App\\Service\\RiderAPIHandler\\CMBRiderAPIHandler" - - # map manager - #App\Service\GISManager\Bing: ~ - App\Service\GISManager\OpenStreet: ~ - #App\Service\GISManager\Google: ~ - - #App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Bing" - App\Service\GISManagerInterface: "@App\\Service\\GISManager\\OpenStreet" - #App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Google" - - App\EventListener\JobOrderActiveCacheListener: - arguments: - $jo_cache: "@App\\Service\\JobOrderCache" - $mqtt: "@App\\Service\\MQTTClient" - tags: - - name: 'doctrine.orm.entity_listener' - event: 'postUpdate' - entity: 'App\Entity\JobOrder' - - name: 'doctrine.orm.entity_listener' - event: 'postRemove' - entity: 'App\Entity\JobOrder' - - name: 'doctrine.orm.entity_listener' - event: 'postPersist' - entity: 'App\Entity\JobOrder' - - App\Service\JobOrderCache: - arguments: - $redis_prov: "@App\\Service\\RedisClientProvider" - $active_jo_key: "%env(LOCATION_JO_ACTIVE_KEY)%" - - App\Service\RiderCache: - arguments: - $redis_prov: "@App\\Service\\RedisClientProvider" - $loc_key: "%env(LOCATION_RIDER_ACTIVE_KEY)%" - $status_key: "%env(STATUS_RIDER_KEY)%" - - # API logging - App\EventSubscriber\LogSubscriber: - arguments: - $api_log_flag: "%env(API_LOGGING)%" diff --git a/config/routes/job_order.yaml b/config/routes/job_order.yaml index 6ea3a3c5..a67620d6 100644 --- a/config/routes/job_order.yaml +++ b/config/routes/job_order.yaml @@ -176,26 +176,6 @@ jo_reject_hub: controller: App\Controller\JobOrderController::rejectHubSubmit methods: [POST] -jo_onestep_form: - path: /job-order/onestep - controller: App\Controller\JobOrderController::oneStepForm - methods: [GET] - -jo_onestep_submit: - path: /job-order/onestep - controller: App\Controller\JobOrderController::oneStepSubmit - methods: [POST] - -jo_onestep_edit_form: - path: /job-order/onestep/{id}/edit - controller: App\Controller\JobOrderController::oneStepEditForm - methods: [GET] - -jo_onestep_edit_submit: - path: /job-order/onestep/{id}/edit - controller: App\Controller\JobOrderController::oneStepEditSubmit - methods: [POST] - jo_ajax_popup: path: /job-order/{id}/popup controller: App\Controller\JobOrderController::popupInfo @@ -206,26 +186,6 @@ jo_tracker: controller: App\Controller\JobOrderController::tracker methods: [GET] -jo_walkin_form: - path: /job-order/walk-in - controller: App\Controller\JobOrderController::walkInForm - methods: [GET] - -jo_walkin_submit: - path: /job-order/walk-in - controller: App\Controller\JobOrderController::walkInSubmit - methods: [POST] - -jo_walkin_edit_form: - path: /job-order/walk-in/{id} - controller: App\Controller\JobOrderController::walkInEditForm - methods: [GET] - -jo_walkin_edit_submit: - path: /job-order/walk-in/{id} - controller: App\Controller\JobOrderController::walkInEditSubmit - methods: [POST] - jo_autoassign: path: /job-order/autoassign controller: App\Controller\JobOrderController::autoAssignForm diff --git a/src/Controller/CustomerController.php b/src/Controller/CustomerController.php index e15e050d..a8f1da4a 100644 --- a/src/Controller/CustomerController.php +++ b/src/Controller/CustomerController.php @@ -182,9 +182,7 @@ class CustomerController extends Controller public function getCustomerVehicles(Request $req, CustomerHandlerInterface $cust_handler) { - if (!(($this->isGranted('jo_onestep.form')) || - ($this->isGranted('jo_walkin.form')) || - ($this->isGranted('jo_in.list')))) + if (!($this->isGranted('jo_in.list'))) { $exception = $this->createAccessDeniedException('No access.'); throw $exception; diff --git a/src/Controller/JobOrderController.php b/src/Controller/JobOrderController.php index fbab3cb2..acc302fe 100644 --- a/src/Controller/JobOrderController.php +++ b/src/Controller/JobOrderController.php @@ -4,7 +4,6 @@ namespace App\Controller; use App\Ramcar\JOStatus; use App\Ramcar\InvoiceCriteria; -use App\Ramcar\CMBServiceType; use App\Ramcar\ServiceType; use App\Ramcar\JOCancelReasons; @@ -291,13 +290,11 @@ class JobOrderController extends Controller $rows[$key]['meta']['reassign_rider_url'] = $this->generateUrl('jo_open_rider_form', ['id' => $jo_id]); // $rows[$key]['meta']['edit_url'] = $this->generateUrl('jo_open_edit_form', ['id' => $jo_id]); $rows[$key]['meta']['edit_url'] = $this->generateUrl($jo_handler->getEditRoute($jo_id, $tier_params['edit_route']), ['id' => $jo_id]); - $rows[$key]['meta']['onestep_edit_url'] = $this->generateUrl('jo_onestep_edit_form', ['id' => $jo_id]); } else { // $rows[$key]['meta']['update_url'] = $this->generateUrl($tier_params['edit_route'], ['id' => $jo_id]); $rows[$key]['meta']['update_url'] = $this->generateUrl($jo_handler->getEditRoute($jo_id, $tier_params['edit_route']), ['id' => $jo_id]); - $rows[$key]['meta']['onestep_edit_url'] = $this->generateUrl('jo_onestep_edit_form', ['id' => $jo_id]); $rows[$key]['meta']['pdf_url'] = $this->generateUrl('jo_pdf_form', ['id' => $jo_id]); } @@ -853,95 +850,6 @@ class JobOrderController extends Controller ]); } - /** - * @Menu(selected="jo_onestep_form") - */ - public function oneStepForm(EntityManagerInterface $em, JobOrderHandlerInterface $jo_handler, GISManagerInterface $gis) - { - $this->denyAccessUnlessGranted('jo_onestep.form', null, 'No access.'); - - $params = $jo_handler->initializeOneStepForm(); - $params['submit_url'] = $this->generateUrl('jo_onestep_submit'); - $params['return_url'] = $this->generateUrl('jo_onestep_form'); - $params['map_js_file'] = $gis->getJSJOFile(); - $params['vmfgs'] = $em->getRepository(VehicleManufacturer::class)->findAll(); - $params['vmakes'] = $em->getRepository(Vehicle::class)->findAll(); - - $template = $params['template']; - - // response - return $this->render($template, $params); - } - - public function oneStepSubmit(Request $req, JobOrderHandlerInterface $jo_handler) - { - $this->denyAccessUnlessGranted('jo_onestep.form', null, 'No access.'); - - // initialize error list - $error_array = []; - $id = -1; - $error_array = $jo_handler->processOneStepJobOrder($req, $id); - - // check if any errors were found - if (!empty($error_array)) { - // return validation failure response - return $this->json([ - 'success' => false, - 'errors' => $error_array - ], 422); - } - - - // return successful response - return $this->json([ - 'success' => 'Changes have been saved!' - ]); - } - - /** - * @Menu(selected="jo_onestep_edit_form") - */ - public function oneStepEditForm($id, EntityManagerInterface $em, JobOrderHandlerInterface $jo_handler, - GISManagerInterface $gis, MapTools $map_tools) - { - $this->denyAccessUnlessGranted('jo_onestep.edit', null, 'No access.'); - - $params = $jo_handler->initializeOneStepEditForm($id, $map_tools); - $params['submit_url'] = $this->generateUrl('jo_onestep_edit_submit', ['id' => $id]); - $params['return_url'] = $this->generateUrl('jo_open'); - $params['map_js_file'] = $gis->getJSJOFile(); - $params['vmfgs'] = $em->getRepository(VehicleManufacturer::class)->findAll(); - $params['vmakes'] = $em->getRepository(Vehicle::class)->findAll(); - - $template = $params['template']; - - // response - return $this->render($template, $params); - } - - public function oneStepEditSubmit(Request $req, JobOrderHandlerInterface $jo_handler, $id) - { - $this->denyAccessUnlessGranted('jo_onestep.edit', null, 'No access.'); - - $error_array = []; - $error_array = $jo_handler->processOneStepJobOrder($req, $id); - - // check if any errors were found - if (!empty($error_array)) { - // return validation failure response - return $this->json([ - 'success' => false, - 'errors' => $error_array - ], 422); - } - - - // return successful response - return $this->json([ - 'success' => 'Changes have been saved!' - ]); - } - /** * @ParamConverter("jo", class="App\Entity\JobOrder") */ @@ -978,99 +886,12 @@ class JobOrderController extends Controller $params['jo'] = $jo; $params['rider'] = $rider; $params['rider_pos'] = $rider_tracker->getRiderLocation($rider->getID()); - $params['service_type'] = CMBServiceType::getName($jo->getServiceType()); + $params['service_type'] = ServiceType::getName($jo->getServiceType()); $params['map_js_file'] = $gis_manager->getJSInitFile(); return $this->render('job-order/tracker.html.twig', $params); } - /** - * @Menu(selected="jo_walkin_form") - */ - public function walkInForm(EntityManagerInterface $em, JobOrderHandlerInterface $jo_handler) - { - $this->denyAccessUnlessGranted('jo_walkin.form', null, 'No access.'); - - $params = $jo_handler->initializeWalkinForm(); - $params['submit_url'] = $this->generateUrl('jo_walkin_submit'); - $params['return_url'] = $this->generateUrl('jo_walkin_form'); - $params['vmfgs'] = $em->getRepository(VehicleManufacturer::class)->findAll(); - $params['vmakes'] = $em->getRepository(Vehicle::class)->findAll(); - $params['hubs'] = $em->getRepository(Hub::class)->findAll(); - - $template = $params['template']; - - // response - return $this->render($template, $params); - } - - public function walkInSubmit(Request $req, JobOrderHandlerInterface $jo_handler) - { - $this->denyAccessUnlessGranted('jo_walkin.form', null, 'No access.'); - - // initialize error list - $error_array = []; - $id = -1; - $error_array = $jo_handler->processWalkinJobOrder($req, $id); - - // check if any errors were found - if (!empty($error_array)) { - // return validation failure response - return $this->json([ - 'success' => false, - 'errors' => $error_array - ], 422); - } - - // return successful response - return $this->json([ - 'success' => 'Changes have been saved!' - ]); - } - - /** - * @Menu(selected="jo_walkin_edit_form") - */ - public function walkInEditForm($id, EntityManagerInterface $em, JobOrderHandlerInterface $jo_handler) - { - $this->denyAccessUnlessGranted('jo_walkin.edit', null, 'No access.'); - - $params = $jo_handler->initializeWalkinEditForm($id); - $params['submit_url'] = $this->generateUrl('jo_walkin_edit_submit', ['id' => $id]); - $params['return_url'] = $this->generateUrl('jo_open'); - $params['vmfgs'] = $em->getRepository(VehicleManufacturer::class)->findAll(); - $params['vmakes'] = $em->getRepository(Vehicle::class)->findAll(); - $params['hubs'] = $em->getRepository(Hub::class)->findAll(); - - $template = $params['template']; - - // response - return $this->render($template, $params); - } - - public function walkInEditSubmit(Request $req, JobOrderHandlerInterface $jo_handler, $id) - { - $this->denyAccessUnlessGranted('jo_walkin.edit', null, 'No access.'); - - $error_array = []; - $error_array = $jo_handler->processWalkinJobOrder($req, $id); - - // check if any errors were found - if (!empty($error_array)) { - // return validation failure response - return $this->json([ - 'success' => false, - 'errors' => $error_array - ], 422); - } - - - // return successful response - return $this->json([ - 'success' => 'Changes have been saved!' - ]); - } - /** * @Menu(selected="jo_hub_view") */ diff --git a/src/Service/JobOrderHandler/ResqJobOrderHandler.php b/src/Service/JobOrderHandler/ResqJobOrderHandler.php index 971f6903..6785ab0e 100644 --- a/src/Service/JobOrderHandler/ResqJobOrderHandler.php +++ b/src/Service/JobOrderHandler/ResqJobOrderHandler.php @@ -1517,157 +1517,6 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface } - // CMB code - public function processOneStepJobOrder(Request $req, $id) - { - // initialize error list - $error_array = []; - - $em = $this->em; - - $jo = $em->getRepository(JobOrder::class)->find($id); - if (empty($jo)) - { - // new job order - $jo = new JobOrder(); - } - - // check if lat and lng are provided - if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) { - $error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.'; - } - - // check if customer vehicle is set - if (empty($req->request->get('customer_vehicle'))) { - $error_array['customer_vehicle'] = 'No vehicle selected.'; - } else { - // get customer vehicle - $cust_vehicle = $em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle')); - - if (empty($cust_vehicle)) { - $error_array['customer_vehicle'] = 'Invalid vehicle specified.'; - } - } - - // check if hub AND rider is selected - if ((empty($req->request->get('hub_id'))) && - (empty($req->request->get('rider_id')))) { - $error_array['hub'] = 'No hub selected.'; - } else { - if (empty($req->request->get('rider_id'))) { - $error_array['rider'] = 'No rider selected.'; - } else { - // get hub - $hub = $em->getRepository(Hub::class)->find($req->request->get('hub_id')); - - if (empty($hub)) { - $error_array['hub'] = 'Invalid hub specified.'; - } else { - // get rider - $rider = $em->getRepository(Rider::class)->find($req->request->get('rider_id')); - - if (empty($rider)) { - $error_array['rider'] = 'Invalid rider specified.'; - } - } - } - } - - if (empty($error_array)) - { - // get current user - $user = $this->security->getUser(); - - // coordinates - $point = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat')); - - $stype = $req->request->get('service_type'); - - // set and save values - $jo->setDateSchedule(DateTime::createFromFormat("d M Y h:i A", $req->request->get('date_schedule_date') . " " . $req->request->get('date_schedule_time'))) - ->setCoordinates($point) - ->setAdvanceOrder($req->request->get('flag_advance') ?? false) - ->setServiceType($stype) - ->setWarrantyClass($req->request->get('warranty_class')) - ->setCustomer($cust_vehicle->getCustomer()) - ->setCustomerVehicle($cust_vehicle) - ->setSource($req->request->get('source')) - ->setStatus(JOStatus::ASSIGNED) - ->setDeliveryInstructions($req->request->get('delivery_instructions')) - ->setTier1Notes($req->request->get('tier1_notes')) - ->setTier2Notes($req->request->get('tier2_notes')) - ->setDeliveryAddress($req->request->get('delivery_address')) - ->setORName($req->request->get('or_name')) - ->setPromoDetail($req->request->get('promo_detail')) - ->setModeOfPayment($req->request->get('mode_of_payment')) - ->setLandmark($req->request->get('landmark')) - ->setHub($hub) - ->setRider($rider); - - // check if user is null, meaning call to create came from API - if ($user != null) - { - $jo->setCreatedBy($user); - } - - // check if reference JO is set and validate - if (!empty($req->request->get('ref_jo'))) { - // get reference JO - $ref_jo = $em->getRepository(JobOrder::class)->find($req->request->get('ref_jo')); - - if (empty($ref_jo)) { - $error_array['ref_jo'] = 'Invalid reference job order specified.'; - } else { - $jo->setReferenceJO($ref_jo); - } - } - - // call service to generate job order and invoice - $invoice_items = $req->request->get('invoice_items', []); - $promo_id = $req->request->get('invoice_promo'); - $invoice_change = $req->request->get('invoice_change', 0); - - // check if invoice changed - if ($invoice_change) - { - $this->ic->generateInvoiceCriteria($jo, $promo_id, $invoice_items, $error_array); - } - - // validate - $errors = $this->validator->validate($jo); - - // add errors to list - foreach ($errors as $error) { - $error_array[$error->getPropertyPath()] = $error->getMessage(); - } - - // check if errors are found - if (empty($error_array)) - { - // validated, no error. save the job order - $em->persist($jo); - - // the event - $event = new JOEvent(); - $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::CREATE) - ->setJobOrder($jo); - - if ($user != null) - { - $event->setUser($user); - } - - $em->persist($event); - $em->flush(); - } - } - - return $error_array; - - } - - // initialize incoming job order form public function initializeIncomingForm() { @@ -1684,83 +1533,6 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface return $params; } - // CMB code - public function initializeOneStepForm() - { - $params['obj'] = new JobOrder(); - $params['mode'] = 'onestep'; - - $this->fillDropdownParameters($params); - $this->fillFormTags($params); - - // get template to display - $params['template'] = $this->getTwigTemplate('jo_onestep'); - - // return params - return $params; - } - - // CMB code - public function initializeOneStepEditForm($id, $map_tools) - { - $em = $this->em; - $obj = $em->getRepository(JobOrder::class)->find($id); - - $params['obj'] = $obj; - $params['mode'] = 'onestep-edit'; - $params['cvid'] = $obj->getCustomerVehicle()->getID(); - $params['vid'] = $obj->getCustomerVehicle()->getVehicle()->getID(); - - $this->fillDropdownParameters($params); - $this->fillFormTags($params); - - // get the hubs - // TODO: move this snippet to a function - $hubs = $map_tools->getClosestHubs($obj->getCoordinates(), 50, date("H:i:s")); - - $params['hubs'] = []; - - // format duration and distance into friendly time - foreach ($hubs as $hub) { - // duration - $seconds = $hub['duration']; - - if (!empty($seconds) && $seconds > 0) { - $hours = floor($seconds / 3600); - $minutes = ceil(($seconds / 60) % 60); - - $hub['duration'] = ($hours > 0 ? number_format($hours) . " hr" . ($hours > 1 ? "s" : '') . ($minutes > 0 ? ", " : '') : '') . ($minutes > 0 ? number_format($minutes) . " min" . ($minutes > 1 ? "s" : '') : ''); - } else { - $hub['duration'] = false; - } - - // distance - $meters = $hub['distance']; - - if (!empty($meters) && $meters > 0) { - $hub['distance'] = round($meters / 1000) . " km"; - } else { - $hub['distance'] = false; - } - - // counters - $hub['rider_count'] = count($hub['hub']->getAvailableRiders()); - $hub['jo_count'] = count($hub['hub']->getForAssignmentJobOrders()); - - // check for rejection - $hub['flag_rejected'] = false; - $hub_id = $hub['hub']->getID(); - - $params['hubs'][] = $hub; - } - - - // get template to display - $params['template'] = $this->getTwigTemplate('jo_onestep_edit_form'); - - return $params; - } - // initialize open edit job order form public function initializeOpenEditForm($id) { @@ -2916,17 +2688,6 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $params['ftags']['invoice_edit'] = true; $params['ftags']['preset_vehicle'] = true; break; - case 'onestep': - $params['ftags']['vehicle_dropdown'] = true; - $params['ftags']['set_map_coordinate'] = false; - $params['ftags']['invoice_edit'] = true; - $params['ftags']['ticket_table'] = false; - $params['ftags']['cancel_button'] = false; - break; - case 'onestep-edit': - $params['ftags']['invoice_edit'] = true; - $params['ftags']['preset_vehicle'] = true; - break; } } diff --git a/src/Service/JobOrderHandlerInterface.php b/src/Service/JobOrderHandlerInterface.php index cff06242..77aa7cf0 100644 --- a/src/Service/JobOrderHandlerInterface.php +++ b/src/Service/JobOrderHandlerInterface.php @@ -25,9 +25,6 @@ interface JobOrderHandlerInterface // generate job order public function generateJobOrder(Request $req, int $id); - // process one step job order - public function processOneStepJobOrder(Request $req, int $id); - // dispatch job order public function dispatchJobOrder(Request $req, int $id, MQTTClient $mclient); @@ -82,12 +79,6 @@ interface JobOrderHandlerInterface // initialize rider form public function initializeRiderForm(int $id); - // initialize one step form - public function initializeOneStepForm(); - - // initialize one step edit form - public function initializeOneStepEditForm(int $id, MapTools $map_tools); - // generate pdf form for job order public function generatePDFForm(Request $req, int $id, string $proj_path); -- 2.43.5 From 19ec112bd2f0b6da294b2b0fd0503bdc9ca0561f Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 19 Jul 2021 10:08:38 +0000 Subject: [PATCH 37/42] Move JO event creation to job order service. #591 --- config/services.yaml | 7 + src/Controller/ResqAPI/JobOrderController.php | 56 +---- .../JobOrderHandler/ResqJobOrderHandler.php | 234 ++++++++++-------- src/Service/JobOrderManager.php | 89 ++++++- 4 files changed, 229 insertions(+), 157 deletions(-) diff --git a/config/services.yaml b/config/services.yaml index 41bd65ab..87fa1e05 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -304,3 +304,10 @@ services: App\Service\MobileAPIHandler: arguments: $em: "@doctrine.orm.entity_manager" + + # job order service + App\Service\JobOrderManager: + arguments: + $em: "@doctrine.orm.entity_manager" + $rah: "@App\\Service\\RiderAssignmentHandlerInterface" + diff --git a/src/Controller/ResqAPI/JobOrderController.php b/src/Controller/ResqAPI/JobOrderController.php index 73c7d835..6f2805c6 100644 --- a/src/Controller/ResqAPI/JobOrderController.php +++ b/src/Controller/ResqAPI/JobOrderController.php @@ -39,6 +39,7 @@ use App\Service\HubFilterLogger; use App\Service\HubFilteringGeoChecker; use App\Service\MobileAPIHandler; use App\Service\RiderTracker; +use App\Service\JobOrderManager; use App\Entity\JobOrder; use App\Entity\CustomerVehicle; @@ -47,6 +48,7 @@ use App\Entity\Battery; use App\Entity\JOEvent; use App\Entity\Customer; use App\Entity\Hub; +use App\Entity\Invoice; use Catalyst\APIBundle\Access\Generator as ACLGenerator; @@ -66,7 +68,7 @@ class JobOrderController extends APIController InventoryManager $im, MQTTClient $mclient, RiderAssignmentHandlerInterface $rah, PromoLogger $promo_logger, EntityManagerInterface $em, HubSelector $hub_select, HubDistributor $hub_dist, HubFilterLogger $hub_filter_logger, HubFilteringGeoChecker $hub_geofence, - MobileAPIHandler $mah) + MobileAPIHandler $mah, JobOrderManager $jo_manager) { $this->denyAccessUnlessGranted('mobile_jo.request', null, 'No access.'); @@ -134,7 +136,7 @@ class JobOrderController extends APIController $em->persist($invoice); // create JO event logs - $this->processEvents($em, $jo, $rah, $mclient, JOEventType::CREATE); + $jo_manager->processJobOrderEvents($jo, JOEventType::CREATE); // send mqtt events $payload = [ @@ -162,7 +164,7 @@ class JobOrderController extends APIController RiderAssignmentHandlerInterface $rah, PromoLogger $promo_logger, HubSelector $hub_select, HubDistributor $hub_dist, HubFilterLogger $hub_filter_logger, HubFilteringGeoChecker $hub_geofence, EntityManagerInterface $em, - MobileAPIHandler $mah) + MobileAPIHandler $mah, JobOrderManager $jo_manager) { $this->denyAccessUnlessGranted('mobile_jo.request', null, 'No access.'); @@ -260,7 +262,7 @@ class JobOrderController extends APIController $em->persist($invoice); // create JO event logs - $this->processEvents($em, $jo, $rah, $mclient, JOEventType::CREATE); + $jo_manager->processJobOrderEvents($jo, JOEventType::CREATE); // send mqtt events $payload = [ @@ -376,7 +378,8 @@ class JobOrderController extends APIController } public function cancelJobOrder(Request $req, MQTTClient $mclient, EntityManagerInterface $em, - MobileAPIHandler $mah, RiderAssignmentHandlerInterface $rah) + MobileAPIHandler $mah, RiderAssignmentHandlerInterface $rah, + JobOrderManager $jo_manager) { $this->denyAccessUnlessGranted('mobile_jo.cancel', null, 'No access.'); @@ -420,7 +423,7 @@ class JobOrderController extends APIController $jo->cancel($cancel_reason); // create event logs - $this->processEvents($em, $jo, $rah, $mclient, JOEventType::CANCEL); + $jo_manager->processJobOrderEvents($jo, JOEventType::CANCEL); // send mqtt events $payload = [ @@ -1110,47 +1113,6 @@ class JobOrderController extends APIController } } - protected function processEvents(EntityManagerInterface $em, JobOrder $jo, - RiderAssignmentHandlerInterface $rah, MQTTClient $mclient, - $jo_event_type) - { - // add event log for JO - $event = new JOEvent(); - $event->setDateHappen(new DateTime()) - ->setTypeID($jo_event_type) - ->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); - } - 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); - } - } - protected function processMQTTEvents(JobOrder $jo, $payload, MQTTClient $mclient, RiderAssignmentHandlerInterface$rah) { diff --git a/src/Service/JobOrderHandler/ResqJobOrderHandler.php b/src/Service/JobOrderHandler/ResqJobOrderHandler.php index 6785ab0e..fcc3b6b0 100644 --- a/src/Service/JobOrderHandler/ResqJobOrderHandler.php +++ b/src/Service/JobOrderHandler/ResqJobOrderHandler.php @@ -56,6 +56,7 @@ use App\Service\PromoLogger; use App\Service\HubSelector; use App\Service\HubDistributor; use App\Service\HubFilteringGeoChecker; +use App\Service\JobOrderManager; use CrEOF\Spatial\PHP\Types\Geometry\Point; @@ -80,6 +81,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface protected $promo_logger; protected $hub_dist; protected $hub_geofence; + protected $mclient; + protected $jo_manager; protected $template_hash; @@ -87,7 +90,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface InvoiceGeneratorInterface $ic, ValidatorInterface $validator, TranslatorInterface $translator, RiderAssignmentHandlerInterface $rah, string $country_code, WarrantyHandler $wh, RisingTideGateway $rt, - PromoLogger $promo_logger, HubDistributor $hub_dist, HubFilteringGeoChecker $hub_geofence) + PromoLogger $promo_logger, HubDistributor $hub_dist, HubFilteringGeoChecker $hub_geofence, + MQTTClient $mclient, JobOrderManager $jo_manager) { $this->em = $em; $this->ic = $ic; @@ -101,6 +105,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $this->promo_logger = $promo_logger; $this->hub_dist = $hub_dist; $this->hub_geofence = $hub_geofence; + $this->mclient = $mclient; + $this->jo_manager = $jo_manager; $this->loadTemplates(); } @@ -342,106 +348,18 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface ->setDpaConsent($is_dpa_checked); } - // check if lat and lng are provided - if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) { - $error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.'; - } - // check if customer vehicle is set - if (empty($req->request->get('customer_vehicle'))) { - $error_array['customer_vehicle'] = 'No vehicle selected.'; - } else { + // validate and set job order object + $this->validateJobOrder($req, $error_array); + if (empty($error_array)) + { // get customer vehicle $cust_vehicle = $em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle')); + // TODO: check status before saving since JO might already + // have a status that needs to be retained + $this->setJobOrderObject($req, $jo, $cust_vehicle); - if (empty($cust_vehicle)) { - $error_array['customer_vehicle'] = 'Invalid vehicle specified.'; - } - } - - // check if landmark is set - if (empty($req->request->get('landmark'))) - $error_array['landmark'] = 'Landmark is required.'; - - // check if customer is not willing to wait - $will_wait = $req->request->get('flag_willing_to_wait'); - $reason = ''; - $more_reason = ''; - if ($will_wait == WillingToWaitContent::NOT_WILLING_TO_WAIT) - { - // get the reason and text - $reason = $req->request->get('no_wait_reason'); - $more_reason = $req->request->get('not_wait_notes'); - } - - // check if service is battery sales - $stype = $req->request->get('service_type'); - $no_trade_in_reason = ''; - if ($stype == ServiceType::BATTERY_REPLACEMENT_NEW) - { - // check if trade in - $is_trade_in = $req->request->get('invoice_trade_in_type'); - if (empty($is_trade_in)) - { - $no_trade_in_reason = $req->request->get('no_trade_in_reason'); - - if (empty($no_trade_in_reason)) - $error_array['no_trade_in_reason'] = 'No trade in reason required.'; - } - } - - // TODO: check status before saving since JO might already - // have a status that needs to be retained - - if (empty($error_array)) { - // get current user - $user = $this->security->getUser(); - - // coordinates - $point = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat')); - - // set and save values - $jo->setDateSchedule(DateTime::createFromFormat("d M Y h:i A", $req->request->get('date_schedule_date') . " " . $req->request->get('date_schedule_time'))) - ->setCoordinates($point) - ->setAdvanceOrder($req->request->get('flag_advance') ?? false) - ->setServiceType($stype) - ->setWarrantyClass($req->request->get('warranty_class')) - ->setCustomer($cust_vehicle->getCustomer()) - ->setCustomerVehicle($cust_vehicle) - ->setSource($req->request->get('source')) - ->setStatus(JOStatus::PENDING) - ->setDeliveryInstructions($req->request->get('delivery_instructions')) - ->setTier1Notes($req->request->get('tier1_notes')) - ->setTier2Notes($req->request->get('tier2_notes')) - ->setDeliveryAddress($req->request->get('delivery_address')) - ->setORName($req->request->get('or_name')) - ->setPromoDetail($req->request->get('promo_detail')) - ->setModeOfPayment($req->request->get('mode_of_payment')) - ->setLandmark($req->request->get('landmark')) - ->setWillWait($req->request->get('flag_willing_to_wait')) - ->setReasonNotWait($reason) - ->setNotWaitingNotes($more_reason) - ->setNoTradeInReason($no_trade_in_reason); - - // check if user is null, meaning call to create came from API - if ($user != null) - { - $jo->setCreatedBy($user); - } - - // check if reference JO is set and validate - if (!empty($req->request->get('ref_jo'))) { - // get reference JO - $ref_jo = $em->getRepository(JobOrder::class)->find($req->request->get('ref_jo')); - - if (empty($ref_jo)) { - $error_array['ref_jo'] = 'Invalid reference job order specified.'; - } else { - $jo->setReferenceJO($ref_jo); - } - } - - // call service to generate job order and invoice + // call service to generate invoice $invoice_items = $req->request->get('invoice_items', []); $promo_id = $req->request->get('invoice_promo'); $invoice_change = $req->request->get('invoice_change', 0); @@ -467,18 +385,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $em->persist($jo); $em->persist($customer); - // the event - $event = new JOEvent(); - $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::CREATE) - ->setJobOrder($jo); + $this->jo_manager->processJobOrderEvents($jo, JOEventType::CREATE); - if ($user != null) - { - $event->setUser($user); - } - - $em->persist($event); $em->flush(); } } @@ -3004,6 +2912,116 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface } } + protected function validateJobOrder(Request $req, &$error_array) + { + // check if lat and lng are provided + if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) { + $error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.'; + } + + // check if customer vehicle is set + if (empty($req->request->get('customer_vehicle'))) { + $error_array['customer_vehicle'] = 'No vehicle selected.'; + } else { + // get customer vehicle + $cust_vehicle = $this->em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle')); + + if (empty($cust_vehicle)) { + $error_array['customer_vehicle'] = 'Invalid vehicle specified.'; + } + } + + // check if landmark is set + if (empty($req->request->get('landmark'))) + $error_array['landmark'] = 'Landmark is required.'; + + // check if service is battery sales + $stype = $req->request->get('service_type'); + if ($stype == ServiceType::BATTERY_REPLACEMENT_NEW) + { + // check if trade in + $is_trade_in = $req->request->get('invoice_trade_in_type'); + if (empty($is_trade_in)) + { + if (empty($req->request->get('no_trade_in_reason'))) + $error_array['no_trade_in_reason'] = 'No trade in reason required.'; + } + } + + // check if reference JO is set and validate + if (!empty($req->request->get('ref_jo'))) { + // get reference JO + $ref_jo = $em->getRepository(JobOrder::class)->find($req->request->get('ref_jo')); + + if (empty($ref_jo)) { + $error_array['ref_jo'] = 'Invalid reference job order specified.'; + } + } + } + + protected function setJobOrderObject(Request $req, JobOrder $jo, $cust_vehicle) + { + // check if customer is not willing to wait + $will_wait = $req->request->get('flag_willing_to_wait'); + $reason = ''; + $more_reason = ''; + if ($will_wait == WillingToWaitContent::NOT_WILLING_TO_WAIT) + { + // get the reason and text + $reason = $req->request->get('no_wait_reason'); + $more_reason = $req->request->get('not_wait_notes'); + } + + // check if service is battery sales + $stype = $req->request->get('service_type'); + $no_trade_in_reason = ''; + if ($stype == ServiceType::BATTERY_REPLACEMENT_NEW) + { + // check if trade in + $is_trade_in = $req->request->get('invoice_trade_in_type'); + if (empty($is_trade_in)) + $no_trade_in_reason = $req->request->get('no_trade_in_reason'); + } + + // coordinates + $point = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat')); + + // set and save values + $jo->setDateSchedule(DateTime::createFromFormat("d M Y h:i A", $req->request->get('date_schedule_date') . " " . $req->request->get('date_schedule_time'))) + ->setCoordinates($point) + ->setAdvanceOrder($req->request->get('flag_advance') ?? false) + ->setServiceType($stype) + ->setWarrantyClass($req->request->get('warranty_class')) + ->setCustomer($cust_vehicle->getCustomer()) + ->setCustomerVehicle($cust_vehicle) + ->setSource($req->request->get('source')) + ->setStatus(JOStatus::PENDING) + ->setDeliveryInstructions($req->request->get('delivery_instructions')) + ->setTier1Notes($req->request->get('tier1_notes')) + ->setTier2Notes($req->request->get('tier2_notes')) + ->setDeliveryAddress($req->request->get('delivery_address')) + ->setORName($req->request->get('or_name')) + ->setPromoDetail($req->request->get('promo_detail')) + ->setModeOfPayment($req->request->get('mode_of_payment')) + ->setLandmark($req->request->get('landmark')) + ->setWillWait($req->request->get('flag_willing_to_wait')) + ->setReasonNotWait($reason) + ->setNotWaitingNotes($more_reason) + ->setNoTradeInReason($no_trade_in_reason); + + // get current user + $user = $this->security->getUser(); + if ($user != null) + $jo->setCreatedBy($user); + + // check if reference JO is set + if (!empty($req->request->get('ref_jo'))) { + // get reference JO + $ref_jo = $em->getRepository(JobOrder::class)->find($req->request->get('ref_jo')); + $jo->setReferenceJO($ref_jo); + } + } + public function getEditRoute($jo_id, $tier) { if (empty($tier)) diff --git a/src/Service/JobOrderManager.php b/src/Service/JobOrderManager.php index c54557d6..6d35fc74 100644 --- a/src/Service/JobOrderManager.php +++ b/src/Service/JobOrderManager.php @@ -2,19 +2,34 @@ namespace App\Service; +use Doctrine\ORM\EntityManagerInterface; + +use Symfony\Component\Security\Core\Security; + use App\Entity\JobOrder; +use App\Entity\JOEvent; +use App\Entity\User; use App\Ramcar\ServiceType; +use App\Ramcar\JOStatus; +use App\Ramcar\JOEventType; -use Doctrine\ORM\EntityManagerInterface; +use DateTime; class JobOrderManager { protected $em; + protected $security; + protected $rah; + protected $mclient; - public function __construct(EntityManagerInterface $em) + public function __construct(EntityManagerInterface $em, Security $security, + RiderAssignmentHandlerInterface $rah, MQTTClient $mclient) { $this->em = $em; + $this->security = $security; + $this->rah = $rah; + $this->mclient = $mclient; } public function fulfillJobOrder($jo_id) @@ -51,4 +66,74 @@ class JobOrderManager $this->em->flush(); } } + + public function processJobOrderEvents(JobOrder $jo, $jo_event_type) + { + $em = $this->em; + + // check for the jo event type + if ($jo_event_type == JOEventType::CREATE) + { + // add event log for JO + $event = new JOEvent(); + $event->setDateHappen(new DateTime()) + ->setTypeID($jo_event_type) + ->setJobOrder($jo); + + $user = $this->security->getUser(); + // check if user is User or APIUser + if ($user instanceof User) + $event->setUser($user); + + $em->persist($event); + + // check for JO status for additional events + // (1) when mobile app gets a new JO, finds a hub and assigns a rider + 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); + } + // (2) when mobile app gets a new JO, finds a hub but no rider + 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); + } + } + // TODO: check for other JO event types + if ($jo_event_type == JOEventType::CANCEL) + { + // add event log for JO + $event = new JOEvent(); + $event->setDateHappen(new DateTime()) + ->setTypeID($jo_event_type) + ->setJobOrder($jo); + + $user = $this->security->getUser(); + // check if user is User or APIUser + if ($user instanceof User) + $event->setUser($user); + + $em->persist($event); + } + } + } -- 2.43.5 From e33b9eb71935aae55c71dc1da1d9d4369e991cf9 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 21 Jul 2021 04:13:04 +0000 Subject: [PATCH 38/42] Move customer tag removal to service. #591 --- src/Controller/ResqAPI/JobOrderController.php | 53 ++++++------------- .../JobOrderHandler/ResqJobOrderHandler.php | 24 ++------- src/Service/JobOrderManager.php | 23 ++++++++ 3 files changed, 41 insertions(+), 59 deletions(-) diff --git a/src/Controller/ResqAPI/JobOrderController.php b/src/Controller/ResqAPI/JobOrderController.php index 6f2805c6..355274fa 100644 --- a/src/Controller/ResqAPI/JobOrderController.php +++ b/src/Controller/ResqAPI/JobOrderController.php @@ -66,7 +66,7 @@ class JobOrderController extends APIController public function requestJobOrder(Request $req, InvoiceGeneratorInterface $ic, GeofenceTracker $geo, InventoryManager $im, MQTTClient $mclient, RiderAssignmentHandlerInterface $rah, - PromoLogger $promo_logger, EntityManagerInterface $em, HubSelector $hub_select, + EntityManagerInterface $em, HubSelector $hub_select, HubDistributor $hub_dist, HubFilterLogger $hub_filter_logger, HubFilteringGeoChecker $hub_geofence, MobileAPIHandler $mah, JobOrderManager $jo_manager) { @@ -154,15 +154,20 @@ class JobOrderController extends APIController 'invoice' => $invoice_data ]; - $this->removeCustomerTag($jo, $jo->getCustomerVehicle(), $promo_logger, $mobile_user->getID()); + // check service type + if ($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) + { + $customer_tags = $cust->getCustomerTagObjects(); + $jo_manager->removeCustomerTag($jo, $customer_tags, $mobile_user->getID()); + } return new APIResponse(true, 'Job order created', $data); } public function newRequestJobOrder(Request $req, InvoiceGeneratorInterface $ic, GeofenceTracker $geo, InventoryManager $im, MQTTClient $mclient, - RiderAssignmentHandlerInterface $rah, PromoLogger $promo_logger, - HubSelector $hub_select, HubDistributor $hub_dist, HubFilterLogger $hub_filter_logger, + RiderAssignmentHandlerInterface $rah, HubSelector $hub_select, + HubDistributor $hub_dist, HubFilterLogger $hub_filter_logger, HubFilteringGeoChecker $hub_geofence, EntityManagerInterface $em, MobileAPIHandler $mah, JobOrderManager $jo_manager) { @@ -281,7 +286,12 @@ class JobOrderController extends APIController 'invoice' => $invoice_data ]; - $this->removeCustomerTag($jo, $jo->getCustomerVehicle(), $promo_logger, $mobile_user->getID()); + // check service type + if ($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) + { + $customer_tags = $cust->getCustomerTagObjects(); + $jo_manager->removeCustomerTag($jo, $customer_tags, $mobile_user->getID()); + } return new APIResponse(true, 'Job order created', $data); } @@ -1167,39 +1177,6 @@ class JobOrderController extends APIController return $invoice_data; } - protected function removeCustomerTag(JobOrder $jo, CustomerVehicle $cv, PromoLogger $promo_logger, $mobile_user_id) - { - // check service type - if ($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) - { - $customer = $cv->getCustomer(); - $customer_tags = $customer->getCustomerTagObjects(); - if (!empty($customer_tags)) - { - foreach ($customer_tags as $customer_tag) - { - if ($customer_tag->getID() == $invoice->getUsedCustomerTagId()) - { - // remove associated entity - $customer->removeCustomerTag($customer_tag); - - // log the availment of promo from customer - $created_by = $mobile_user_id; - $cust_id = $jo->getCustomer()->getID(); - $cust_fname = $jo->getCustomer()->getFirstName(); - $cust_lname = $jo->getCustomer()->getLastName(); - $jo_id = $jo->getID(); - $invoice_id = $jo->getInvoice()->getID(); - // TODO: check if we store total price of invoice or just the discounted amount - $amount = $jo->getInvoice()->getTotalPrice(); - $promo_logger->logPromoInfo($created_by, $cust_id, $cust_fname, $cust_lname, $jo_id, - $invoice_id, $amount); - } - } - } - } - } - protected function generateJobOrderData($req, $jo, $rt, $mah) { $status = $jo->getStatus(); diff --git a/src/Service/JobOrderHandler/ResqJobOrderHandler.php b/src/Service/JobOrderHandler/ResqJobOrderHandler.php index fcc3b6b0..f425241c 100644 --- a/src/Service/JobOrderHandler/ResqJobOrderHandler.php +++ b/src/Service/JobOrderHandler/ResqJobOrderHandler.php @@ -403,30 +403,12 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface // check service type if ($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) { - $customer = $cust_vehicle->getCustomer(); + // process customer tags $customer_tags = $customer->getCustomerTagObjects(); if (!empty($customer_tags)) { - foreach ($customer_tags as $customer_tag) - { - if ($customer_tag->getID() == $jo->getInvoice()->getUsedCustomerTagId()) - { - // remove associated entity - $customer->removeCustomerTag($customer_tag); - - // log the availment of promo from customer - $created_by = $jo->getCreatedBy()->getUsername(); - $cust_id = $jo->getCustomer()->getID(); - $cust_fname = $jo->getCustomer()->getFirstName(); - $cust_lname = $jo->getCustomer()->getLastName(); - $jo_id = $jo->getID(); - $invoice_id = $jo->getInvoice()->getID(); - // TODO: check if we store total price of invoice or just the discounted amount - $amount = $jo->getInvoice()->getTotalPrice(); - $this->promo_logger->logPromoInfo($created_by, $cust_id, $cust_fname, $cust_lname, $jo_id, - $invoice_id, $amount); - } - } + $username = $jo->getCreatedBy()->getUsername(); + $this->jo_manager->removeCustomerTag($jo, $customer_tags, $username); } } } diff --git a/src/Service/JobOrderManager.php b/src/Service/JobOrderManager.php index 6d35fc74..27b32b6c 100644 --- a/src/Service/JobOrderManager.php +++ b/src/Service/JobOrderManager.php @@ -136,4 +136,27 @@ class JobOrderManager } } + public function removeCustomerTag(JobOrder $jo, $customer_tags, $username) + { + foreach ($customer_tags as $customer_tag) + { + if ($customer_tag->getID() == $jo->getInvoice()->getUsedCustomerTagId()) + { + // remove associated entity + $customer->removeCustomerTag($customer_tag); + + // log the availment of promo from customer + $created_by = $username; + $cust_id = $jo->getCustomer()->getID(); + $cust_fname = $jo->getCustomer()->getFirstName(); + $cust_lname = $jo->getCustomer()->getLastName(); + $jo_id = $jo->getID(); + $invoice_id = $jo->getInvoice()->getID(); + // TODO: check if we store total price of invoice or just the discounted amount + $amount = $jo->getInvoice()->getTotalPrice(); + $this->promo_logger->logPromoInfo($created_by, $cust_id, $cust_fname, $cust_lname, $jo_id, + $invoice_id, $amount); + } + } + } } -- 2.43.5 From 64bf68e445c3ae5bd4118c6faefd37eede89a5f3 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 21 Jul 2021 06:36:47 +0000 Subject: [PATCH 39/42] Fix bugs during testing customer tag removal. #591 --- src/Controller/ResqAPI/JobOrderController.php | 4 ++-- src/Service/JobOrderHandler/ResqJobOrderHandler.php | 2 +- src/Service/JobOrderManager.php | 8 ++++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Controller/ResqAPI/JobOrderController.php b/src/Controller/ResqAPI/JobOrderController.php index 355274fa..bad7799c 100644 --- a/src/Controller/ResqAPI/JobOrderController.php +++ b/src/Controller/ResqAPI/JobOrderController.php @@ -158,7 +158,7 @@ class JobOrderController extends APIController if ($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) { $customer_tags = $cust->getCustomerTagObjects(); - $jo_manager->removeCustomerTag($jo, $customer_tags, $mobile_user->getID()); + $jo_manager->removeCustomerTag($jo, $cust, $customer_tags, $mobile_user->getID()); } return new APIResponse(true, 'Job order created', $data); @@ -290,7 +290,7 @@ class JobOrderController extends APIController if ($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) { $customer_tags = $cust->getCustomerTagObjects(); - $jo_manager->removeCustomerTag($jo, $customer_tags, $mobile_user->getID()); + $jo_manager->removeCustomerTag($jo, $cust, $customer_tags, $mobile_user->getID()); } return new APIResponse(true, 'Job order created', $data); diff --git a/src/Service/JobOrderHandler/ResqJobOrderHandler.php b/src/Service/JobOrderHandler/ResqJobOrderHandler.php index f425241c..259c01d4 100644 --- a/src/Service/JobOrderHandler/ResqJobOrderHandler.php +++ b/src/Service/JobOrderHandler/ResqJobOrderHandler.php @@ -408,7 +408,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface if (!empty($customer_tags)) { $username = $jo->getCreatedBy()->getUsername(); - $this->jo_manager->removeCustomerTag($jo, $customer_tags, $username); + $this->jo_manager->removeCustomerTag($jo, $customer, $customer_tags, $username); } } } diff --git a/src/Service/JobOrderManager.php b/src/Service/JobOrderManager.php index 27b32b6c..8e9d2db7 100644 --- a/src/Service/JobOrderManager.php +++ b/src/Service/JobOrderManager.php @@ -9,6 +9,7 @@ use Symfony\Component\Security\Core\Security; use App\Entity\JobOrder; use App\Entity\JOEvent; use App\Entity\User; +use App\Entity\Customer; use App\Ramcar\ServiceType; use App\Ramcar\JOStatus; @@ -22,14 +23,17 @@ class JobOrderManager protected $security; protected $rah; protected $mclient; + protected $promo_logger; public function __construct(EntityManagerInterface $em, Security $security, - RiderAssignmentHandlerInterface $rah, MQTTClient $mclient) + RiderAssignmentHandlerInterface $rah, MQTTClient $mclient, + PromoLogger $promo_logger) { $this->em = $em; $this->security = $security; $this->rah = $rah; $this->mclient = $mclient; + $this->promo_logger = $promo_logger; } public function fulfillJobOrder($jo_id) @@ -136,7 +140,7 @@ class JobOrderManager } } - public function removeCustomerTag(JobOrder $jo, $customer_tags, $username) + public function removeCustomerTag(JobOrder $jo, Customer $customer, $customer_tags, $username) { foreach ($customer_tags as $customer_tag) { -- 2.43.5 From 5cfbb112a48e992f8ecce88caddab0a0d6e7f6cb Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 21 Jul 2021 07:13:06 +0000 Subject: [PATCH 40/42] Refactor editing of job order. #591 --- src/Controller/ResqAPI/JobOrderController.php | 1 - .../JobOrderHandler/ResqJobOrderHandler.php | 120 +++++------------- src/Service/JobOrderManager.php | 18 ++- 3 files changed, 47 insertions(+), 92 deletions(-) diff --git a/src/Controller/ResqAPI/JobOrderController.php b/src/Controller/ResqAPI/JobOrderController.php index bad7799c..6ac4dd23 100644 --- a/src/Controller/ResqAPI/JobOrderController.php +++ b/src/Controller/ResqAPI/JobOrderController.php @@ -32,7 +32,6 @@ use App\Service\MQTTClient; use App\Service\GeofenceTracker; use App\Service\InventoryManager; use App\Service\RiderAssignmentHandlerInterface; -use App\Service\PromoLogger; use App\Service\HubSelector; use App\Service\HubDistributor; use App\Service\HubFilterLogger; diff --git a/src/Service/JobOrderHandler/ResqJobOrderHandler.php b/src/Service/JobOrderHandler/ResqJobOrderHandler.php index 259c01d4..f569f977 100644 --- a/src/Service/JobOrderHandler/ResqJobOrderHandler.php +++ b/src/Service/JobOrderHandler/ResqJobOrderHandler.php @@ -355,8 +355,6 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface { // get customer vehicle $cust_vehicle = $em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle')); - // TODO: check status before saving since JO might already - // have a status that needs to be retained $this->setJobOrderObject($req, $jo, $cust_vehicle); // call service to generate invoice @@ -378,17 +376,21 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $error_array[$error->getPropertyPath()] = $error->getMessage(); } - // check if errors are found - if (empty($error_array)) - { - // validated, no error. save the job order and customer - $em->persist($jo); - $em->persist($customer); - - $this->jo_manager->processJobOrderEvents($jo, JOEventType::CREATE); - - $em->flush(); + // check if any errors were found + if (!empty($error_array)) { + // return validation failure response + return $this->json([ + 'success' => false, + 'errors' => $error_array + ], 422); } + + $em->persist($jo); + $em->persist($customer); + + $this->jo_manager->processJobOrderEvents($jo, JOEventType::CREATE); + + $em->flush(); } $data['error_array'] = $error_array; @@ -431,69 +433,15 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface if (empty($obj)) throw $this->createNotFoundException('The item does not exist'); - // check if lat and lng are provided - if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) { - $error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.'; - } - - // check if landmark is set - if (empty($req->request->get('landmark'))) - $error_array['landmark'] = 'Landmark is required.'; - - // check if customer is not willing to wait - $will_wait = $req->request->get('flag_willing_to_wait'); - $reason = ''; - $more_reason = ''; - if ($will_wait == WillingToWaitContent::NOT_WILLING_TO_WAIT) + // validate and set job order object + $this->validateJobOrder($req, $error_array); + if (empty($error_array)) { - // get the reason and text - $reason = $req->request->get('no_wait_reason'); - $more_reason = $req->request->get('not_wait_notes'); - } - - // check if service type is battery sales - $stype = $req->request->get('service_type'); - $no_trade_in_reason = ''; - if ($stype == ServiceType::BATTERY_REPLACEMENT_NEW) - { - // check if trade in - $is_trade_in = $req->request->get('invoice_trade_in_type'); - if (empty($is_trade_in)) - { - $no_trade_in_reason = $req->request->get('no_trade_in_reason'); - - if (empty($no_trade_in_reason)) - $error_array['no_trade_in_reason'] = 'No trade in reason required.'; - } - } - - if (empty($error_array)) - { - // get current user - $user = $this->security->getUser(); - - // coordinates - $point = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat')); - - // set and save values - $obj->setDateSchedule(DateTime::createFromFormat("d M Y h:i A", $req->request->get('date_schedule_date') . " " . $req->request->get('date_schedule_time'))) - ->setCoordinates($point) - ->setAdvanceOrder($req->request->get('flag_advance') ?? false) - ->setServiceType($stype) - ->setWarrantyClass($req->request->get('warranty_class')) - ->setSource($req->request->get('source')) - ->setDeliveryInstructions($req->request->get('delivery_instructions')) - ->setTier1Notes($req->request->get('tier1_notes')) - ->setTier2Notes($req->request->get('tier2_notes')) - ->setDeliveryAddress($req->request->get('delivery_address')) - ->setORName($req->request->get('or_name')) - ->setPromoDetail($req->request->get('promo_detail')) - ->setModeOfPayment($req->request->get('mode_of_payment')) - ->setLandmark($req->request->get('landmark')) - ->setWillWait($req->request->get('flag_willing_to_wait')) - ->setReasonNotWait($reason) - ->setNotWaitingNotes($more_reason) - ->setNoTradeInReason($no_trade_in_reason); + // get customer vehicle + $cust_vehicle = $em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle')); + // TODO: check status before saving since JO might already + // have a status that needs to be retained + $this->setJobOrderObject($req, $obj, $cust_vehicle); // did they change invoice? $invoice_items = $req->request->get('invoice_items', []); @@ -521,20 +469,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface ], 422); } - // the event - $event = new JOEvent(); - $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::OPEN_EDIT) - ->setJobOrder($obj); - - error_log('open edit?'); - - if ($user != null) - { - $event->setUser($user); - } - - $em->persist($event); + $this->jo_manager->processJobOrderEvents($obj, JOEventType::OPEN_EDIT); // validated! save the entity $em->flush(); @@ -548,7 +483,6 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface } return $data; - } // dispatch job order @@ -2977,7 +2911,6 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface ->setCustomer($cust_vehicle->getCustomer()) ->setCustomerVehicle($cust_vehicle) ->setSource($req->request->get('source')) - ->setStatus(JOStatus::PENDING) ->setDeliveryInstructions($req->request->get('delivery_instructions')) ->setTier1Notes($req->request->get('tier1_notes')) ->setTier2Notes($req->request->get('tier2_notes')) @@ -2991,6 +2924,13 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface ->setNotWaitingNotes($more_reason) ->setNoTradeInReason($no_trade_in_reason); + // check if jo status is null + if ($jo->getStatus() == null) + { + // new JO + $jo->setStatus(JOStatus::PENDING); + } + // get current user $user = $this->security->getUser(); if ($user != null) diff --git a/src/Service/JobOrderManager.php b/src/Service/JobOrderManager.php index 8e9d2db7..0ee7b8fb 100644 --- a/src/Service/JobOrderManager.php +++ b/src/Service/JobOrderManager.php @@ -122,7 +122,7 @@ class JobOrderManager $em->persist($hub_assign_event); } } - // TODO: check for other JO event types + // TODO: check for other JO event types. See if all other event types have no special processing if ($jo_event_type == JOEventType::CANCEL) { // add event log for JO @@ -138,6 +138,22 @@ class JobOrderManager $em->persist($event); } + if ($jo_event_type == JOEventType::OPEN_EDIT) + { + // add event log for JO + $event = new JOEvent(); + $event->setDateHappen(new DateTime()) + ->setTypeID($jo_event_type) + ->setJobOrder($jo); + + $user = $this->security->getUser(); + // check if user is User or APIUser + if ($user instanceof User) + $event->setUser($user); + + $em->persist($event); + } + } public function removeCustomerTag(JobOrder $jo, Customer $customer, $customer_tags, $username) -- 2.43.5 From a28b7ec6d09f28d7d3284f6cc522171a2132a57f Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 21 Jul 2021 09:47:03 +0000 Subject: [PATCH 41/42] Modify setting of JO object. #591 --- .../JobOrderHandler/ResqJobOrderHandler.php | 189 +++++++----------- 1 file changed, 75 insertions(+), 114 deletions(-) diff --git a/src/Service/JobOrderHandler/ResqJobOrderHandler.php b/src/Service/JobOrderHandler/ResqJobOrderHandler.php index f569f977..4b02a402 100644 --- a/src/Service/JobOrderHandler/ResqJobOrderHandler.php +++ b/src/Service/JobOrderHandler/ResqJobOrderHandler.php @@ -353,9 +353,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $this->validateJobOrder($req, $error_array); if (empty($error_array)) { - // get customer vehicle - $cust_vehicle = $em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle')); - $this->setJobOrderObject($req, $jo, $cust_vehicle); + $this->setJobOrderObject($em, $req, $jo, JOStatus::PENDING); // call service to generate invoice $invoice_items = $req->request->get('invoice_items', []); @@ -437,11 +435,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $this->validateJobOrder($req, $error_array); if (empty($error_array)) { - // get customer vehicle - $cust_vehicle = $em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle')); - // TODO: check status before saving since JO might already - // have a status that needs to be retained - $this->setJobOrderObject($req, $obj, $cust_vehicle); + $this->setJobOrderObject($em, $req, $obj, $obj->getStatus()); // did they change invoice? $invoice_items = $req->request->get('invoice_items', []); @@ -492,7 +486,6 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $em = $this->em; $obj = $em->getRepository(JobOrder::class)->find($id); $processor = $obj->getProcessedBy(); - $user = $this->security->getUser();; // check if we're the one processing, return error otherwise if ($processor == null) @@ -516,87 +509,23 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface // $error_array['dispatch'] = 'Could not dispatch. Job Order is not pending.'; } - // check if lat and lng are provided - if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) - { - $error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.'; - } + // validate + $this->validateJobOrder($req, $error_array); // check if hub is set if (empty($req->request->get('hub'))) - { $error_array['hub'] = 'No hub selected.'; - } else { // get hub $hub = $em->getRepository(Hub::class)->find($req->request->get('hub')); - if (empty($hub)) - { $error_array['hub'] = 'Invalid hub specified.'; - } - } - - // check facilitated type - $fac_type = $req->request->get('facilitated_type'); - if (!empty($fac_type)) - { - if (!FacilitatedType::validate($fac_type)) - $fac_type = null; - } - else - $fac_type = null; - - // check facilitated by - $fac_by_id = $req->request->get('facilitated_by'); - $fac_by = null; - if (!empty($fac_by_id)) - { - $fac_by = $em->getRepository(Hub::class)->find($fac_by_id); - if (empty($fac_by)) - $fac_by = null; - } - - // check if landmark is set - if (empty($req->request->get('landmark'))) - $error_array['landmark'] = 'Landmark is required.'; - - // check if customer is not willing to wait - $will_wait = $req->request->get('flag_willing_to_wait'); - $reason = ''; - $more_reason = ''; - if ($will_wait == WillingToWaitContent::NOT_WILLING_TO_WAIT) - { - // get the reason and text - $reason = $req->request->get('no_wait_reason'); - $more_reason = $req->request->get('not_wait_notes'); } if (empty($error_array)) { - // coordinates - $point = new Point($req->request->get('coord_lng'), $req->request->get('coord_lat')); - - // set and save values - $obj->setDateSchedule(DateTime::createFromFormat("d M Y h:i A", $req->request->get('date_schedule_date') . " " . $req->request->get('date_schedule_time'))) - ->setCoordinates($point) - ->setAdvanceOrder($req->request->get('flag_advance') ?? false) - ->setServiceType($req->request->get('service_type')) - ->setWarrantyClass($req->request->get('warranty_class')) - ->setSource($req->request->get('source')) - ->setStatus(JOStatus::RIDER_ASSIGN) - ->setDeliveryInstructions($req->request->get('delivery_instructions')) - ->setTier1Notes($req->request->get('tier1_notes')) - ->setTier2Notes($req->request->get('tier2_notes')) - ->setDeliveryAddress($req->request->get('delivery_address')) - ->setFacilitatedType($fac_type) - ->setFacilitatedBy($fac_by) - ->setHub($hub) - ->setLandmark($req->request->get('landmark')) - ->setWillWait($req->request->get('flag_willing_to_wait')) - ->setReasonNotWait($reason) - ->setNotWaitingNotes($more_reason); + $this->setJobOrderObject($em, $req, $obj, JOStatus::RIDER_ASSIGN); // validate $errors = $this->validator->validate($obj); @@ -605,22 +534,17 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface foreach ($errors as $error) { $error_array[$error->getPropertyPath()] = $error->getMessage(); } - } - if (empty($error_array)) - { - // the event - $event = new JOEvent(); - $event->setDateHappen(new DateTime()) - ->setTypeID(JOEventType::HUB_ASSIGN) - ->setJobOrder($obj); - - if ($user != null) - { - $event->setUser($user); + // check if any errors were found + if (!empty($error_array)) { + // return validation failure response + return $this->json([ + 'success' => false, + 'errors' => $error_array + ], 422); } - $em->persist($event); + $this->jo_manager->processJobOrderEvents($jo, JOEventType::HUB_ASSIGN); // validated! save the entity $em->flush(); @@ -2875,8 +2799,66 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface } } - protected function setJobOrderObject(Request $req, JobOrder $jo, $cust_vehicle) - { + protected function setJobOrderObject(EntityManagerInterface $em, Request $req, JobOrder $jo, $jo_status) + { + // new job order + if ($jo_status == JOStatus::PENDING) + { + // these are fields that are only set when new job order + // get customer vehicle + $cust_vehicle = $em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle')); + + $jo->setCustomer($cust_vehicle->getCustomer()) + ->setCustomerVehicle($cust_vehicle) + ->setORName($req->request->get('or_name')) + ->setPromoDetail($req->request->get('promo_detail')); + + // get current user + $user = $this->security->getUser(); + if ($user != null) + $jo->setCreatedBy($user); + + // check if reference JO is set + if (!empty($req->request->get('ref_jo'))) { + // get reference JO + $ref_jo = $em->getRepository(JobOrder::class)->find($req->request->get('ref_jo')); + $jo->setReferenceJO($ref_jo); + } + } + + // dispatch/assign hub + if ($jo_status == JOStatus::RIDER_ASSIGN) + { + // this means JO is in dispatch/assign hub + // for dispatch, set the hub and facilitated by and facilitated type + // check facilitated type + $fac_type = $req->request->get('facilitated_type'); + if (!empty($fac_type)) + { + if (!FacilitatedType::validate($fac_type)) + $fac_type = null; + } + else + $fac_type = null; + + // check facilitated by + $fac_by_id = $req->request->get('facilitated_by'); + $fac_by = null; + if (!empty($fac_by_id)) + { + $fac_by = $em->getRepository(Hub::class)->find($fac_by_id); + if (empty($fac_by)) + $fac_by = null; + } + + // get hub + $hub = $em->getRepository(Hub::class)->find($req->request->get('hub')); + + $jo->setFacilitatedType($fac_type) + ->setFacilitatedBy($fac_by) + ->setHub($hub); + } + // check if customer is not willing to wait $will_wait = $req->request->get('flag_willing_to_wait'); $reason = ''; @@ -2908,40 +2890,19 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface ->setAdvanceOrder($req->request->get('flag_advance') ?? false) ->setServiceType($stype) ->setWarrantyClass($req->request->get('warranty_class')) - ->setCustomer($cust_vehicle->getCustomer()) - ->setCustomerVehicle($cust_vehicle) ->setSource($req->request->get('source')) ->setDeliveryInstructions($req->request->get('delivery_instructions')) ->setTier1Notes($req->request->get('tier1_notes')) ->setTier2Notes($req->request->get('tier2_notes')) ->setDeliveryAddress($req->request->get('delivery_address')) - ->setORName($req->request->get('or_name')) - ->setPromoDetail($req->request->get('promo_detail')) ->setModeOfPayment($req->request->get('mode_of_payment')) ->setLandmark($req->request->get('landmark')) ->setWillWait($req->request->get('flag_willing_to_wait')) ->setReasonNotWait($reason) ->setNotWaitingNotes($more_reason) - ->setNoTradeInReason($no_trade_in_reason); + ->setNoTradeInReason($no_trade_in_reason) + ->setStatus($jo_status); - // check if jo status is null - if ($jo->getStatus() == null) - { - // new JO - $jo->setStatus(JOStatus::PENDING); - } - - // get current user - $user = $this->security->getUser(); - if ($user != null) - $jo->setCreatedBy($user); - - // check if reference JO is set - if (!empty($req->request->get('ref_jo'))) { - // get reference JO - $ref_jo = $em->getRepository(JobOrder::class)->find($req->request->get('ref_jo')); - $jo->setReferenceJO($ref_jo); - } } public function getEditRoute($jo_id, $tier) -- 2.43.5 From f89ddd73bf1ea75eeb56165d6f5d94d03b2cc338 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 21 Jul 2021 10:12:27 +0000 Subject: [PATCH 42/42] Fix issues found during testing of dispatch. #591 --- .../JobOrderHandler/ResqJobOrderHandler.php | 115 +++++++++++------- src/Service/JobOrderManager.php | 21 +--- 2 files changed, 71 insertions(+), 65 deletions(-) diff --git a/src/Service/JobOrderHandler/ResqJobOrderHandler.php b/src/Service/JobOrderHandler/ResqJobOrderHandler.php index 4b02a402..bc18a81c 100644 --- a/src/Service/JobOrderHandler/ResqJobOrderHandler.php +++ b/src/Service/JobOrderHandler/ResqJobOrderHandler.php @@ -350,10 +350,11 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface // validate and set job order object - $this->validateJobOrder($req, $error_array); + $jo_status = JOStatus::PENDING; + $this->validateJobOrder($req, $error_array, $jo_status); if (empty($error_array)) { - $this->setJobOrderObject($em, $req, $jo, JOStatus::PENDING); + $this->setJobOrderObject($req, $jo, $jo_status); // call service to generate invoice $invoice_items = $req->request->get('invoice_items', []); @@ -432,10 +433,10 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface throw $this->createNotFoundException('The item does not exist'); // validate and set job order object - $this->validateJobOrder($req, $error_array); + $this->validateJobOrder($req, $error_array, $obj->getStatus()); if (empty($error_array)) { - $this->setJobOrderObject($em, $req, $obj, $obj->getStatus()); + $this->setJobOrderObject($req, $obj, $obj->getStatus()); // did they change invoice? $invoice_items = $req->request->get('invoice_items', []); @@ -486,6 +487,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $em = $this->em; $obj = $em->getRepository(JobOrder::class)->find($id); $processor = $obj->getProcessedBy(); + $user = $this->security->getUser(); // check if we're the one processing, return error otherwise if ($processor == null) @@ -510,7 +512,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface } // validate - $this->validateJobOrder($req, $error_array); + $jo_status = JOStatus::RIDER_ASSIGN; + $this->validateJobOrder($req, $error_array, $jo_status); // check if hub is set if (empty($req->request->get('hub'))) @@ -525,7 +528,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface if (empty($error_array)) { - $this->setJobOrderObject($em, $req, $obj, JOStatus::RIDER_ASSIGN); + $this->setJobOrderObject($req, $obj, $jo_status); // validate $errors = $this->validator->validate($obj); @@ -544,7 +547,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface ], 422); } - $this->jo_manager->processJobOrderEvents($jo, JOEventType::HUB_ASSIGN); + $this->jo_manager->processJobOrderEvents($obj, JOEventType::HUB_ASSIGN); // validated! save the entity $em->flush(); @@ -2752,61 +2755,79 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface } } - protected function validateJobOrder(Request $req, &$error_array) + protected function validateJobOrder(Request $req, &$error_array, $jo_status) { - // check if lat and lng are provided - if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) { - $error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.'; - } + // new job order + if ($jo_status == JOStatus::PENDING) + { + // check if service is battery sales + $stype = $req->request->get('service_type'); + if ($stype == ServiceType::BATTERY_REPLACEMENT_NEW) + { + // check if trade in + $is_trade_in = $req->request->get('invoice_trade_in_type'); + if (empty($is_trade_in)) + { + if (empty($req->request->get('no_trade_in_reason'))) + $error_array['no_trade_in_reason'] = 'No trade in reason required.'; + } + } + // check if customer vehicle is set + if (empty($req->request->get('customer_vehicle'))) + $error_array['customer_vehicle'] = 'No vehicle selected.'; + else + { + // get customer vehicle + $cust_vehicle = $this->em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle')); - // check if customer vehicle is set - if (empty($req->request->get('customer_vehicle'))) { - $error_array['customer_vehicle'] = 'No vehicle selected.'; - } else { - // get customer vehicle - $cust_vehicle = $this->em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle')); + if (empty($cust_vehicle)) + $error_array['customer_vehicle'] = 'Invalid vehicle specified.'; + } + // check if reference JO is set and validate + if (!empty($req->request->get('ref_jo'))) + { + // get reference JO + $ref_jo = $em->getRepository(JobOrder::class)->find($req->request->get('ref_jo')); - if (empty($cust_vehicle)) { - $error_array['customer_vehicle'] = 'Invalid vehicle specified.'; + if (empty($ref_jo)) + $error_array['ref_jo'] = 'Invalid reference job order specified.'; } } + // assign hub/dispatch job order + if ($jo_status == JOStatus::RIDER_ASSIGN) + { + // check if hub is set + if (empty($req->request->get('hub'))) + $error_array['hub'] = 'No hub selected.'; + else + { + // get hub + $hub = $this->em->getRepository(Hub::class)->find($req->request->get('hub')); + + if (empty($hub)) + $error_array['hub'] = 'Invalid hub specified.'; + } + } + + // check if lat and lng are provided + if (empty($req->request->get('coord_lng')) || empty($req->request->get('coord_lat'))) + $error_array['coordinates'] = 'No map coordinates provided. Please click on a location on the map.'; + // check if landmark is set if (empty($req->request->get('landmark'))) $error_array['landmark'] = 'Landmark is required.'; - // check if service is battery sales - $stype = $req->request->get('service_type'); - if ($stype == ServiceType::BATTERY_REPLACEMENT_NEW) - { - // check if trade in - $is_trade_in = $req->request->get('invoice_trade_in_type'); - if (empty($is_trade_in)) - { - if (empty($req->request->get('no_trade_in_reason'))) - $error_array['no_trade_in_reason'] = 'No trade in reason required.'; - } - } - - // check if reference JO is set and validate - if (!empty($req->request->get('ref_jo'))) { - // get reference JO - $ref_jo = $em->getRepository(JobOrder::class)->find($req->request->get('ref_jo')); - - if (empty($ref_jo)) { - $error_array['ref_jo'] = 'Invalid reference job order specified.'; - } - } } - protected function setJobOrderObject(EntityManagerInterface $em, Request $req, JobOrder $jo, $jo_status) + protected function setJobOrderObject(Request $req, JobOrder $jo, $jo_status) { // new job order if ($jo_status == JOStatus::PENDING) { // these are fields that are only set when new job order // get customer vehicle - $cust_vehicle = $em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle')); + $cust_vehicle = $this->em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle')); $jo->setCustomer($cust_vehicle->getCustomer()) ->setCustomerVehicle($cust_vehicle) @@ -2821,7 +2842,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface // check if reference JO is set if (!empty($req->request->get('ref_jo'))) { // get reference JO - $ref_jo = $em->getRepository(JobOrder::class)->find($req->request->get('ref_jo')); + $ref_jo = $this->em->getRepository(JobOrder::class)->find($req->request->get('ref_jo')); $jo->setReferenceJO($ref_jo); } } @@ -2846,13 +2867,13 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $fac_by = null; if (!empty($fac_by_id)) { - $fac_by = $em->getRepository(Hub::class)->find($fac_by_id); + $fac_by = $this->em->getRepository(Hub::class)->find($fac_by_id); if (empty($fac_by)) $fac_by = null; } // get hub - $hub = $em->getRepository(Hub::class)->find($req->request->get('hub')); + $hub = $this->em->getRepository(Hub::class)->find($req->request->get('hub')); $jo->setFacilitatedType($fac_type) ->setFacilitatedBy($fac_by) diff --git a/src/Service/JobOrderManager.php b/src/Service/JobOrderManager.php index 0ee7b8fb..a58a5581 100644 --- a/src/Service/JobOrderManager.php +++ b/src/Service/JobOrderManager.php @@ -122,9 +122,10 @@ class JobOrderManager $em->persist($hub_assign_event); } } - // TODO: check for other JO event types. See if all other event types have no special processing - if ($jo_event_type == JOEventType::CANCEL) + else { + // TODO: check for other JO event types. See if all other event types have no special processing + // cancel, edit, dispatch are the same // add event log for JO $event = new JOEvent(); $event->setDateHappen(new DateTime()) @@ -138,22 +139,6 @@ class JobOrderManager $em->persist($event); } - if ($jo_event_type == JOEventType::OPEN_EDIT) - { - // add event log for JO - $event = new JOEvent(); - $event->setDateHappen(new DateTime()) - ->setTypeID($jo_event_type) - ->setJobOrder($jo); - - $user = $this->security->getUser(); - // check if user is User or APIUser - if ($user instanceof User) - $event->setUser($user); - - $em->persist($event); - } - } public function removeCustomerTag(JobOrder $jo, Customer $customer, $customer_tags, $username) -- 2.43.5