From f0b562b0cb38c5e4ca4f9ad8676663f35beda36d Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 24 Jun 2021 09:35:51 +0000 Subject: [PATCH] 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; + } +}