From 60f401e26e5a79c2bd171f9a466df30c8f64bc65 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Wed, 15 Jun 2022 08:22:36 +0000 Subject: [PATCH 01/20] Add permissions for another third party api. Copied the methods from APIController into CAPI third party conrtrollers. #686 --- config/api_acl.yaml | 50 + .../CAPI/ResqAPI/BatteryController.php | 85 + .../CAPI/ResqAPI/JobOrderController.php | 1637 +++++++++++++++++ .../CAPI/ResqAPI/PromoController.php | 40 + .../CAPI/ResqAPI/ServiceController.php | 79 + .../CAPI/ResqAPI/VehicleController.php | 107 ++ 6 files changed, 1998 insertions(+) create mode 100644 src/Controller/CAPI/ResqAPI/BatteryController.php create mode 100644 src/Controller/CAPI/ResqAPI/JobOrderController.php create mode 100644 src/Controller/CAPI/ResqAPI/PromoController.php create mode 100644 src/Controller/CAPI/ResqAPI/ServiceController.php create mode 100644 src/Controller/CAPI/ResqAPI/VehicleController.php diff --git a/config/api_acl.yaml b/config/api_acl.yaml index ae1a9bfb..9182674e 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -69,3 +69,53 @@ access_keys: acls: - id: dealer.list label: List + + - id: tapi_vmanufacturer + label: Third Party Vehicle Manufacturer Access + acls: + - id: tapi_vmanufacturer.list + label: List Third Party Vehicle Manufacturers + - id: tapi_vehicle + label: Third Party Vehicle Make Access + acls: + - id: tapi_vehicle.list + label: List Third Party Vehicles + - id: tapi_promo + labels: Third Party Promo Access + acls: + - id: tapi_promo.list + label: List Third Party Promos + - id: tapi_battery + labels: Third Party Battery Access + acls: + - id: tapi_battery_compatible.list + label: List Third Party Compatible Batteries + - id: tapi_jo + labels: Third Party Job Order Access + acls: + - id: tapi_jo.request + label: Third Party Request Job Order + - id: tapi_jo.get.estimate + label: Third Party Get Estimate + - id: tapi_jo.get.ongoing + label: Third Party Get Ongoing Job Order + - id: tapi_jo.cancel + label: Third Party Cancel Job Order + - id: tapi_jo.get.history + label: Third Party Get Job Order History + - id: tapi_jo.get.invoice + label: Third Party Get Job Order Invoice + - id: tapi_jo.location.support + label: Third Party Check Location Support + - id: tapi_jo.nearest_hub.get + label: Third Party Get Nearest Hub and Slots + - id: tapi_jo.schedule_option.status + label: Third Party Schedule Option Status + - id: tapi_jo.get.info + label: Third Party Get Job Order Info + - id: tapi_service + labels: Third Party Service Access + acls: + - id: tapi_service.list + label: List Third Party Services + diff --git a/src/Controller/CAPI/ResqAPI/BatteryController.php b/src/Controller/CAPI/ResqAPI/BatteryController.php new file mode 100644 index 00000000..7c294e2c --- /dev/null +++ b/src/Controller/CAPI/ResqAPI/BatteryController.php @@ -0,0 +1,85 @@ +acl_gen = $acl_gen; + } + + public function getCompatibleBatteries(Request $req, $vid, EntityManagerInterface $em) + { + $this->denyAccessUnlessGranted('tapi_battery_compatible.list', null, 'No access.'); + + // 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(); + } +} diff --git a/src/Controller/CAPI/ResqAPI/JobOrderController.php b/src/Controller/CAPI/ResqAPI/JobOrderController.php new file mode 100644 index 00000000..b602c970 --- /dev/null +++ b/src/Controller/CAPI/ResqAPI/JobOrderController.php @@ -0,0 +1,1637 @@ +acl_gen = $acl_gen; + } + + // TODO: break this monolithic method down + public function requestJobOrder(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, + HubFilteringGeoChecker $hub_geofence, EntityManagerInterface $em) + { + $this->denyAccessUnlessGranted('tapi_jo.request', null, 'No access.'); + + // 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', ''); + + // landmark + $landmark = $req->request->get('landmark', ' '); + + // longitude and latitude + $long = $req->request->get('long'); + $lat = $req->request->get('lat'); + + // NOTE: had to move this up so we can check for promo before geofence + // customer + // TODO: need to modify how to get customer + $cust = $this->session->getCustomer(); + if ($cust == null) + { + $res->setError(true) + ->setErrorMessage('No customer information found'); + return $res->getReturnResponse(); + } + + $is_covered = false; + // check if customer still has promo + if (($cust->getCustomerTag('TAG_CAR_CLUB_OFFICER_PROMO')) || + ($cust->getCustomerTag('TAG_CAR_CLUB_MEMBER_PROMO'))) + { + // if has customer tag, customer has not availed of promo + $is_covered = true; + } + else + { + // 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'); + // check if hub_id is -1 which means user clicked Book Now before 5 PM + // but confirmed the order after 5 PM + if ($hub_id == -1) + { + $res->setError(true) + ->setErrorMessage('Book Now no longer available.'); + return $res->getReturnResponse(); + } + if (strlen($hub_id) > 0) + $hub = $em->getRepository(Hub::class)->find($hub_id); + + $schedule_date = $req->request->get('date_schedule'); + $slot_id = $req->request->get('slot_id'); + + // process the jo date schedule + $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')); + } + } + + $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; + // $flag_advance_order = $advance_order ? true : false; + + $jo = new JobOrder(); + $jo->setSource(TransactionOrigin::MOBILE_APP) + ->setStatus(JOStatus::PENDING) + ->setDeliveryInstructions('') + ->setTier1Notes('') + ->setTier2Notes('') + ->setDeliveryAddress($address) + ->setTradeInType($trade_in) + ->setDeliveryInstructions($instructions) + // TODO: error check for valid mode of payment + ->setModeOfPayment($req->request->get('mode_of_payment')) + ->setAdvanceOrder($flag_advance_order) + ->setStatusAutoAssign(AutoAssignStatus::NOT_ASSIGNED) + ->setLandmark($landmark); + + $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; + + 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) + { + // TODO: need to factor out the setting of HubCriteria fields + $hub_criteria = new HubCriteria(); + $hub_criteria->setPoint($jo->getCoordinates()); + + // get distance limit for mobile from env + // get value of hub_filter_enable from env + $dotenv = new Dotenv(); + $dotenv->loadEnv(__DIR__.'/../../.env'); + $limit_distance = $_ENV['CUST_DISTANCE_LIMIT']; + $hub_filter_enabled = $_ENV['HUB_FILTER_ENABLE']; + + // set distance limit + $hub_criteria->setLimitDistance($limit_distance); + + // check if hub filter is enabled. If not, use default values + // for the rest of the HubCriteria fields + if ($hub_filter_enabled == 'true') + { + // error_log('hub filter is enabled'); + // check if customer location is in hub filter area + 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); + } + } + + // check if batt is null + if ($batt != null) + { + // add battery to items + $sku = $batt->getSAPCode(); + if (!empty($sku)) + $hub_criteria->addItem($batt->getSAPCode(), 1); + } + + // get customer id. No JO id at this point + $customer_id = $cust->getID(); + + $hub_criteria->setCustomerId($customer_id); + + // 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) + { + // check if hub can be auto assigned + // if not, move on to the next hub in the list + if (($nearest_hub['hub']->isHubAutoAssign())) + { + // check if hub has riders that can be auto assigned + // if not, move on to the next hub + if (($nearest_hub['hub']->isRiderAutoAssign())) + { + $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); + $jo->setDeliveryStatus(DeliveryStatus::RIDER_ASSIGN); + + // set date_assigned for job order + $jo->setDateAssign(new DateTime()); + + $assigned_rider->setAvailable(false); + + // set rider's current job order + $assigned_rider->setCurrentJobOrder($jo); + + // update redis hub_jo_count for hub + $hub_dist->incrementJoCountForHub($nearest_hub['hub']); + + // break out of loop + break; + } + else + { + // we just create the JO and let admin panel handle the hub assignment + // log hub into hub_filter_log + $hub_filter_logger->logFilteredHub($nearest_hub['hub'], 'no_available_rider', null, $cust->getID()); + // continue to go through list to find hub with an available rider + } + } + else + { + // TODO: log hub as cannot be auto rider assigned somewhere + // assign hub + // error_log('Rider cannot be auto assigned ' . $nearest_hub['hub']->getID()); + $jo->setHub($nearest_hub['hub']); + $jo->setStatus(JOStatus::RIDER_ASSIGN); + $jo->setStatusAutoAssign(AutoAssignStatus::HUB_ASSIGNED); + + // update redis hub_jo_count for hub + $hub_dist->incrementJoCountForHub($nearest_hub['hub']); + + break; + } + } + else + { + // TODO: log hub as cannot be auto assigned somewhere + // move to next hub + error_log('Hub cannot be auto-assigned ' . $nearest_hub['hub']->getID()); + continue; + } + } + } + } + else + { + $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' => (float) $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(); + } + + public function getEstimate(Request $req, InvoiceGeneratorInterface $ic, EntityManagerInterface $em) + { + $this->denyAccessUnlessGranted('tapi_jo.get.estimate', null, 'No access.'); + + // 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 + // TODO: needs to be modified to get 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; + + $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; + + // set data + $res->setData($data); + + return $res->getReturnResponse(); + } + + public function getJOInvoice(Request $req, EntityManagerInterface $em) + { + $this->denyAccessUnlessGranted('tapi_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(); + } + + // get customer + // TODO: modify to 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 cancelJobOrder(Request $req, MQTTClient $mclient, EntityManagerInterface $em) + { + $this->denyAccessUnlessGranted('tapi_jo.cancel', null, 'No access.'); + + $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 + // TODO: modify to 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(); + + // TODO: do we need this? + // send mobile app event + $payload = [ + 'event' => 'cancelled', + 'reason' => $cancel_reason, + 'jo_id' => $jo->getID(), + ]; + $mclient->sendRiderEvent($jo, $payload); + + + $res->setData([]); + + return $res->getReturnResponse(); + } + + // we can't use param converter for now because we want to output the proper 404 + public function getJobOrderInfo($id, Request $req, EntityManagerInterface $em, RiderTracker $rt) + { + $this->denyAccessUnlessGranted('tapi_jo.get.info', null, 'No access.'); + + // check required parameters and api key + $res = $this->checkParamsAndKey($req, $em, []); + if ($res->isError()) + return $res->getReturnResponse(); + + // get customer + // TODO: modify to get customer + $cust = $this->session->getCustomer(); + if ($cust == null) + { + $res->setError(true) + ->setErrorMessage('No customer information found'); + return $res->getReturnResponse(); + } + + // get job order data + $jo = $em->getRepository(JobOrder::class)->find($id); + if ($jo == null) + { + $res->setError(true) + ->setErrorMessage('No job order information found'); + return $res->getReturnResponse(); + } + + // check if job order belongs to customer / user + if ($cust->getID() != $jo->getCustomer()->getID()) + { + $res->setError(true) + ->setErrorMessage('No job order information found'); + return $res->getReturnResponse(); + } + + // put into job order data array + $jo_data = $this->generateJobOrderData($req, $jo, $rt); + + $data = [ + 'job_order' => $jo_data + ]; + $res->setData($data); + + return $res->getReturnResponse(); + } + + public function getJOHistory(Request $req, EntityManagerInterface $em) + { + $this->denyAccessUnlessGranted('tapi_jo.get.history', null, 'No access.'); + + $res = $this->checkParamsAndKey($req, $em, []); + if ($res->isError()) + return $res->getReturnResponse(); + + // get customer + // TODO: modify to find 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 = []; + // get the fulfilled and cancelled job orders, since ongoing jos are not yet part of history + $jos = $em->getRepository(JobOrder::class)->findBy([ + 'customer' => $cust, + 'status' => [JOStatus::CANCELLED, JOStatus::FULFILLED] + ], ['date_schedule' => 'DESC']); + foreach ($jos as $jo) + { + // NOTE: use generateJobOrderData method, maybe? + $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(), $em); + + $jo_data['customer_vehicle'] = [ + 'id' => $cv->getID(), + 'plate_number' => $cv->getPlateNumber(), + 'warranty' => $warranty, + ]; + + // rider + $rider = $jo->getRider(); + + // check if jo has rider rating set to true + $has_rider_rating = $jo->hasRiderRating(); + $rating = 0; + $comment = ''; + if ($rider != null) + { + $jo_data['rider'] = $rider->getFullName(); + + // find the rider rating if any + if ($has_rider_rating) + { + $jo_rating = $jo->getRating(); + if ($jo_rating != null) + { + $rating = $jo_rating->getRating(); + + // get comment + $comment = $jo_rating->getComment(); + } + } + } + + // rider rating for jo + $jo_data['has_rider_rating'] = $has_rider_rating; + $jo_data['rider_rating'] = $rating; + $jo_data['comment'] = $comment; + + // invoice items + $items = []; + $jo_items = $jo->getInvoice()->getItems(); + 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(); + } + + public function locationSupport(Request $req, GeofenceTracker $geo, EntityManagerInterface $em) + { + $this->denyAccessUnlessGranted('tapi_jo.location.support', null, 'No access.'); + + $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'); + + // NOTE: had to add this for promo tag + // TODO: modify to find customer if we still need this + $cust = $this->session->getCustomer(); + if ($cust == null) + { + $res->setError(true) + ->setErrorMessage('No customer information found'); + return $res->getReturnResponse(); + } + + $is_covered = false; + // check if customer still has promo + if (($cust->getCustomerTag('TAG_CAR_CLUB_OFFICER_PROMO')) || + ($cust->getCustomerTag('TAG_CAR_CLUB_MEMBER_PROMO'))) + { + // if has customer tag, customer has not availed of promo + $is_covered = true; + } + else + { + // geofence + $is_covered = $geo->isCovered($long, $lat); + } + + $data = [ + 'longitude' => $long, + 'latitude' => $lat, + 'supported' => $is_covered, + ]; + $res->setData($data); + + // check if is_covered is false. If so, we need to set the error part in the response + if (!$is_covered) + { + $res->setError(true) + ->setErrorMessage('Oops! Our service is limited to some areas in Metro Manila, Laguna, and Baguio only. We will update you as soon as we are able to cover your area'); + } + + return $res->getReturnResponse(); + } + + // TODO: should we change to the HubSelector? + public function getNearestHubAndSlots(Request $req, EntityManagerInterface $em, + MapTools $map_tools) + { + $this->denyAccessUnlessGranted('tapi_jo.nearest_hub.get', null, 'No access.'); + + $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')); + + // add checking if customer has a pre-registered hub + // TODO: modify how we get customer + $cust = $this->session->getCustomer(); + if ($cust == null) + { + $res->setError(true) + ->setErrorMessage('No customer information found'); + return $res->getReturnResponse(); + } + + // check if customer has customer tag promo + // TODO: do we still need this? + if (($cust->getCustomerTag('TAG_CAR_CLUB_OFFICER_PROMO')) || + ($cust->getCustomerTag('TAG_CAR_CLUB_MEMBER_PROMO'))) + { + // if has customer tag, customer has not availed of promo, get the hub where customer is pre-registered + $car_club_cust_hub = $cust->getCarClubCustomerHub(); + if ($car_club_cust_hub != null) + { + // need to get the rider slots for the pre-registered hub + $hub = $car_club_cust_hub->getHub(); + $nearest_hub_slots = $this->findAdvanceNearestHubAndSlots($coordinates, $em, $map_tools, $hub); + } + else + { + $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. Please expect a call from us and we will assist you with your request. Thank you and stay safe!'); + return $res->getReturnResponse(); + } + } + } + else + { + $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. Please expect a call from us 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) + { + $this->denyAccessUnlessGranted('tapi_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(); + + $schedule_choice = true; + + // 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'); + + // commenting out the time check since we can now book 24/7 + // this will get uncommented out if and when ECQ will kick in + //if (($hour < 8) || ($hour > 16)) + // $schedule_choice = false; + + // add checking if customer has a pre-registered hub + // TODO: modify how we get customer + $cust = $this->session->getCustomer(); + if ($cust == null) + { + $res->setError(true) + ->setErrorMessage('No customer information found'); + return $res->getReturnResponse(); + } + // check if customer has customer tag promo + if (($cust->getCustomerTag('TAG_CAR_CLUB_OFFICER_PROMO')) || + ($cust->getCustomerTag('TAG_CAR_CLUB_MEMBER_PROMO'))) + { + // if has customer tag, customer has not availed of promo, get the hub where customer is pre-registered + $car_club_hub = $cust->getCarClubCustomerHub(); + if ($car_club_hub != null) + { + $schedule_choice = false; + } + } + + // schedule_choice will always be true aka customer can opt to + // Book Now or Schedule Order EXCEPT if customer has customer tag promo + // or ECQ comes back + $data = [ + 'display_schedule_choice' => $schedule_choice, + ]; + $res->setData($data); + + return $res->getReturnResponse(); + } + + protected function generateJobOrderData($req, $jo, $rt) + { + $status = $jo->getStatus(); + + $dest = $jo->getCoordinates(); + + $jo_data = [ + 'id' => $jo->getID(), + 'date_create' => $jo->getDateCreate()->format('M d, Y'), + 'service_type' => $jo->getServiceType(), + 'destination' => [ + 'long' => $dest->getLongitude(), + 'lat' => $dest->getLatitude(), + ], + 'delivery_address' => $jo->getDeliveryAddress(), + 'delivery_instructions' => $jo->getDeliveryInstructions(), + 'jo_status' => $status, + 'status' => $this->generateAPIRiderStatus($status), + ]; + + // customer vehicle and warranty + $cv = $jo->getCustomerVehicle(); + + // get latest warranty using plate number + $warranty = $this->findWarranty($cv->getPlateNumber(), $em); + + $jo_data['customer_vehicle'] = [ + 'id' => $cv->getID(), + 'plate_number' => $cv->getPlateNumber(), + 'warranty' => $warranty, + ]; + + // customer information + $customer = $jo->getCustomer(); + $jo_data['customer'] = [ + 'first_name' => $customer->getFirstName(), + 'last_name' => $customer->getLastName(), + 'mobile_number' => $customer->getPhoneMobile(), + ]; + + // rider + $rider = $jo->getRider(); + if ($rider != null) + { + // default image url + $url_prefix = $req->getSchemeAndHttpHost(); + $image_url = $url_prefix . '/assets/images/user.gif'; + if ($rider->getImageFile() != null) + $image_url = $url_prefix . '/uploads/' . $rider->getImageFile(); + + $coord = $rt->getRiderLocation($rider->getID()); + + $jo_data['rider'] = [ + 'id' => $rider->getID(), + 'name' => $rider->getFullName(), + 'plate_num' => $rider->getPlateNumber(), + 'contact_num' => $rider->getContactNumber(), + 'image_url' => $image_url, + 'location' => [ + 'long' => $coord->getLongitude(), + 'lat' => $coord->getLatitude() + ] + ]; + } + else + { + $jo_data['rider'] = null; + } + + // invoice items + $items = []; + $jo_items = $jo->getInvoice()->getItems(); + foreach ($jo_items as $item) + { + $items[] = [ + 'id' => $item->getID(), + 'title' => $item->getTitle(), + 'qty' => $item->getQuantity(), + 'price' => $item->getPrice(), + ]; + } + + $jo_data['items'] = $items; + + + // dates depending on status + switch ($status) + { + case JOStatus::FULFILLED: + if ($jo->getDateFulfill() == null) + $jo_data['date_fulfilled'] = ''; + else + $jo_data['date_fulfilled'] = $jo->getDateFulfill()->format('M d, Y'); + break; + case JOStatus::CANCELLED: + $date_cancel = $jo->getDateCancel(); + if ($date_cancel == null) + $date_cancel = new DateTime(); + $jo_data['date_cancelled'] = $date_cancel->format('M d, Y'); + break; + } + + return $jo_data; + } + + protected function findWarranty($plate_number, EntityManagerInterface $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 findAdvanceNearestHubAndSlots(Point $coordinates, EntityManagerInterface $em, MapTools $map_tools, $hub=null) + { + $hub_data = []; + + if ($hub != null) + { + // get the slots of hub + $hub_slots = $this->getHubRiderSlots($hub, $em); + + $slots = $hub_slots['slot_data']; + + $hub_data = [ + 'hub' => $hub, + 'slots' => $slots, + ]; + return $hub_data; + } + + // get the nearest 10 hubs + $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; + $hub_slots = []; + $slot_found = false; + // find the nearest hub + if (!empty($nearest_hubs_with_distance)) + { + // get slots of nearest hub right after getting nearest hub. + // then check if hub has available slots. If not, get next nearest hub. + foreach ($nearest_hubs_with_distance as $nhd) + { + if (empty($nearest)) + { + // get the slots for the hub to check if hub is available for assignment + $hub_slots = $this->getHubRiderSlots($nhd['hub'], $em); + + $flag_hub_available = $hub_slots['flag_hub_available']; + if ($flag_hub_available == true) + { + $nearest = $nhd; + } + } + else + { + if ($nhd['distance'] < $nearest['distance']) + { + // get the slots for nearest which is nhd right now + $hub_slots = $this->getHubRiderSlots($nhd['hub'], $em); + + $flag_hub_available = $hub_slots['flag_hub_available']; + + // if hub is available, set hub to nearest + if ($flag_hub_available == true) + { + $nearest = $nhd; + } + } + } + } + } + + if ($nearest != null) + { + // set hub data to what is in nearest + $hub_data = [ + 'hub' => $nearest['hub'], + 'slots' => $hub_slots['slot_data'], + ]; + } + + 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); + + // error_log(print_r($hub_slots, true)); + + return $hub_slots; + } + + 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; + } + + 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; + } + + protected function getBatteryImageURL($req, $batt) + { + // 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() . $this->generateUrl('static_battery_image') . '/' . $filename; + + return $file_path; + } +} + diff --git a/src/Controller/CAPI/ResqAPI/PromoController.php b/src/Controller/CAPI/ResqAPI/PromoController.php new file mode 100644 index 00000000..87e214d0 --- /dev/null +++ b/src/Controller/CAPI/ResqAPI/PromoController.php @@ -0,0 +1,40 @@ +acl_gen = $acl_gen; + } + + public function listPromos(Request $req, EntityManagerInterface $em) + { + $this->denyAccessUnlessGranted('tapi_promo.list', null, 'No access.'); + + // check required parameters and api key + $required_params = []; + $res = $this->checkParamsAndKey($req, $em, $required_params); + if ($res->isError()) + return $res->getReturnResponse(); + + return $res->getReturnResponse(); + } + +} diff --git a/src/Controller/CAPI/ResqAPI/ServiceController.php b/src/Controller/CAPI/ResqAPI/ServiceController.php new file mode 100644 index 00000000..73b853c8 --- /dev/null +++ b/src/Controller/CAPI/ResqAPI/ServiceController.php @@ -0,0 +1,79 @@ +acl_gen = $acl_gen; + } + + public function listServices(Request $req, EntityManagerInterface $em) + { + $this->denyAccessUnlessGranted('tapi_service.list', null, 'No access.'); + + $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(); + } +} diff --git a/src/Controller/CAPI/ResqAPI/VehicleController.php b/src/Controller/CAPI/ResqAPI/VehicleController.php new file mode 100644 index 00000000..e85a45ad --- /dev/null +++ b/src/Controller/CAPI/ResqAPI/VehicleController.php @@ -0,0 +1,107 @@ +acl_gen = $acl_gen; + } + + public function listVehicleManufacturers(Request $req, EntityManagerInterface $em) + { + $this->denyAccessUnlessGranted('tapi_vmanufacturer.list', null, 'No access.'); + + // 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) + { + $this->denyAccessUnlessGranted('tapi_vehicle.list', null, 'No access.'); + + // 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'] + ); + + $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(); + } +} From 44b9679a2e97c6a3c9e73d5cf51071a4f8e7be0d Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 16 Jun 2022 04:26:27 +0000 Subject: [PATCH 02/20] Move third party api controllers to a more descriptive directory. #686 --- .../ResqAPI => TAPI}/BatteryController.php | 2 +- .../ResqAPI => TAPI}/JobOrderController.php | 32 +++++++++++++++---- .../ResqAPI => TAPI}/PromoController.php | 2 +- .../ResqAPI => TAPI}/ServiceController.php | 2 +- .../ResqAPI => TAPI}/VehicleController.php | 2 +- 5 files changed, 30 insertions(+), 10 deletions(-) rename src/Controller/{CAPI/ResqAPI => TAPI}/BatteryController.php (98%) rename src/Controller/{CAPI/ResqAPI => TAPI}/JobOrderController.php (98%) rename src/Controller/{CAPI/ResqAPI => TAPI}/PromoController.php (96%) rename src/Controller/{CAPI/ResqAPI => TAPI}/ServiceController.php (98%) rename src/Controller/{CAPI/ResqAPI => TAPI}/VehicleController.php (98%) diff --git a/src/Controller/CAPI/ResqAPI/BatteryController.php b/src/Controller/TAPI/BatteryController.php similarity index 98% rename from src/Controller/CAPI/ResqAPI/BatteryController.php rename to src/Controller/TAPI/BatteryController.php index 7c294e2c..5423153b 100644 --- a/src/Controller/CAPI/ResqAPI/BatteryController.php +++ b/src/Controller/TAPI/BatteryController.php @@ -1,6 +1,6 @@ checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res->getReturnResponse(); + // get data from request + $data = $this->getJobOrderRequestInfo($req); + + // process customer and vehicle information + $this->processCustomerAndVehicleInformation(); + // trade in type $trade_in = $req->request->get('trade_in'); @@ -1633,5 +1644,14 @@ class JobOrderController extends APIController return $file_path; } + + protected function getJobOrderRequestInfo(Request $req) + { + + return $data; + } + + // TODO: add function to clean plate number + // TODO: add function to normalize strings (lowercase them since the types are lowercase) } diff --git a/src/Controller/CAPI/ResqAPI/PromoController.php b/src/Controller/TAPI/PromoController.php similarity index 96% rename from src/Controller/CAPI/ResqAPI/PromoController.php rename to src/Controller/TAPI/PromoController.php index 87e214d0..9b21a429 100644 --- a/src/Controller/CAPI/ResqAPI/PromoController.php +++ b/src/Controller/TAPI/PromoController.php @@ -1,6 +1,6 @@ Date: Fri, 17 Jun 2022 08:47:55 +0000 Subject: [PATCH 03/20] Start processing of request data. #686 --- src/Controller/TAPI/JobOrderController.php | 348 +++++++++++++-------- 1 file changed, 214 insertions(+), 134 deletions(-) diff --git a/src/Controller/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index 7519889a..55f65d46 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -92,51 +92,15 @@ class JobOrderController extends APIController return $res->getReturnResponse(); // get data from request - $data = $this->getJobOrderRequestInfo($req); + $data = []; + $data = $this->getJobOrderRequestInfo($req, $data); // process customer and vehicle information - $this->processCustomerAndVehicleInformation(); - - // 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', ''); - - // landmark - $landmark = $req->request->get('landmark', ' '); - - // longitude and latitude - $long = $req->request->get('long'); - $lat = $req->request->get('lat'); - - // NOTE: had to move this up so we can check for promo before geofence - // customer - // TODO: need to modify how to get customer - $cust = $this->session->getCustomer(); - if ($cust == null) - { - $res->setError(true) - ->setErrorMessage('No customer information found'); - return $res->getReturnResponse(); - } + $this->processCustomerAndVehicleInformation($data, $em); $is_covered = false; - // check if customer still has promo - if (($cust->getCustomerTag('TAG_CAR_CLUB_OFFICER_PROMO')) || - ($cust->getCustomerTag('TAG_CAR_CLUB_MEMBER_PROMO'))) - { - // if has customer tag, customer has not availed of promo - $is_covered = true; - } - else - { - // geofence - $is_covered = $geo->isCovered($long, $lat); - } + // geofence + $is_covered = $geo->isCovered($data['long'], $data['lat']); if (!$is_covered) { @@ -146,43 +110,6 @@ class JobOrderController extends APIController return $res->getReturnResponse(); } - $hub = null; - $hub_id = $req->request->get('hub_id'); - // check if hub_id is -1 which means user clicked Book Now before 5 PM - // but confirmed the order after 5 PM - if ($hub_id == -1) - { - $res->setError(true) - ->setErrorMessage('Book Now no longer available.'); - return $res->getReturnResponse(); - } - if (strlen($hub_id) > 0) - $hub = $em->getRepository(Hub::class)->find($hub_id); - - $schedule_date = $req->request->get('date_schedule'); - $slot_id = $req->request->get('slot_id'); - - // process the jo date schedule - $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')); - } - } - - $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; - // $flag_advance_order = $advance_order ? true : false; - $jo = new JobOrder(); $jo->setSource(TransactionOrigin::MOBILE_APP) ->setStatus(JOStatus::PENDING) @@ -193,33 +120,13 @@ class JobOrderController extends APIController ->setTradeInType($trade_in) ->setDeliveryInstructions($instructions) // TODO: error check for valid mode of payment - ->setModeOfPayment($req->request->get('mode_of_payment')) - ->setAdvanceOrder($flag_advance_order) + ->setModeOfPayment($data['payment_mode']) + ->setAdvanceOrder($data['is_advance_order']) ->setStatusAutoAssign(AutoAssignStatus::NOT_ASSIGNED) ->setLandmark($landmark); $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); @@ -228,21 +135,10 @@ class JobOrderController extends APIController $icrit = new InvoiceCriteria(); $icrit->setServiceType($stype); + // TODO add promo to criteria if any // 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); - } + // put in criteria + $icrit->addPromo($promo); // check customer vehicle $cv = $em->getRepository(CustomerVehicle::class)->find($req->request->get('cv_id')); @@ -263,21 +159,6 @@ class JobOrderController extends APIController 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; - switch ($trade_in) { case TradeInType::MOTOLITE: @@ -1645,13 +1526,212 @@ class JobOrderController extends APIController return $file_path; } - protected function getJobOrderRequestInfo(Request $req) + protected function getJobOrderRequestInfo(Request $req, EntityManagerInterface $em, &$data) { - - return $data; + $r = $req->request; + + // trade-in type + $trade_in_type = $this->cleanText($r->get('trade_in_type')); + if (!TradeInType::validate($trade_in_type)) + { + $message = 'Invalid trade in type'; + return $message; + } + + // address + $address = $r->get('delivery_address', 'Set by third party API'); + + // instructions + $instructions = $r->get('delivery_instructions', ''); + + // landmark + $landmark = $r->get('landmark', ' '); + + // longitude and latitude + $long = $r->get('longitude'); + $lat = $r->get('latitude'); + + // validate service type + $stype = $this->cleanText($r->get('service_type')); + if (!ServiceType::validate($stype)) + { + $message = 'Invalid service type'; + return $message; + } + + // get mode of payment + // TODO: do we need to validate this? + $payment_mode = $this->clean($r->get('mode_of_payment')); + if (!ModeOfPayment::validate($payment_mode)) + { + $message = 'Invalid mode of payment'; + return $message; + } + + $advance_order = $r->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; + + $hub = null; + $hub_id = $r->get('hub_id'); + if (strlen($hub_id) > 0) + $hub = $em->getRepository(Hub::class)->find($hub_id); + + $schedule_date = $r->get('date_schedule'); + $slot_id = $r->get('slot_id'); + + // process the jo date schedule + $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')); + } + } + + // check promo + $promo = null; + $promo_id = $r->get('promo_id'); + if (!empty($promo_id)) + { + $promo = $em->getRepository(Promo::class)->find($promo_id); + if ($promo == null) + { + $message = 'Invalid promo id'; + return $message; + } + } + + // check battery + $batt = null; + $batt_id = $req->request->get('batt_id'); + if ($batt_id != null) + { + $batt = $em->getRepository(Battery::class)->find($batt_id); + if ($batt == null) + { + $message = 'Invalid battery id'; + return $message; + } + } + + // get customer and vehicle info + $fname = $r->get('first_name', ''); + $lname = $r->get('last_name', ''); + $mobile = $r->get('mobile_number', ''); + + // validate mobile number + $clean_mobile = $this->cleanPhoneNumber($mobile); + if ($clean_mobile == false) + { + $message = 'Invalid mobile number.'; + return $message; + } + + $vmanu = $r->get('vehicle_manufacturer', ''); + $vmodel = $r->get('vehicle_model', ''); + $plate_number = $r->get('plate_number'); + + // clean plate number + $clean_plate = $this->cleanPlateNumber($plate_number); + + $data = [ + 'trade_in_type' => $trade_in_type, + 'service_type' => $stype, + 'long' => $long, + 'lat' => $lat, + 'payment_mode' => $payment_mode, + 'first_name' => $fname, + 'last_name' => $lname, + 'mobile' => $clean_mobile, + 'vmanu' => $vmanu, + 'vmodel' => $model, + 'plate_number' => $clean_plate, + 'address' => $address, + 'instructions' => $instructions, + 'landmark' => $landmark, + 'is_advance_order' => $flag_advance_order, + 'hub' => $hub, + 'date_schedule' => $date_schedule, + 'promo' => $promo, + 'batt' => $batt, + ]; + + return null; } - // TODO: add function to clean plate number - // TODO: add function to normalize strings (lowercase them since the types are lowercase) + protected function processCustomerAndVehicleInformation($data, EntityManagerInterface $em) + { + // retrieve customer info + $fname = $data['first_name']; + $lname = $data['last_name']; + $vmanu = $data['vmanu']; + $vmodel = $data['vmodel']; + $plate_number = $data['plate_number']; + $mobile = $data['mobile']; + + // find customer given phone number + $cust = $em->getRepository(Customer::class)->findOneBy(['phone_mobile' => $mobile]); + + if ($cust == null) + { + // create new customer and customer vehicle + } + else + { + // find customer vehicle using plate number + $cv = $em->getRepository(CustomerVehicle::class)->findOneBy(['plate_number' => $plate_number]); + if ($cv == null) + { + // create customer vehicle + } + } + + return $cust; + } + + protected function cleanPhoneNumber($mobile) + { + // remove any non digit character from string + $clean_number = preg_replace('~\D~', '', $mobile); + + // does it fit our 09XXXXXXXXX pattern? + if (preg_match('/^09[0-9]{9}$/', $clean_number)) + { + return $clean_number; + } + // does it fit our 9XXXXXXXXX pattern? + else if (preg_match('/^9[0-9]{9}$/', $clean_number)) + { + return $clean_number; + } + // does it fit our 63XXXXXXXXXX pattern? + else if (preg_match('/^63[0-9]{10}$/', $clean_number)) + { + // strip the 63 since we don't save the country code + $c_number = substr($clean_number, 0, 2); + return $c_number; + } + + return false; + } + + protected function cleanPlateNumber($plate) + { + // remove spaces and make upper case + return strtoupper(str_replace(' ', '', $plate)); + } + + protected function cleanText($name) + { + return strtolower(trim($name)); + } } From 08050416bbc048de989f50ae0fe2fd415e68a014 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 20 Jun 2022 06:50:06 +0000 Subject: [PATCH 04/20] Add route for job order creation using third party API. #686 --- config/routes/tapi.yaml | 6 + src/Controller/APIUserController.php | 3 +- src/Controller/TAPI/JobOrderController.php | 409 +++++++++++++-------- src/Ramcar/TransactionOrigin.php | 2 + 4 files changed, 269 insertions(+), 151 deletions(-) create mode 100644 config/routes/tapi.yaml diff --git a/config/routes/tapi.yaml b/config/routes/tapi.yaml new file mode 100644 index 00000000..fad92ed7 --- /dev/null +++ b/config/routes/tapi.yaml @@ -0,0 +1,6 @@ +# third party api + +tapi_jo_request: + path: /tapi/job_order + controller: App\Controller\TAPI\JobOrderController::requestJobOrder + methods: [POST] diff --git a/src/Controller/APIUserController.php b/src/Controller/APIUserController.php index 06f128e9..302e97dd 100644 --- a/src/Controller/APIUserController.php +++ b/src/Controller/APIUserController.php @@ -160,7 +160,8 @@ class APIUserController extends Controller $meta = ['rider_id' => $rider_id]; // set api user in rider - $rider->setAPIUser($obj); + if ($rider != null) + $rider->setAPIUser($obj); // set and save values $obj->setName($req->request->get('name')) diff --git a/src/Controller/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index 55f65d46..a34f5a28 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -48,6 +48,7 @@ use App\Entity\JOEvent; use App\Entity\Customer; use App\Entity\Hub; use App\Entity\Invoice; +use App\Entity\Vehicle; use DateTime; use DateInterval; @@ -70,6 +71,7 @@ class JobOrderController extends APIController HubSelector $hub_select, HubDistributor $hub_dist, HubFilterLogger $hub_filter_logger, HubFilteringGeoChecker $hub_geofence, EntityManagerInterface $em) { + // TODO: fix all the responses $this->denyAccessUnlessGranted('tapi_jo.request', null, 'No access.'); // check required parameters and api key @@ -82,21 +84,19 @@ class JobOrderController extends APIController 'first_name', 'last_name', 'mobile_number', - 'vehicle_manufacturer', - 'vehicle_model', + 'vehicle_manufacturer_id', + 'vehicle_model_id', '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 data from request - $data = []; - $data = $this->getJobOrderRequestInfo($req, $data); - - // process customer and vehicle information - $this->processCustomerAndVehicleInformation($data, $em); + $status = $this->getJobOrderRequestInfo($req, $data); + if ($status != null) + return new APIResponse(false, $status); $is_covered = false; // geofence @@ -105,72 +105,43 @@ class JobOrderController extends APIController 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(); + $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 new APIResponse(false, $msg); } $jo = new JobOrder(); - $jo->setSource(TransactionOrigin::MOBILE_APP) + $jo->setSource($data['source']) ->setStatus(JOStatus::PENDING) - ->setDeliveryInstructions('') + ->setDeliveryInstructions($data['instructions']) ->setTier1Notes('') ->setTier2Notes('') - ->setDeliveryAddress($address) - ->setTradeInType($trade_in) - ->setDeliveryInstructions($instructions) - // TODO: error check for valid mode of payment + ->setDeliveryAddress($data['address']) + ->setTradeInType($data['trade_in_type']) + ->setDeliveryInstructions($data['instructions']) ->setModeOfPayment($data['payment_mode']) ->setAdvanceOrder($data['is_advance_order']) ->setStatusAutoAssign(AutoAssignStatus::NOT_ASSIGNED) - ->setLandmark($landmark); + ->setLandmark($data['landmark']); - $jo->setCustomer($cust); + $jo->setCustomer($data['customer']); // set coordinates - $point = new Point($long, $lat); + $point = new Point($data['long'], $data['lat']); $jo->setCoordinates($point); // make invoice criteria $icrit = new InvoiceCriteria(); - $icrit->setServiceType($stype); + $icrit->setServiceType($data['service_type']); // TODO add promo to criteria if any // check promo // put in criteria - $icrit->addPromo($promo); + $icrit->addPromo($data['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); + $icrit->setCustomerVehicle($data['customer_vehicle']); + $jo->setCustomerVehicle($data['customer_vehicle']); - // check if customer owns vehicle - if ($cust->getID() != $cv->getCustomer()->getID()) - { - $res->setError(true) - ->setErrorMessage('Customer does not own vehicle'); - return $res->getReturnResponse(); - } - - switch ($trade_in) - { - case TradeInType::MOTOLITE: - case TradeInType::OTHER: - break; - - default: - $trade_in = ''; - break; - } - - $icrit->addEntry($batt, $trade_in, 1); + $icrit->addEntry($data['batt'], $data['trade_in_type'], 1); // send to invoice generator $invoice = $ic->generateInvoice($icrit); @@ -200,7 +171,7 @@ class JobOrderController extends APIController { // error_log('hub filter is enabled'); // check if customer location is in hub filter area - if ($hub_geofence->isCovered($long, $lat)) + if ($hub_geofence->isCovered($data['long'], $data['lat'])) { // if true, set other values for HubCriteria // TODO: set this properly, since the other flags @@ -213,6 +184,7 @@ class JobOrderController extends APIController } // check if batt is null + $batt = $data['batt']; if ($batt != null) { // add battery to items @@ -222,6 +194,7 @@ class JobOrderController extends APIController } // get customer id. No JO id at this point + $cust = $data['customer']; $customer_id = $cust->getID(); $hub_criteria->setCustomerId($customer_id); @@ -326,7 +299,7 @@ class JobOrderController extends APIController $jo->setStatusAutoAssign(AutoAssignStatus::HUB_ASSIGNED); if ($date_schedule != null) - $jo->setDateSchedule($date_schedule); + $jo->setDateSchedule($data['date_schedule']); // update redis hub_jo_count for hub $hub_dist->incrementJoCountForHub($hub); @@ -414,41 +387,10 @@ 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); - - // 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); + $message = 'Job order created.'; - return $res->getReturnResponse(); + return new APIResponse(true, $message, $data); } public function getEstimate(Request $req, InvoiceGeneratorInterface $ic, EntityManagerInterface $em) @@ -1528,14 +1470,27 @@ class JobOrderController extends APIController protected function getJobOrderRequestInfo(Request $req, EntityManagerInterface $em, &$data) { + $error = $this->validateRequest($req); + if ($error != null) + { + // there is a validation error + return $error; + } + $r = $req->request; + // at this point, the request data has been validated // trade-in type $trade_in_type = $this->cleanText($r->get('trade_in_type')); - if (!TradeInType::validate($trade_in_type)) + switch ($trade_in_type) { - $message = 'Invalid trade in type'; - return $message; + case TradeInType::MOTOLITE: + case TradeInType::OTHER: + break; + + default: + $trade_in_type = ''; + break; } // address @@ -1551,22 +1506,11 @@ class JobOrderController extends APIController $long = $r->get('longitude'); $lat = $r->get('latitude'); - // validate service type + // get service type $stype = $this->cleanText($r->get('service_type')); - if (!ServiceType::validate($stype)) - { - $message = 'Invalid service type'; - return $message; - } // get mode of payment - // TODO: do we need to validate this? $payment_mode = $this->clean($r->get('mode_of_payment')); - if (!ModeOfPayment::validate($payment_mode)) - { - $message = 'Invalid mode of payment'; - return $message; - } $advance_order = $r->get('flag_advance_order'); // check for 'false' text @@ -1596,6 +1540,97 @@ class JobOrderController extends APIController } } + // get promo + $promo_id = $r->get('promo_id'); + $promo = $em->getRepository(Promo::class)->find($promo_id); + + // check battery + $batt_id = $req->request->get('batt_id'); + $batt = $em->getRepository(Battery::class)->find($batt_id); + + // get customer and vehicle info + $fname = trim($r->get('first_name', '')); + $lname = trim($r->get('last_name', '')); + $mobile = $r->get('mobile_number', ''); + + // validate mobile number + $clean_mobile = $this->cleanPhoneNumber($mobile); + + $vmanu_id = $r->get('vehicle_manufacturer'); + // find vehicle manufacturer + $vmanu = $em->getRepository(VehicleManufacturer::class)->find($vmanu_id); + + $vmodel_id = $r->get('vehicle_model'); + // find vehicle + $vehicle = $em->getRepository(Vehicle::class)->find($vmodel_id); + + $plate_number = $r->get('plate_number'); + + // clean plate number + $clean_plate = $this->cleanPlateNumber($plate_number); + + $c_data = [ + 'first_name' => $fname, + 'last_name' => $lname, + 'mobile' => $clean_mobile, + 'vmanu' => $vmanu, + 'vehicle' => $vehicle, + 'plate_number' => $clean_plate, + ]; + + // process customer and vehicle information + $cust_data = $this->processCustomerAndVehicleInformation($c_data, $em); + + $data = [ + 'trade_in_type' => $trade_in_type, + 'service_type' => $stype, + 'long' => $long, + 'lat' => $lat, + 'payment_mode' => $payment_mode, + 'address' => $address, + 'instructions' => $instructions, + 'landmark' => $landmark, + 'is_advance_order' => $flag_advance_order, + 'hub' => $hub, + 'date_schedule' => $date_schedule, + 'promo' => $promo, + 'batt' => $batt, + 'customer' => $cust_data['customer'], + 'customer_vehicle' => $cust_data['customer_vehicle'], + 'source' => TransactionOrigin::THIRD_PARTY, + ]; + + return null; + } + + protected function validateRequest(Request $req, EntityManagerInterface $em) + { + $r = $req->request; + + // validate trade-in type + $trade_in_type = $this->cleanText($r->get('trade_in_type')); + if (!TradeInType::validate($trade_in_type)) + { + $message = 'Invalid trade in type'; + return $message; + } + + // validate service type + $stype = $this->cleanText($r->get('service_type')); + if (!ServiceType::validate($stype)) + { + $message = 'Invalid service type'; + return $message; + } + + // validate mode of payment + $payment_mode = $this->clean($r->get('mode_of_payment')); + if (!ModeOfPayment::validate($payment_mode)) + { + $message = 'Invalid mode of payment'; + return $message; + } + // check promo $promo = null; $promo_id = $r->get('promo_id'); @@ -1603,7 +1638,7 @@ class JobOrderController extends APIController { $promo = $em->getRepository(Promo::class)->find($promo_id); if ($promo == null) - { + { $message = 'Invalid promo id'; return $message; } @@ -1612,7 +1647,7 @@ class JobOrderController extends APIController // check battery $batt = null; $batt_id = $req->request->get('batt_id'); - if ($batt_id != null) + if ($empty($batt_id)) { $batt = $em->getRepository(Battery::class)->find($batt_id); if ($batt == null) @@ -1622,12 +1657,8 @@ class JobOrderController extends APIController } } - // get customer and vehicle info - $fname = $r->get('first_name', ''); - $lname = $r->get('last_name', ''); - $mobile = $r->get('mobile_number', ''); - // validate mobile number + $mobile = $r->get('mobile_number', ''); $clean_mobile = $this->cleanPhoneNumber($mobile); if ($clean_mobile == false) { @@ -1635,66 +1666,144 @@ class JobOrderController extends APIController return $message; } - $vmanu = $r->get('vehicle_manufacturer', ''); - $vmodel = $r->get('vehicle_model', ''); - $plate_number = $r->get('plate_number'); + $vmanu = null; + $vmanu_id = $r->get('vehicle_manufacturer'); + // validate the vehicle manufacturer id + // find vehicle manufacturer + $vmanu = $em->getRepository(VehicleManufacturer::class)->find($vmanu_id); + if ($vmanu == null) + { + $message = 'Invalid vehicle manufacturer id.'; + return $message; + } - // clean plate number - $clean_plate = $this->cleanPlateNumber($plate_number); + $vmodel = null; + $vmodel_id = $r->get('vehicle_model'); + // validate the vehicle model id + // find vehicle + $vmodel = $em->getRepository(Vehicle::class)->find($vmodel_id); + if ($vmodel = null) + { + $message = 'Invalid vehicle model id.'; + return $message; + } - $data = [ - 'trade_in_type' => $trade_in_type, - 'service_type' => $stype, - 'long' => $long, - 'lat' => $lat, - 'payment_mode' => $payment_mode, - 'first_name' => $fname, - 'last_name' => $lname, - 'mobile' => $clean_mobile, - 'vmanu' => $vmanu, - 'vmodel' => $model, - 'plate_number' => $clean_plate, - 'address' => $address, - 'instructions' => $instructions, - 'landmark' => $landmark, - 'is_advance_order' => $flag_advance_order, - 'hub' => $hub, - 'date_schedule' => $date_schedule, - 'promo' => $promo, - 'batt' => $batt, - ]; + // confirm that vehicle model's manufacturer is the same as the one in vehicle + if ($vmodel->getManufacturer()->getID != $vmanu_id) + { + $message = 'Invalid vehicle manufacturer id for vehicle model.'; + return $message; + } return null; } protected function processCustomerAndVehicleInformation($data, EntityManagerInterface $em) { + $c_data = []; + // retrieve customer info $fname = $data['first_name']; $lname = $data['last_name']; $vmanu = $data['vmanu']; - $vmodel = $data['vmodel']; + $vehicle = $data['vehicle']; $plate_number = $data['plate_number']; $mobile = $data['mobile']; - - // find customer given phone number - $cust = $em->getRepository(Customer::class)->findOneBy(['phone_mobile' => $mobile]); + + $cust = null; + $cust_vehicle = null; - if ($cust == null) + // find customer + customer vehicle combo + $cv = $this->findCustomerAndCustomerVehicle($data, $em); + if ($cv == null) { - // create new customer and customer vehicle - } - else - { - // find customer vehicle using plate number - $cv = $em->getRepository(CustomerVehicle::class)->findOneBy(['plate_number' => $plate_number]); - if ($cv == null) + // find customer given phone number + $cust = $em->getRepository(Customer::class)->findOneBy(['phone_mobile' => $mobile]); + + if ($cust == null) + { + // get the api_user that made the call so that it gets added to the source + // source becomes TAPI_USER_ + $user_id = $_SERVER['HTTP_X_CATA_API_KEY']; + $source = 'TAPI_USER'; + $username = ''; + + if (!empty($user_id)) + { + $api_user = $this->getUser(); + if ($api_user != null) + { + $username = $api_user->getName(); + $source = $source . '_' . $username; + } + } + + // create new customer and customer vehicle + $cust = new Customer(); + + $cust->setFirstName($fname) + ->setLastName($lname) + ->setPhoneMobile($mobile) + ->setCreateSource($source); + + $em->persist($cust); + + // add customer vehicle + $cust_vehicle = $this->createCustomerVehicle($em, $cust, $vehicle); + + } + else { // create customer vehicle + $cust_vehicle = $this->createCustomerVehicle($em, $cust, $vehicle); } + + $em->flush(); } - return $cust; + $c_data = [ + 'customer' => $cust, + 'customer_vehicle' => $cust_vehicle, + ]; + + return $c_data; + } + + protected function createCustomerVehicle(EntityManagerInterface $em, Customer $cust, Vehicle $vehicle) + { + // add customer vehicle + $cust_vehicle = new CustomerVehicle(); + + $cust_vehicle->setCustomer($cust) + ->setPlateNumber($plate_number) + ->setVehicle($vehicle); + + $em->persist($cust_vehicle); + + return $cust_vehicle; + } + + protected function findCustomerAndCustomerVehicle($data, EntityManagerInterface $em) + { + $plate_number = $data['plate_number']; + $mobile = $data['mobile']; + + $query = $em->createQuery('SELECT cv, c FROM App\Entity\CustomerVehicle cv + JOIN cv.customer c + WHERE cv.plate_number = :plate_number + AND c.phone_mobile = :phone_mobile'); + $query->setParameter('plate_number', $plate_number) + ->setParameter('phone_mobile', $mobile); + + $cust_results = $query->iterate(); + + $cust_vehicle = null; + foreach ($cust_results as $row) + { + $cust_vehicle = $row[0]; + } + + return $cust_vehicle; } protected function cleanPhoneNumber($mobile) diff --git a/src/Ramcar/TransactionOrigin.php b/src/Ramcar/TransactionOrigin.php index 8d4c12aa..80f0d029 100644 --- a/src/Ramcar/TransactionOrigin.php +++ b/src/Ramcar/TransactionOrigin.php @@ -11,6 +11,7 @@ class TransactionOrigin extends NameValue const MOBILE_APP = 'mobile_app'; const WALK_IN = 'walk_in'; const LAZADA = 'lazada'; + const THIRD_PARTY = 'third_party'; // TODO: for now, resq also gets the walk-in option const COLLECTION = [ @@ -21,5 +22,6 @@ class TransactionOrigin extends NameValue 'mobile_app' => 'Mobile App', 'walk_in' => 'Walk-in', 'lazada' => 'Lazada', + 'third_party' => 'Third Party', ]; } From fb91d462ffb616d49966c5212ca6d0ffca9e429f Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 20 Jun 2022 09:00:56 +0000 Subject: [PATCH 05/20] Add path to tapi calls. Add more required parameters for new job order. #686 --- config/api_acl.yaml | 8 +- config/packages/security.yaml | 8 ++ src/Controller/TAPI/JobOrderController.php | 132 +++++++++++++-------- 3 files changed, 96 insertions(+), 52 deletions(-) diff --git a/config/api_acl.yaml b/config/api_acl.yaml index 9182674e..b235ff81 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -81,17 +81,17 @@ access_keys: - id: tapi_vehicle.list label: List Third Party Vehicles - id: tapi_promo - labels: Third Party Promo Access + label: Third Party Promo Access acls: - id: tapi_promo.list label: List Third Party Promos - id: tapi_battery - labels: Third Party Battery Access + label: Third Party Battery Access acls: - id: tapi_battery_compatible.list label: List Third Party Compatible Batteries - id: tapi_jo - labels: Third Party Job Order Access + label: Third Party Job Order Access acls: - id: tapi_jo.request label: Third Party Request Job Order @@ -114,7 +114,7 @@ access_keys: - id: tapi_jo.get.info label: Third Party Get Job Order Info - id: tapi_service - labels: Third Party Service Access + label: Third Party Service Access acls: - id: tapi_service.list label: List Third Party Services diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 2eecd1e8..60518b75 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -59,6 +59,14 @@ security: provider: api_key_user_provider user_checker: Catalyst\AuthBundle\Service\UserChecker + third_party_api: + pattern: ^\/tapi\/ + 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/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index a34f5a28..0127aadd 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -4,6 +4,7 @@ namespace App\Controller\TAPI; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Dotenv\Dotenv; use Doctrine\ORM\Query; use Doctrine\ORM\EntityManagerInterface; @@ -25,6 +26,8 @@ use App\Ramcar\JOEventType; use App\Ramcar\HubCriteria; use App\Ramcar\ModeOfPayment; use App\Ramcar\APIRiderStatus; +use App\Ramcar\VehicleStatusCondition; +use App\Ramcar\FuelType; use App\Service\InvoiceGeneratorInterface; use App\Service\RisingTideGateway; @@ -49,6 +52,7 @@ use App\Entity\Customer; use App\Entity\Hub; use App\Entity\Invoice; use App\Entity\Vehicle; +use App\Entity\VehicleManufacturer; use DateTime; use DateInterval; @@ -71,9 +75,6 @@ class JobOrderController extends APIController HubSelector $hub_select, HubDistributor $hub_dist, HubFilterLogger $hub_filter_logger, HubFilteringGeoChecker $hub_geofence, EntityManagerInterface $em) { - // TODO: fix all the responses - $this->denyAccessUnlessGranted('tapi_jo.request', null, 'No access.'); - // check required parameters and api key $required_params = [ 'service_type', @@ -86,6 +87,10 @@ class JobOrderController extends APIController 'mobile_number', 'vehicle_manufacturer_id', 'vehicle_model_id', + 'vehicle_model_year', + 'vehicle_color', + 'vehicle_condition', + 'vehicle_fuel_type', 'plate_number' ]; @@ -94,7 +99,8 @@ class JobOrderController extends APIController return new APIResponse(false, $msg); // get data from request - $status = $this->getJobOrderRequestInfo($req, $data); + $data = []; + $status = $this->getJobOrderRequestInfo($req, $em, $data); if ($status != null) return new APIResponse(false, $status); @@ -112,6 +118,8 @@ class JobOrderController extends APIController $jo = new JobOrder(); $jo->setSource($data['source']) ->setStatus(JOStatus::PENDING) + ->setServiceType($data['service_type']) + ->setWarrantyClass($data['warranty_class']) ->setDeliveryInstructions($data['instructions']) ->setTier1Notes('') ->setTier2Notes('') @@ -124,6 +132,7 @@ class JobOrderController extends APIController ->setLandmark($data['landmark']); $jo->setCustomer($data['customer']); + $jo->setCustomerVehicle($data['customer_vehicle']); // set coordinates $point = new Point($data['long'], $data['lat']); @@ -136,10 +145,10 @@ class JobOrderController extends APIController // TODO add promo to criteria if any // check promo // put in criteria - $icrit->addPromo($data['promo']); + if ($data['promo'] != null) + $icrit->addPromo($data['promo']); $icrit->setCustomerVehicle($data['customer_vehicle']); - $jo->setCustomerVehicle($data['customer_vehicle']); $icrit->addEntry($data['batt'], $data['trade_in_type'], 1); @@ -149,6 +158,7 @@ class JobOrderController extends APIController // assign hub and rider // check if hub is null + $hub = $data['hub']; if ($hub == null) { // TODO: need to factor out the setting of HubCriteria fields @@ -158,7 +168,7 @@ class JobOrderController extends APIController // get distance limit for mobile from env // get value of hub_filter_enable from env $dotenv = new Dotenv(); - $dotenv->loadEnv(__DIR__.'/../../.env'); + $dotenv->loadEnv(__DIR__.'/../../../.env'); $limit_distance = $_ENV['CUST_DISTANCE_LIMIT']; $hub_filter_enabled = $_ENV['HUB_FILTER_ENABLE']; @@ -298,7 +308,7 @@ class JobOrderController extends APIController $jo->setStatus(JOStatus::RIDER_ASSIGN); $jo->setStatusAutoAssign(AutoAssignStatus::HUB_ASSIGNED); - if ($date_schedule != null) + if ($data['date_schedule'] != null) $jo->setDateSchedule($data['date_schedule']); // update redis hub_jo_count for hub @@ -1470,7 +1480,7 @@ class JobOrderController extends APIController protected function getJobOrderRequestInfo(Request $req, EntityManagerInterface $em, &$data) { - $error = $this->validateRequest($req); + $error = $this->validateRequest($req, $em); if ($error != null) { // there is a validation error @@ -1481,7 +1491,7 @@ class JobOrderController extends APIController // at this point, the request data has been validated // trade-in type - $trade_in_type = $this->cleanText($r->get('trade_in_type')); + $trade_in_type = $this->cleanText($r->get('trade_in_type', '')); switch ($trade_in_type) { case TradeInType::MOTOLITE: @@ -1507,12 +1517,12 @@ class JobOrderController extends APIController $lat = $r->get('latitude'); // get service type - $stype = $this->cleanText($r->get('service_type')); + $stype = $this->cleanText($r->get('service_type', '')); // get mode of payment - $payment_mode = $this->clean($r->get('mode_of_payment')); + $payment_mode = $this->cleanText($r->get('mode_of_payment', '')); - $advance_order = $r->get('flag_advance_order'); + $advance_order = $r->get('flag_advance_order', 0); // check for 'false' text if ($advance_order === false || $advance_order === 0 || $advance_order === '0' || $advance_order == 'false') $flag_advance_order = false; @@ -1525,28 +1535,22 @@ class JobOrderController extends APIController $hub = $em->getRepository(Hub::class)->find($hub_id); $schedule_date = $r->get('date_schedule'); - $slot_id = $r->get('slot_id'); // process the jo date schedule $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')); - } - } + if (strlen($schedule_date) > 0) + $date_schedule = DateTime::createFromFormat('Y-m-d H:i', $schedule_date); // get promo - $promo_id = $r->get('promo_id'); + $promo_id = $r->get('promo_id', 0); $promo = $em->getRepository(Promo::class)->find($promo_id); // check battery - $batt_id = $req->request->get('batt_id'); + $batt_id = $req->request->get('battery_id', 0); $batt = $em->getRepository(Battery::class)->find($batt_id); + $warranty_class = ''; + if (($batt != null) && ($stype == ServiceType::BATTERY_REPLACEMENT_NEW)) + $warranty_class = WarrantyClass::WTY_PRIVATE; // get customer and vehicle info $fname = trim($r->get('first_name', '')); @@ -1556,19 +1560,24 @@ class JobOrderController extends APIController // validate mobile number $clean_mobile = $this->cleanPhoneNumber($mobile); - $vmanu_id = $r->get('vehicle_manufacturer'); + $vmanu_id = $r->get('vehicle_manufacturer_id', 0); // find vehicle manufacturer $vmanu = $em->getRepository(VehicleManufacturer::class)->find($vmanu_id); - $vmodel_id = $r->get('vehicle_model'); + $vmodel_id = $r->get('vehicle_model_id', 0); // find vehicle $vehicle = $em->getRepository(Vehicle::class)->find($vmodel_id); - $plate_number = $r->get('plate_number'); + $plate_number = $r->get('plate_number', ''); // clean plate number $clean_plate = $this->cleanPlateNumber($plate_number); + $v_condition = $this->cleanText($r->get('vehicle_condition', '')); + $fuel_type = $this->cleanText($r->get('vehicle_fuel_type', '')); + $color = trim($r->get('vehicle_color', '')); + $model_year = trim($r->get('vehicle_model_year', 0)); + $c_data = [ 'first_name' => $fname, 'last_name' => $lname, @@ -1576,6 +1585,10 @@ class JobOrderController extends APIController 'vmanu' => $vmanu, 'vehicle' => $vehicle, 'plate_number' => $clean_plate, + 'model_year' => $model_year, + 'condition' => $v_condition, + 'color' => $color, + 'fuel_type' => $fuel_type, ]; // process customer and vehicle information @@ -1598,6 +1611,7 @@ class JobOrderController extends APIController 'customer' => $cust_data['customer'], 'customer_vehicle' => $cust_data['customer_vehicle'], 'source' => TransactionOrigin::THIRD_PARTY, + 'warranty_class' => $warranty_class, ]; return null; @@ -1608,15 +1622,16 @@ class JobOrderController extends APIController $r = $req->request; // validate trade-in type - $trade_in_type = $this->cleanText($r->get('trade_in_type')); - if (!TradeInType::validate($trade_in_type)) + $trade_in_type = $this->cleanText($r->get('trade_in_type', '')); + if ((!empty($trade_in_type)) && + (!TradeInType::validate($trade_in_type))) { $message = 'Invalid trade in type'; return $message; } // validate service type - $stype = $this->cleanText($r->get('service_type')); + $stype = $this->cleanText($r->get('service_type', '')); if (!ServiceType::validate($stype)) { $message = 'Invalid service type'; @@ -1624,7 +1639,7 @@ class JobOrderController extends APIController } // validate mode of payment - $payment_mode = $this->clean($r->get('mode_of_payment')); + $payment_mode = $this->cleanText($r->get('mode_of_payment', '')); if (!ModeOfPayment::validate($payment_mode)) { $message = 'Invalid mode of payment'; @@ -1633,7 +1648,7 @@ class JobOrderController extends APIController // check promo $promo = null; - $promo_id = $r->get('promo_id'); + $promo_id = $r->get('promo_id', 0); if (!empty($promo_id)) { $promo = $em->getRepository(Promo::class)->find($promo_id); @@ -1646,8 +1661,8 @@ class JobOrderController extends APIController // check battery $batt = null; - $batt_id = $req->request->get('batt_id'); - if ($empty($batt_id)) + $batt_id = $req->request->get('battery_id', 0); + if (!empty($batt_id)) { $batt = $em->getRepository(Battery::class)->find($batt_id); if ($batt == null) @@ -1667,7 +1682,7 @@ class JobOrderController extends APIController } $vmanu = null; - $vmanu_id = $r->get('vehicle_manufacturer'); + $vmanu_id = $r->get('vehicle_manufacturer_id', 0); // validate the vehicle manufacturer id // find vehicle manufacturer $vmanu = $em->getRepository(VehicleManufacturer::class)->find($vmanu_id); @@ -1678,23 +1693,39 @@ class JobOrderController extends APIController } $vmodel = null; - $vmodel_id = $r->get('vehicle_model'); + $vmodel_id = $r->get('vehicle_model_id', 0); // validate the vehicle model id // find vehicle $vmodel = $em->getRepository(Vehicle::class)->find($vmodel_id); - if ($vmodel = null) + if ($vmodel == null) { $message = 'Invalid vehicle model id.'; return $message; } // confirm that vehicle model's manufacturer is the same as the one in vehicle - if ($vmodel->getManufacturer()->getID != $vmanu_id) + if ($vmodel->getManufacturer()->getID() != $vmanu_id) { $message = 'Invalid vehicle manufacturer id for vehicle model.'; return $message; } + // validate vehicle condition + $v_condition = $this->cleanText($r->get('vehicle_condition', '')); + if (!VehicleStatusCondition::validate($v_condition)) + { + $message = 'Invalid vehicle condition.'; + return $message; + } + + // validate fuel type + $fuel_type = $this->cleanText($r->get('vehicle_fuel_type', '')); + if (!FuelType::validate($fuel_type)) + { + $message = 'Invalid vehicle fuel type.'; + return $message; + } + return null; } @@ -1714,8 +1745,8 @@ class JobOrderController extends APIController $cust_vehicle = null; // find customer + customer vehicle combo - $cv = $this->findCustomerAndCustomerVehicle($data, $em); - if ($cv == null) + $cust_vehicle = $this->findCustomerAndCustomerVehicle($data, $em); + if ($cust_vehicle == null) { // find customer given phone number $cust = $em->getRepository(Customer::class)->findOneBy(['phone_mobile' => $mobile]); @@ -1749,34 +1780,39 @@ class JobOrderController extends APIController $em->persist($cust); // add customer vehicle - $cust_vehicle = $this->createCustomerVehicle($em, $cust, $vehicle); + $cust_vehicle = $this->createCustomerVehicle($em, $cust, $data); } else { // create customer vehicle - $cust_vehicle = $this->createCustomerVehicle($em, $cust, $vehicle); + $cust_vehicle = $this->createCustomerVehicle($em, $cust, $data); } $em->flush(); } $c_data = [ - 'customer' => $cust, + 'customer' => $cust_vehicle->getCustomer(), 'customer_vehicle' => $cust_vehicle, ]; return $c_data; } - protected function createCustomerVehicle(EntityManagerInterface $em, Customer $cust, Vehicle $vehicle) + protected function createCustomerVehicle(EntityManagerInterface $em, Customer $cust, $data) { // add customer vehicle $cust_vehicle = new CustomerVehicle(); $cust_vehicle->setCustomer($cust) - ->setPlateNumber($plate_number) - ->setVehicle($vehicle); + ->setPlateNumber($data['plate_number']) + ->setVehicle($data['vehicle']) + ->setModelYear($data['model_year']) + ->setStatusCondition($data['condition']) + ->setColor($data['color']) + ->setHasMotoliteBattery(true) + ->setFuelType($data['fuel_type']); $em->persist($cust_vehicle); From 5b32349437676f31cd4dfa7423259bb29830ee98 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Mon, 20 Jun 2022 10:20:42 +0000 Subject: [PATCH 06/20] Fix the responses for the api calls for vehicle and battery. #686 --- config/routes/tapi.yaml | 18 +++++++++++++ src/Controller/TAPI/BatteryController.php | 16 +++++------- src/Controller/TAPI/JobOrderController.php | 2 ++ src/Controller/TAPI/VehicleController.php | 30 +++++++++++----------- 4 files changed, 42 insertions(+), 24 deletions(-) diff --git a/config/routes/tapi.yaml b/config/routes/tapi.yaml index fad92ed7..8042bccb 100644 --- a/config/routes/tapi.yaml +++ b/config/routes/tapi.yaml @@ -1,6 +1,24 @@ # third party api +# job order tapi_jo_request: path: /tapi/job_order controller: App\Controller\TAPI\JobOrderController::requestJobOrder methods: [POST] + +# vehicle manufacturer and vehicle +tapi_vehicle_mfg_list: + path: /tapi/vehicle/mfgs + controller: App\Controller\TAPI\VehicleController::listVehicleManufacturers + methods: [GET] + +tapi_vehicle_make_list: + path: /tapi/vehicle/mfgs/{mfg_id}/makes + controller: App\Controller\TAPI\VehicleController::listVehicleMakes + methods: [GET] + +# battery +tapi_battery_list: + path: /tapi/vehicles/{vid}/compatible_batteries + controller: App\Controller\TAPI\BatteryController::getCompatibleBatteries + methods: [GET] diff --git a/src/Controller/TAPI/BatteryController.php b/src/Controller/TAPI/BatteryController.php index 5423153b..f75f7e91 100644 --- a/src/Controller/TAPI/BatteryController.php +++ b/src/Controller/TAPI/BatteryController.php @@ -31,17 +31,16 @@ class BatteryController extends APIController // 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 vehicle $vehicle = $em->getRepository(Vehicle::class)->find($vid); if ($vehicle == null) { - $res->setError(true) - ->setErrorMessage('Invalid vehicle'); - return $res->getReturnResponse(); + $message = 'Invalid vehicle id.'; + return new APIResponse(false, $message); } // batteries @@ -77,9 +76,8 @@ class BatteryController extends APIController ], 'batteries' => $batt_list, ]; - $res->setData($data); - - return $res->getReturnResponse(); + $message = 'Compatible batteries found.'; + return new APIResponse(true, $message, $data); } } diff --git a/src/Controller/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index 0127aadd..eccfe8f3 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -75,6 +75,8 @@ class JobOrderController extends APIController HubSelector $hub_select, HubDistributor $hub_dist, HubFilterLogger $hub_filter_logger, HubFilteringGeoChecker $hub_geofence, EntityManagerInterface $em) { + $this->denyAccessUnlessGranted('tapi_jo.request', null, 'No access.'); + // check required parameters and api key $required_params = [ 'service_type', diff --git a/src/Controller/TAPI/VehicleController.php b/src/Controller/TAPI/VehicleController.php index df471726..5e8bf122 100644 --- a/src/Controller/TAPI/VehicleController.php +++ b/src/Controller/TAPI/VehicleController.php @@ -29,11 +29,11 @@ class VehicleController extends APIController { $this->denyAccessUnlessGranted('tapi_vmanufacturer.list', null, 'No access.'); - // check required parameters and api key + // 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 manufacturer list $mfgs = $em->getRepository(VehicleManufacturer::class)->findBy(['flag_mobile' => true], ['name' => 'asc']); @@ -49,9 +49,11 @@ class VehicleController extends APIController $data = [ 'manufacturers' => $mfg_list ]; - $res->setData($data); - return $res->getReturnResponse(); + $message = 'Vehicle manufacturers found.'; + + return new APIResponse(true, $message, $data); + } public function listVehicleMakes(Request $req, $mfg_id, EntityManagerInterface $em) @@ -60,17 +62,16 @@ class VehicleController extends APIController // 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 manufacturer $mfg = $em->getRepository(VehicleManufacturer::class)->find($mfg_id); if ($mfg == null) { - $res->setError(true) - ->setErrorMessage('Invalid vehicle manufacturer id'); - return $res->getReturnResponse(); + $message = 'Invalid vehicle manufacturer id.'; + return new APIResponse(false, $message); } // get makes @@ -88,7 +89,6 @@ class VehicleController extends APIController $vlist[] = [ 'id' => $v->getID(), 'make' => trim($v->getMake() . ' ' . $v->getModelYearFormatted(false)), - // 'make' => $v->getMake() . ' ' . $v->getModelYearFrom() . '-' . $v->getModelYearTo(), ]; } @@ -100,8 +100,8 @@ class VehicleController extends APIController 'makes' => $vlist, ]; - $res->setData($data); + $message = 'Vehicle models found.'; + return new APIResponse(true, $message, $data); - return $res->getReturnResponse(); } } From ce6b1f8049731237aea0033c36f30c1fdeca388d Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 21 Jun 2022 03:20:30 +0000 Subject: [PATCH 07/20] Fix responses. Add routes for promo. #686 --- config/routes/tapi.yaml | 6 ++++++ src/Controller/TAPI/BatteryController.php | 10 ++++++++++ src/Controller/TAPI/JobOrderController.php | 1 + src/Controller/TAPI/PromoController.php | 13 +++++++++---- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/config/routes/tapi.yaml b/config/routes/tapi.yaml index 8042bccb..f72c1280 100644 --- a/config/routes/tapi.yaml +++ b/config/routes/tapi.yaml @@ -22,3 +22,9 @@ tapi_battery_list: path: /tapi/vehicles/{vid}/compatible_batteries controller: App\Controller\TAPI\BatteryController::getCompatibleBatteries methods: [GET] + +# promos +tapi_promo_list: + path: /tapi/promos + controller: App\Controller\TAPI\PromoController::listPromos + methods: [GET] diff --git a/src/Controller/TAPI/BatteryController.php b/src/Controller/TAPI/BatteryController.php index f75f7e91..7e015fe6 100644 --- a/src/Controller/TAPI/BatteryController.php +++ b/src/Controller/TAPI/BatteryController.php @@ -80,4 +80,14 @@ class BatteryController extends APIController $message = 'Compatible batteries found.'; return new APIResponse(true, $message, $data); } + + // TODO: might have to put this in a common service since JobOrderController also calls this + protected function getBatteryImageURL($req, $batt) + { + // 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() . $this->generateUrl('static_battery_image') . '/' . $filename; + + return $file_path; + } } diff --git a/src/Controller/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index eccfe8f3..1ec64252 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -1471,6 +1471,7 @@ class JobOrderController extends APIController return $selected_rider; } + // TODO: might have to put this in a common service since BatteryController also calls this protected function getBatteryImageURL($req, $batt) { // TODO: workaround for now, we get static image of battery based on model name diff --git a/src/Controller/TAPI/PromoController.php b/src/Controller/TAPI/PromoController.php index 9b21a429..90cbaf0a 100644 --- a/src/Controller/TAPI/PromoController.php +++ b/src/Controller/TAPI/PromoController.php @@ -30,11 +30,16 @@ class PromoController extends APIController // 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); - return $res->getReturnResponse(); + $data = []; + // TODO: add call to get promos here + + $message = 'Promos found.'; + + return new APIResponse(true, $message, $data); } } From 7985ec8f340355bf1cd365594d6021b5abceabc6 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 21 Jun 2022 03:57:16 +0000 Subject: [PATCH 08/20] Rename validateRequest to validateJORequest. Modify required parameters for getEstimate. #686 --- src/Controller/TAPI/JobOrderController.php | 24 ++++++---------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/src/Controller/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index 1ec64252..4235dddd 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -412,23 +412,11 @@ class JobOrderController extends APIController // check required parameters and api key $required_params = [ 'service_type', - 'cv_id', - // 'batt_id', - 'trade_in', + 'vehicle_id', ]; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); - - // customer - // TODO: needs to be modified to get customer - $cust = $this->session->getCustomer(); - if ($cust == null) - { - $res->setError(true) - ->setErrorMessage('No customer information found'); - return $res->getReturnResponse(); - } + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); // make invoice criteria $icrit = new InvoiceCriteria(); @@ -1483,7 +1471,7 @@ class JobOrderController extends APIController protected function getJobOrderRequestInfo(Request $req, EntityManagerInterface $em, &$data) { - $error = $this->validateRequest($req, $em); + $error = $this->validateJORequest($req, $em); if ($error != null) { // there is a validation error @@ -1620,7 +1608,7 @@ class JobOrderController extends APIController return null; } - protected function validateRequest(Request $req, EntityManagerInterface $em) + protected function validateJORequest(Request $req, EntityManagerInterface $em) { $r = $req->request; From f486a1b5a026c73b705aaecad17289a495fe205a Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 21 Jun 2022 07:55:25 +0000 Subject: [PATCH 09/20] Add route for getEstimate. Modify getEstimate for third party api. #686 --- config/routes/tapi.yaml | 5 + src/Controller/TAPI/JobOrderController.php | 213 ++++++++++++++------- 2 files changed, 150 insertions(+), 68 deletions(-) diff --git a/config/routes/tapi.yaml b/config/routes/tapi.yaml index f72c1280..3d345d5f 100644 --- a/config/routes/tapi.yaml +++ b/config/routes/tapi.yaml @@ -6,6 +6,11 @@ tapi_jo_request: controller: App\Controller\TAPI\JobOrderController::requestJobOrder methods: [POST] +tapi_estimate: + path: /tapi/estimate + controller: App\Controller\TAPI\JobOrderController::getEstimate + methods: [POST] + # vehicle manufacturer and vehicle tapi_vehicle_mfg_list: path: /tapi/vehicle/mfgs diff --git a/src/Controller/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index 4235dddd..e627b15f 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -412,78 +412,26 @@ class JobOrderController extends APIController // check required parameters and api key $required_params = [ 'service_type', - 'vehicle_id', + 'vehicle_model_id', ]; $msg = $this->checkRequiredParameters($req, $required_params); if ($msg) return new APIResponse(false, $msg); + $data = []; + $msg = $this->validateAndGetEstimateRequest($req, $em, $data); + if ($msg != null) + return new APIResponse(false, $msg); + // make invoice criteria $icrit = new InvoiceCriteria(); - $icrit->setServiceType($req->request->get('service_type')); + $icrit->setServiceType($data['service_type']); + $icrit->setCustomerVehicle($data['customer_vehicle']); - // 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(); - } + if ($data['promo'] != null) + $icrit->addPromo($data['promo']); - // 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; - - $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); + $icrit->addEntry($data['battery'], $data['trade_in_type'], 1); // send to invoice generator $invoice = $ic->generateInvoice($icrit); @@ -517,10 +465,8 @@ class JobOrderController extends APIController $data['items'] = $items_data; - // set data - $res->setData($data); - - return $res->getReturnResponse(); + $message = 'Estimate computed.'; + return new APIResponse(true, $message, $data); } public function getJOInvoice(Request $req, EntityManagerInterface $em) @@ -1663,6 +1609,18 @@ class JobOrderController extends APIController } } + // check if service type is BATTERY_REPLACEMENT_WARRANTY or + // BATTERY_REPLACEMENT_NEW and if battery_id is empty + if (($stype == ServiceType::BATTERY_REPLACEMENT_NEW) || + ($stype == ServiceType::BATTERY_REPLACEMENT_WARRANTY)) + { + if ($batt == null) + { + $message = 'battery_id cannot be empty for selected service type.'; + return $message; + } + } + // validate mobile number $mobile = $r->get('mobile_number', ''); $clean_mobile = $this->cleanPhoneNumber($mobile); @@ -1802,7 +1760,7 @@ class JobOrderController extends APIController ->setModelYear($data['model_year']) ->setStatusCondition($data['condition']) ->setColor($data['color']) - ->setHasMotoliteBattery(true) + ->setHasMotoliteBattery(false) ->setFuelType($data['fuel_type']); $em->persist($cust_vehicle); @@ -1833,6 +1791,125 @@ class JobOrderController extends APIController return $cust_vehicle; } + protected function validateAndGetEstimateRequest(Request $req, EntityManagerInterface $em, &$data) + { + $r = $req->request; + + // validate service type + $stype = $this->cleanText($r->get('service_type', '')); + if (!ServiceType::validate($stype)) + { + $message = 'Invalid service type'; + return $message; + } + + $trade_in_type = $this->cleanText($r->get('trade_in_type', '')); + if ((!empty($trade_in_type)) && + (!TradeInType::validate($trade_in_type))) + { + $message = 'Invalid trade in type'; + return $message; + } + + switch ($trade_in_type) + { + case TradeInType::MOTOLITE: + case TradeInType::OTHER: + break; + + default: + $trade_in_type = ''; + break; + } + + // check battery + $batt = null; + $batt_id = $req->request->get('battery_id', 0); + if (!empty($batt_id)) + { + $batt = $em->getRepository(Battery::class)->find($batt_id); + if ($batt == null) + { + $message = 'Invalid battery id'; + return $message; + } + } + + // check if service type is BATTERY_REPLACEMENT_WARRANTY or + // BATTERY_REPLACEMENT_NEW and if battery_id is empty + if (($stype == ServiceType::BATTERY_REPLACEMENT_NEW) || + ($stype == ServiceType::BATTERY_REPLACEMENT_WARRANTY)) + { + if ($batt == null) + { + $message = 'battery_id cannot be empty for selected service type.'; + return $message; + } + } + + $vmodel = null; + $vmodel_id = $r->get('vehicle_model_id', 0); + // validate the vehicle model id + // find vehicle + $vmodel = $em->getRepository(Vehicle::class)->find($vmodel_id); + if ($vmodel == null) + { + $message = 'Invalid vehicle model id.'; + return $message; + } + + // validate fuel type + $fuel_type = $this->cleanText($r->get('vehicle_fuel_type', '')); + if ((!empty($fuel_type)) && + (!FuelType::validate($fuel_type))) + { + $message = 'Invalid vehicle fuel type.'; + return $message; + } + + // validate promo + $promo = null; + $promo_id = $r->get('promo_id', 0); + if (!empty($promo_id)) + { + $promo = $em->getRepository(Promo::class)->find($promo_id); + if ($promo == null) + { + $message = 'Invalid promo id'; + return $message; + } + } + + // invoice criteria needs a customer vehicle object + // with customer set. We create dummy customer vehicle object + // with dummy customer set + $dummy_cv = $this->createDummyCustomerVehicle($vmodel, $fuel_type); + + $data = [ + 'service_type' => $stype, + 'trade_in_type' => $trade_in_type, + 'vehicle' => $vmodel, + 'battery' => $batt, + 'fuel_type' => $fuel_type, + 'promo' => $promo, + 'customer_vehicle' => $dummy_cv, + ]; + + return null; + } + + protected function createDummyCustomerVehicle($vmodel, $fuel_type) + { + $dummy_cv = new CustomerVehicle(); + $dummy_cust = new Customer(); + + $dummy_cv->setCustomer($dummy_cust) + ->setFuelType($fuel_type) + ->setHasMotoliteBattery(false); + + return $dummy_cv; + } + protected function cleanPhoneNumber($mobile) { // remove any non digit character from string From 3e73bc0513e6cfa8904594ecd2f611c95bc35d10 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 21 Jun 2022 08:32:19 +0000 Subject: [PATCH 10/20] Add route for getJOInvoice. Modify getJOInvoice responses. #686 --- config/routes/tapi.yaml | 5 +++ src/Controller/TAPI/JobOrderController.php | 44 +++++----------------- 2 files changed, 14 insertions(+), 35 deletions(-) diff --git a/config/routes/tapi.yaml b/config/routes/tapi.yaml index 3d345d5f..fb343038 100644 --- a/config/routes/tapi.yaml +++ b/config/routes/tapi.yaml @@ -11,6 +11,11 @@ tapi_estimate: controller: App\Controller\TAPI\JobOrderController::getEstimate methods: [POST] +tapi_jo_invoice: + path: /tapi/job_order/invoice/{jo_id} + controller: App\Controller\TAPI\JobOrderController:getJOInvoice + methods: [GET] + # vehicle manufacturer and vehicle tapi_vehicle_mfg_list: path: /tapi/vehicle/mfgs diff --git a/src/Controller/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index e627b15f..3d38efd5 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -469,44 +469,20 @@ class JobOrderController extends APIController return new APIResponse(true, $message, $data); } - public function getJOInvoice(Request $req, EntityManagerInterface $em) + public function getJOInvoice(Request $req, $jo_id, EntityManagerInterface $em) { $this->denyAccessUnlessGranted('tapi_jo.get.invoice', null, 'No access.'); - $required_params = [ - 'jo_id', - ]; - $res = $this->checkParamsAndKey($req, $em, $required_params); - if ($res->isError()) - return $res->getReturnResponse(); + $required_params = []; + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); - // 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 - // TODO: modify to 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(); + $message = 'No job order found'; + return new APIResponse(false, $message); } $invoice = $jo->getInvoice(); @@ -540,10 +516,8 @@ class JobOrderController extends APIController $data['items'] = $items_data; - // set data - $res->setData($data); - - return $res->getReturnResponse(); + $message = 'JO invoice found.'; + return new APIResponse(true, $message, $data); } public function cancelJobOrder(Request $req, MQTTClient $mclient, EntityManagerInterface $em) From 4e613e3c013cd700e3489a3d704eb38778dbebb0 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 21 Jun 2022 08:54:09 +0000 Subject: [PATCH 11/20] Add route for cancelJobOrder. Modify cancelJobOrder responses. #686 --- config/routes/tapi.yaml | 5 +++ src/Controller/TAPI/JobOrderController.php | 38 +++++----------------- 2 files changed, 14 insertions(+), 29 deletions(-) diff --git a/config/routes/tapi.yaml b/config/routes/tapi.yaml index fb343038..34d45650 100644 --- a/config/routes/tapi.yaml +++ b/config/routes/tapi.yaml @@ -16,6 +16,11 @@ tapi_jo_invoice: controller: App\Controller\TAPI\JobOrderController:getJOInvoice methods: [GET] +tapi_jo_cancel: + path: /tapi/job_order/cancel + controller: App\Controller\TAPI\JobOrderController:cancelJobOrder + methods: [POST] + # vehicle manufacturer and vehicle tapi_vehicle_mfg_list: path: /tapi/vehicle/mfgs diff --git a/src/Controller/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index 3d38efd5..5b625b5d 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -528,41 +528,21 @@ class JobOrderController extends APIController '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 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 - // TODO: modify to 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(); + $message = 'No job order found'; + return new APIResponse(false, $message); } // 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); @@ -584,10 +564,10 @@ class JobOrderController extends APIController ]; $mclient->sendRiderEvent($jo, $payload); + $data = []; + $message = 'Job order cancelled.'; - $res->setData([]); - - return $res->getReturnResponse(); + return new APIResponse(true, $message, $data); } // we can't use param converter for now because we want to output the proper 404 From 144afae551b18e53184039efffbc7f389ea20b22 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 21 Jun 2022 09:10:23 +0000 Subject: [PATCH 12/20] Add route for getJobOrderInfo. Modify the responses for getJobOrderInfo. #686 --- config/routes/tapi.yaml | 5 ++ src/Controller/TAPI/JobOrderController.php | 57 +++++++++++----------- 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/config/routes/tapi.yaml b/config/routes/tapi.yaml index 34d45650..59ec7a80 100644 --- a/config/routes/tapi.yaml +++ b/config/routes/tapi.yaml @@ -21,6 +21,11 @@ tapi_jo_cancel: controller: App\Controller\TAPI\JobOrderController:cancelJobOrder methods: [POST] +tapi_jo_info: + path: /tapi/job_order/{id}/info + controller: App\Controller\TAPI\JobOrderController::getJobOrderInfo + methods: [GET] + # vehicle manufacturer and vehicle tapi_vehicle_mfg_list: path: /tapi/vehicle/mfgs diff --git a/src/Controller/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index 5b625b5d..b5c9418c 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -53,6 +53,7 @@ use App\Entity\Hub; use App\Entity\Invoice; use App\Entity\Vehicle; use App\Entity\VehicleManufacturer; +use App\Entity\Warranty; use DateTime; use DateInterval; @@ -575,47 +576,29 @@ class JobOrderController extends APIController { $this->denyAccessUnlessGranted('tapi_jo.get.info', null, 'No access.'); - // check required parameters and api key - $res = $this->checkParamsAndKey($req, $em, []); - if ($res->isError()) - return $res->getReturnResponse(); - - // get customer - // TODO: modify to get customer - $cust = $this->session->getCustomer(); - if ($cust == null) - { - $res->setError(true) - ->setErrorMessage('No customer information found'); - return $res->getReturnResponse(); - } + // check required parameters + $required_params = []; + $msg = $this->checkRequiredParameters($req, $required_params); + if ($msg) + return new APIResponse(false, $msg); // get job order data $jo = $em->getRepository(JobOrder::class)->find($id); if ($jo == null) { - $res->setError(true) - ->setErrorMessage('No job order information found'); - return $res->getReturnResponse(); - } - - // check if job order belongs to customer / user - if ($cust->getID() != $jo->getCustomer()->getID()) - { - $res->setError(true) - ->setErrorMessage('No job order information found'); - return $res->getReturnResponse(); + $message = 'No job order information found'; + return new APIResponse(false, $message); } // put into job order data array - $jo_data = $this->generateJobOrderData($req, $jo, $rt); + $jo_data = $this->generateJobOrderData($req, $jo, $rt, $em); $data = [ 'job_order' => $jo_data ]; - $res->setData($data); - return $res->getReturnResponse(); + $message = 'Job order information found.'; + return new APIResponse(true, $message, $data); } public function getJOHistory(Request $req, EntityManagerInterface $em) @@ -930,7 +913,7 @@ class JobOrderController extends APIController return $res->getReturnResponse(); } - protected function generateJobOrderData($req, $jo, $rt) + protected function generateJobOrderData($req, $jo, $rt, $em) { $status = $jo->getStatus(); @@ -1864,6 +1847,22 @@ class JobOrderController extends APIController return $dummy_cv; } + 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'; + } + protected function cleanPhoneNumber($mobile) { // remove any non digit character from string From 2112edd4f0ef20870f1c49acf592938e69ba3861 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 21 Jun 2022 09:43:19 +0000 Subject: [PATCH 13/20] Remove getJOHistory. Add route for locationSupport. Modify responses of locationSupport. #686 --- config/api_acl.yaml | 2 - config/routes/tapi.yaml | 7 +- src/Controller/TAPI/JobOrderController.php | 167 ++------------------- 3 files changed, 17 insertions(+), 159 deletions(-) diff --git a/config/api_acl.yaml b/config/api_acl.yaml index b235ff81..c1c1067f 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -101,8 +101,6 @@ access_keys: label: Third Party Get Ongoing Job Order - id: tapi_jo.cancel label: Third Party Cancel Job Order - - id: tapi_jo.get.history - label: Third Party Get Job Order History - id: tapi_jo.get.invoice label: Third Party Get Job Order Invoice - id: tapi_jo.location.support diff --git a/config/routes/tapi.yaml b/config/routes/tapi.yaml index 59ec7a80..0c3e20c9 100644 --- a/config/routes/tapi.yaml +++ b/config/routes/tapi.yaml @@ -22,10 +22,15 @@ tapi_jo_cancel: methods: [POST] tapi_jo_info: - path: /tapi/job_order/{id}/info + path: /tapi/job_order/{jo_id}/info controller: App\Controller\TAPI\JobOrderController::getJobOrderInfo methods: [GET] +tapi_location_support: + path: /tapi/location_support + controller: App\Controller\TAPI\JobOrderController:locationSupport + methods: [POST] + # vehicle manufacturer and vehicle tapi_vehicle_mfg_list: path: /tapi/vehicle/mfgs diff --git a/src/Controller/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index b5c9418c..72ecdac1 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -601,130 +601,6 @@ class JobOrderController extends APIController return new APIResponse(true, $message, $data); } - public function getJOHistory(Request $req, EntityManagerInterface $em) - { - $this->denyAccessUnlessGranted('tapi_jo.get.history', null, 'No access.'); - - $res = $this->checkParamsAndKey($req, $em, []); - if ($res->isError()) - return $res->getReturnResponse(); - - // get customer - // TODO: modify to find 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 = []; - // get the fulfilled and cancelled job orders, since ongoing jos are not yet part of history - $jos = $em->getRepository(JobOrder::class)->findBy([ - 'customer' => $cust, - 'status' => [JOStatus::CANCELLED, JOStatus::FULFILLED] - ], ['date_schedule' => 'DESC']); - foreach ($jos as $jo) - { - // NOTE: use generateJobOrderData method, maybe? - $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(), $em); - - $jo_data['customer_vehicle'] = [ - 'id' => $cv->getID(), - 'plate_number' => $cv->getPlateNumber(), - 'warranty' => $warranty, - ]; - - // rider - $rider = $jo->getRider(); - - // check if jo has rider rating set to true - $has_rider_rating = $jo->hasRiderRating(); - $rating = 0; - $comment = ''; - if ($rider != null) - { - $jo_data['rider'] = $rider->getFullName(); - - // find the rider rating if any - if ($has_rider_rating) - { - $jo_rating = $jo->getRating(); - if ($jo_rating != null) - { - $rating = $jo_rating->getRating(); - - // get comment - $comment = $jo_rating->getComment(); - } - } - } - - // rider rating for jo - $jo_data['has_rider_rating'] = $has_rider_rating; - $jo_data['rider_rating'] = $rating; - $jo_data['comment'] = $comment; - - // invoice items - $items = []; - $jo_items = $jo->getInvoice()->getItems(); - 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(); - } - public function locationSupport(Request $req, GeofenceTracker $geo, EntityManagerInterface $em) { $this->denyAccessUnlessGranted('tapi_jo.location.support', null, 'No access.'); @@ -733,52 +609,31 @@ class JobOrderController extends APIController '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); - $long = $req->query->get('longitude'); - $lat = $req->query->get('latitude'); - - // NOTE: had to add this for promo tag - // TODO: modify to find customer if we still need this - $cust = $this->session->getCustomer(); - if ($cust == null) - { - $res->setError(true) - ->setErrorMessage('No customer information found'); - return $res->getReturnResponse(); - } + $long = $req->request->get('longitude'); + $lat = $req->request->get('latitude'); $is_covered = false; - // check if customer still has promo - if (($cust->getCustomerTag('TAG_CAR_CLUB_OFFICER_PROMO')) || - ($cust->getCustomerTag('TAG_CAR_CLUB_MEMBER_PROMO'))) - { - // if has customer tag, customer has not availed of promo - $is_covered = true; - } - else - { - // geofence - $is_covered = $geo->isCovered($long, $lat); - } + // geofence + $is_covered = $geo->isCovered($long, $lat); $data = [ 'longitude' => $long, 'latitude' => $lat, 'supported' => $is_covered, ]; - $res->setData($data); - // check if is_covered is false. If so, we need to set the error part in the response + // check if is_covered is false. If so, we need to modify the message + $message = 'Location is supported.'; if (!$is_covered) { - $res->setError(true) - ->setErrorMessage('Oops! Our service is limited to some areas in Metro Manila, Laguna, and Baguio only. We will update you as soon as we are able to cover your area'); + $message = '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(); + return new APIResponse(true, $message, $data); } // TODO: should we change to the HubSelector? From fd77f1ef627a0acb8980a6e73463583ab083c882 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 21 Jun 2022 10:08:58 +0000 Subject: [PATCH 14/20] Add route for getNearestHubAndSlots. Modify getNearestHubAndSlots. #686 --- config/routes/tapi.yaml | 5 + src/Controller/TAPI/JobOrderController.php | 124 ++++++++++++--------- 2 files changed, 77 insertions(+), 52 deletions(-) diff --git a/config/routes/tapi.yaml b/config/routes/tapi.yaml index 0c3e20c9..afa2f084 100644 --- a/config/routes/tapi.yaml +++ b/config/routes/tapi.yaml @@ -31,6 +31,11 @@ tapi_location_support: controller: App\Controller\TAPI\JobOrderController:locationSupport methods: [POST] +tapi_nearest_hub_slots: + path: /tapi/hub_slots + controller: App\Controller\TAPI\JobOrderController::getNearestHubAndSlots + methods: [POST] + # vehicle manufacturer and vehicle tapi_vehicle_mfg_list: path: /tapi/vehicle/mfgs diff --git a/src/Controller/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index 72ecdac1..4b1e6684 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -647,57 +647,18 @@ class JobOrderController extends APIController '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')); + $coordinates = new Point($req->request->get('longitude'), $req->request->get('latitude')); - // add checking if customer has a pre-registered hub - // TODO: modify how we get customer - $cust = $this->session->getCustomer(); - if ($cust == null) + $nearest_hub_slots = $this->findAdvanceNearestHubAndSlots($coordinates, $em, $map_tools); + + if (empty($nearest_hub_slots['hub'])) { - $res->setError(true) - ->setErrorMessage('No customer information found'); - return $res->getReturnResponse(); - } - - // check if customer has customer tag promo - // TODO: do we still need this? - if (($cust->getCustomerTag('TAG_CAR_CLUB_OFFICER_PROMO')) || - ($cust->getCustomerTag('TAG_CAR_CLUB_MEMBER_PROMO'))) - { - // if has customer tag, customer has not availed of promo, get the hub where customer is pre-registered - $car_club_cust_hub = $cust->getCarClubCustomerHub(); - if ($car_club_cust_hub != null) - { - // need to get the rider slots for the pre-registered hub - $hub = $car_club_cust_hub->getHub(); - $nearest_hub_slots = $this->findAdvanceNearestHubAndSlots($coordinates, $em, $map_tools, $hub); - } - else - { - $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. Please expect a call from us and we will assist you with your request. Thank you and stay safe!'); - return $res->getReturnResponse(); - } - } - } - else - { - $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. Please expect a call from us and we will assist you with your request. Thank you and stay safe!'); - return $res->getReturnResponse(); - } + $message = 'Thank you for reaching out to us. Please expect a call from us and we will assist you with your request. Thank you and stay safe!'; + return new APIResponse (false, $message); } // make hub data @@ -706,9 +667,9 @@ class JobOrderController extends APIController 'hub_slots' => $nearest_hub_slots['slots'], ]; - $res->setData($data); + $message = 'Nearest hub and slots found.'; - return $res->getReturnResponse(); + return new APIResponse(true, $message, $data); } public function scheduleOptionStatus(Request $req, EntityManagerInterface $em) @@ -1146,6 +1107,56 @@ class JobOrderController extends APIController return $hub_slots; } + protected function generateHubSlots($rider_slots, $slots) + { + $data = []; + $total_rslots = 0; + $total_unavailable_rslots = 0; + foreach ($rider_slots as $day_id => $rslot) + { + $data[$day_id] = []; + + foreach ($rslot as $slot_id => $avail_slots) + { + // increment total rider slots + $total_rslots++; + + $slot_data = [ + 'id' => $slot_id, + 'label' => $slots[$slot_id], + 'available' => true, + ]; + + // mark unavailable ones + if ($avail_slots <= 0) + { // increment total number of unavailable slots + $total_unavailable_rslots++; + $slot_data['available'] = false; + } + + // add to day data + $data[$day_id][] = $slot_data; + } + } + + // check if hub has available slots + $hub_available = true; + // error_log('total rider slots ' . $total_rslots); + // error_log('total unavailable slots ' . $total_unavailable_rslots); + if ($total_rslots == $total_unavailable_rslots) + { + // error_log('hub has no available slots'); + $hub_available = false; + } + + $hs_data = [ + 'flag_hub_available' => $hub_available, + 'slot_data' => $data, + ]; + + return $hs_data; + } + protected function getTimeFromSlot($slot_id) { $time_selected = ''; @@ -1264,11 +1275,20 @@ class JobOrderController extends APIController $hub = $em->getRepository(Hub::class)->find($hub_id); $schedule_date = $r->get('date_schedule'); + $slot_id = $r->get('slot_id'); // process the jo date schedule $date_schedule = null; - if (strlen($schedule_date) > 0) - $date_schedule = DateTime::createFromFormat('Y-m-d H:i', $schedule_date); + 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')); + } + } // get promo $promo_id = $r->get('promo_id', 0); From bbb562d36600611b30589197a10a821c510b2990 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Tue, 21 Jun 2022 10:16:48 +0000 Subject: [PATCH 15/20] Comment out scheduleOptionStatus. #686 --- src/Controller/TAPI/JobOrderController.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Controller/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index 4b1e6684..a18a3037 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -672,6 +672,8 @@ class JobOrderController extends APIController return new APIResponse(true, $message, $data); } + // comment out for now + /* public function scheduleOptionStatus(Request $req, EntityManagerInterface $em) { $this->denyAccessUnlessGranted('tapi_jo.schedule_option.status', null, 'No access.'); @@ -728,6 +730,7 @@ class JobOrderController extends APIController return $res->getReturnResponse(); } + */ protected function generateJobOrderData($req, $jo, $rt, $em) { From accd6fd0f6466f65d8eb2c8a763543887c9aa9b6 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 23 Jun 2022 07:57:24 +0000 Subject: [PATCH 16/20] Add validation for model year. #686 --- src/Controller/TAPI/JobOrderController.php | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/Controller/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index a18a3037..ade44e63 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -1467,6 +1467,33 @@ class JobOrderController extends APIController return $message; } + // check model year + // (1) if empty + // (2) if numeric + // (2)if it falls between a range of years + $model_year = $r->get('vehicle_model_year'); + if (empty($model_year)) + { + $message = 'Vehicle model year is empty.'; + return $message; + } + if (!is_numeric($model_year)) + { + $message = 'Invalid model year. Not a number.'; + return $message; + } + + $year_options = $this->generateYearOptions(); + // get first and last element + $first_year = $year_options[0]; + $last_year = end($year_options); + if (($model_year < $first_year) || + ($model_year > $last_year)) + { + $message = 'Invalid model year.'; + return $message; + } + // confirm that vehicle model's manufacturer is the same as the one in vehicle if ($vmodel->getManufacturer()->getID() != $vmanu_id) { @@ -1777,5 +1804,11 @@ class JobOrderController extends APIController { return strtolower(trim($name)); } + + protected function generateYearOptions() + { + $start_year = 1950; + return range($start_year, date("Y") + 1); + } } From 470dd47195f0f9f012ecd6a255fbb2312f3389e5 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 23 Jun 2022 08:23:34 +0000 Subject: [PATCH 17/20] Add DeliveryStatus to JobOrderController. #686 --- src/Controller/TAPI/JobOrderController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Controller/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index ade44e63..1fdad49c 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -28,6 +28,7 @@ use App\Ramcar\ModeOfPayment; use App\Ramcar\APIRiderStatus; use App\Ramcar\VehicleStatusCondition; use App\Ramcar\FuelType; +use App\Ramcar\DeliveryStatus; use App\Service\InvoiceGeneratorInterface; use App\Service\RisingTideGateway; From 06a2a887ef82d1de45370f3639b9df566beb6578 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 23 Jun 2022 08:46:50 +0000 Subject: [PATCH 18/20] Fix cleaning of mobile number. #686 --- src/Controller/TAPI/JobOrderController.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Controller/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index 1fdad49c..943ac340 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -1777,7 +1777,9 @@ class JobOrderController extends APIController // does it fit our 09XXXXXXXXX pattern? if (preg_match('/^09[0-9]{9}$/', $clean_number)) { - return $clean_number; + // strip the 0 + $c_number = substr($clean_number, 0, 1); + return $c_number; } // does it fit our 9XXXXXXXXX pattern? else if (preg_match('/^9[0-9]{9}$/', $clean_number)) From ee44dfb44e95da5085dcd0725a4bf5f75f065b15 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 23 Jun 2022 09:02:56 +0000 Subject: [PATCH 19/20] Fix cleaning of mobile number. #686 --- src/Controller/TAPI/JobOrderController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Controller/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index 943ac340..88924699 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -1778,7 +1778,7 @@ class JobOrderController extends APIController if (preg_match('/^09[0-9]{9}$/', $clean_number)) { // strip the 0 - $c_number = substr($clean_number, 0, 1); + $c_number = substr($clean_number, 1); return $c_number; } // does it fit our 9XXXXXXXXX pattern? @@ -1790,7 +1790,7 @@ class JobOrderController extends APIController else if (preg_match('/^63[0-9]{10}$/', $clean_number)) { // strip the 63 since we don't save the country code - $c_number = substr($clean_number, 0, 2); + $c_number = substr($clean_number, 2); return $c_number; } From 3910db88f0e875ddb64d3ed70b2649213221bfbb Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 23 Jun 2022 09:39:25 +0000 Subject: [PATCH 20/20] Fix parameter issue for getJobOrderInfo. #686 --- src/Controller/TAPI/JobOrderController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Controller/TAPI/JobOrderController.php b/src/Controller/TAPI/JobOrderController.php index 88924699..d22a8725 100644 --- a/src/Controller/TAPI/JobOrderController.php +++ b/src/Controller/TAPI/JobOrderController.php @@ -573,7 +573,7 @@ class JobOrderController extends APIController } // we can't use param converter for now because we want to output the proper 404 - public function getJobOrderInfo($id, Request $req, EntityManagerInterface $em, RiderTracker $rt) + public function getJobOrderInfo($jo_id, Request $req, EntityManagerInterface $em, RiderTracker $rt) { $this->denyAccessUnlessGranted('tapi_jo.get.info', null, 'No access.'); @@ -584,7 +584,7 @@ class JobOrderController extends APIController return new APIResponse(false, $msg); // get job order data - $jo = $em->getRepository(JobOrder::class)->find($id); + $jo = $em->getRepository(JobOrder::class)->find($jo_id); if ($jo == null) { $message = 'No job order information found';