session = null; } protected function checkMissingParameters(Request $req, $params = []) { $missing = []; // check if parameters are there foreach ($params as $param) { if ($req->getMethod() == 'GET') { $check = $req->query->get($param); if ($check == null) $missing[] = $param; } else if ($req->getMethod() == 'POST') { $check = $req->request->get($param); if ($check == null) $missing[] = $param; } else return $params; } return $missing; } // TODO: type hint entity manager protected function checkAPIKey($em, $api_key) { // find the api key (session id) $session = $em->getRepository(RiderSession::class)->find($api_key); if ($session == null) return null; return $session; } protected function checkParamsAndKey(Request $req, $em, $params) { // returns APIResult object $res = new APIResult(); // check for api_key in query string $api_key = $req->query->get('api_key'); if (empty($api_key)) { $res->setError(true) ->setErrorMessage('Missing API key'); return $res; } // check missing parameters $missing = $this->checkMissingParameters($req, $params); if (count($missing) > 0) { $miss_string = implode(', ', $missing); $res->setError(true) ->setErrorMessage('Missing parameter(s): ' . $miss_string); return $res; } // check api key $sess = $this->checkAPIKey($em, $req->query->get('api_key')); if ($sess == null) { $res->setError(true) ->setErrorMessage('Invalid API Key'); return $res; } // store session $this->session = $sess; return $res; } public function register(Request $req, RiderAPIHandlerInterface $rapi_handler) { $res = new APIResult(); $data = $rapi_handler->register($req); if (isset($data['error'])) { $message = $data['error']; $res->setError(true) ->setErrorMessage($message); } else { $res->setData($data); } // response return $res->getReturnResponse(); } public function login(Request $req, RiderAPIHandlerInterface $rapi_handler) { $res = new APIResult(); $data = $rapi_handler->login($req); if (isset($data['error'])) { $message = $data['error']; $res->setError(true) ->setErrorMessage($message); } else { $res->setData($data); } // response return $res->getReturnResponse(); } public function logout(Request $req, RiderAPIHandlerInterface $rapi_handler) { $res = new APIResult(); $data = $rapi_handler->logout($req); if (isset($data['error'])) { $message = $data['error']; $res->setError(true) ->setErrorMessage($message); } else { $res->setData($data); } // response return $res->getReturnResponse(); } public function getJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) { $res = new APIResult(); $data = $rapi_handler->getJobOrder($req); if (isset($data['error'])) { $message = $data['error']; $res->setError(true) ->setErrorMessage($message); } else { $res->setData($data); } // response return $res->getReturnResponse(); } protected function checkJO(Request $req, $required_params, &$jo = null) { // set jo status to in transit $em = $this->getDoctrine()->getManager(); $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res; // are we logged in? if (!$this->session->hasRider()) { $res->setError(true) ->setErrorMessage('No logged in rider.'); return $res; } $rider = $this->session->getRider(); // check if we have an active JO $jo = $rider->getActiveJobOrder(); if ($jo == null) { $res->setError(true) ->setErrorMessage('No active job order.'); return $res; } // check if the jo_id sent is the same as our active jo if ($req->request->get('jo_id') != $jo->getID()) { $res->setError(true) ->setErrorMessage('Job order selected is not active job order.'); return $res; } return $res; } public function acceptJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) { $res = new APIResult(); $data = $rapi_handler->acceptJobOrder($req); if (isset($data['error'])) { $message = $data['error']; $res->setError(true) ->setErrorMessage($message); } else { $res->setData($data); } // response return $res->getReturnResponse(); } public function cancelJobOrder(Request $req, RiderAPIHandlerInterface $rapi_handler) { $res = new APIResult(); $data = $rapi_handler->cancelJobOrder($req); if (isset($data['error'])) { $message = $data['error']; $res->setError(true) ->setErrorMessage($message); } else { $res->setData($data); } // response return $res->getReturnResponse(); } public function arrive(Request $req, RiderAPIHandlerInterface $rapi_handler) { $res = new APIResult(); $data = $rapi_handler->arrive($req); if (isset($data['error'])) { $message = $data['error']; $res->setError(true) ->setErrorMessage($message); } else { $res->setData($data); } // response return $res->getReturnResponse(); } public function hubArrive(Request $req, RiderAPIHandlerInterface $rapi_handler) { $res = new APIResult(); $data = $rapi_handler->hubArrive($req); if (isset($data['error'])) { $message = $data['error']; $res->setError(true) ->setErrorMessage($message); } else { $res->setData($data); } // response return $res->getReturnResponse(); } public function payment(Request $req, MQTTClient $mclient, WarrantyHandler $wh) { $em = $this->getDoctrine()->getManager(); $required_params = ['jo_id']; $res = $this->checkJO($req, $required_params, $jo); if ($res->isError()) return $res->getReturnResponse(); // set invoice to paid $jo->getInvoice()->setStatus(InvoiceStatus::PAID); /* // set jo status to fulfilled $jo->setStatus(JOStatus::FULFILLED); */ $jo->fulfill(); // add event log $rider = $this->session->getRider(); $event = new JOEvent(); $event->setDateHappen(new DateTime()) ->setTypeID(JOEventType::FULFILL) ->setJobOrder($jo) ->setRider($rider); $em->persist($event); // TODO: tag rider as unavailable // save to customer vehicle battery record // TODO: this has to move to JOHandler $this->updateVehicleBattery($jo); $em->flush(); // create warranty if (($jo->getServiceType() == ServiceType::BATTERY_REPLACEMENT_NEW) || ($jo->getServiceType() == CMBServiceType::BATTERY_REPLACEMENT_NEW)) { $serial = null; $warranty_class = $jo->getWarrantyClass(); $first_name = $jo->getCustomer()->getFirstName(); $last_name = $jo->getCustomer()->getLastName(); $mobile_number = $jo->getCustomer()->getPhoneMobile(); // check if date fulfilled is null if ($jo->getDateFulfill() == null) $date_purchase = $jo->getDateCreate(); else $date_purchase = $jo->getDateFulfill(); $plate_number = $wh->cleanPlateNumber($jo->getCustomerVehicle()->getPlateNumber()); $batt_list = array(); $invoice = $jo->getInvoice(); if (!empty($invoice)) { // get battery $invoice_items = $invoice->getItems(); foreach ($invoice_items as $item) { $battery = $item->getBattery(); if ($battery != null) { $batt_list[] = $item->getBattery(); } } } $wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class); } // send mqtt event (fulfilled) $rider = $this->session->getRider(); $image_url = $req->getScheme() . '://' . $req->getHttpHost() . $req->getBasePath() . '/assets/images/user.gif'; if ($rider->getImageFile() != null) $image_url = $req->getScheme() . '://' . $req->getHttpHost() . $req->getBasePath() . '/uploads/' . $rider->getImageFile(); $payload = [ 'event' => 'fulfilled', 'jo_id' => $jo->getID(), 'driver_image' => $image_url, 'driver_name' => $rider->getFullName(), 'driver_id' => $rider->getID(), ]; $mclient->sendEvent($jo, $payload); return $res->getReturnResponse(); } public function available(Request $req) { $em = $this->getDoctrine()->getManager(); $required_params = []; $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res->getReturnResponse(); // make rider available $this->session->getRider()->setAvailable(true); // TODO: log rider available $em->flush(); return $res->getReturnResponse(); } public function getPromos(Request $req) { $em = $this->getDoctrine()->getManager(); $required_params = []; $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res->getReturnResponse(); $promos = $em->getRepository(Promo::class)->findAll(); $promo_data = []; foreach ($promos as $promo) { $promo_data[] = [ 'id' => $promo->getID(), 'name' => $promo->getName(), 'code' => $promo->getCode(), ]; } $data = [ 'promos' => $promo_data, ]; $res->setData($data); return $res->getReturnResponse(); } public function getBatteries(Request $req) { // get batteries, models, and sizes $em = $this->getDoctrine()->getManager(); $required_params = []; $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res->getReturnResponse(); $batts = $em->getRepository(Battery::class)->findAll(); $models = $em->getRepository(BatteryModel::class)->findAll(); $sizes = $em->getRepository(BatterySize::class)->findAll(); $batt_data = []; foreach ($batts as $batt) { $batt_data[] = [ 'id' => $batt->getID(), 'model_id' => $batt->getModel()->getID(), 'size_id' => $batt->getSize()->getID(), 'sell_price' => $batt->getSellingPrice(), ]; } $model_data = []; foreach ($models as $model) { $model_data[] = [ 'id' => $model->getID(), 'name' => $model->getName(), ]; } $size_data = []; foreach ($sizes as $size) { $size_data[] = [ 'id' => $size->getID(), 'name' => $size->getName(), ]; } $data = [ 'batteries' => $batt_data, 'models' => $model_data, 'sizes' => $size_data, ]; $res->setData($data); return $res->getReturnResponse(); } protected function debugRequest(Request $req) { $all = $req->request->all(); error_log(print_r($all, true)); } public function changeService(Request $req, InvoiceGeneratorInterface $ic) { $this->debugRequest($req); // allow rider to change service, promo, battery and trade-in options $em = $this->getDoctrine()->getManager(); $required_params = ['jo_id', 'stype_id', 'promo_id']; $res = $this->checkJO($req, $required_params, $jo); if ($res->isError()) return $res->getReturnResponse(); // check service type $stype_id = $req->request->get('stype_id'); if ((!CMBServiceType::validate($stype_id)) || (!ServiceType::validate($stype_id))) { $res->setError(true) ->setErrorMessage('Invalid service type - ' . $stype_id); return $res->getReturnResponse(); } // check promo id $promo_id = $req->request->get('promo_id'); // no promo if ($promo_id == 0) $promo = null; else { $promo = $em->getRepository(Promo::class)->find($promo_id); if ($promo == null) { $res->setError(true) ->setErrorMessage('Invalid promo id - ' . $promo_id); return $res->getReturnResponse(); } } // check or number $or_num = $req->request->get('or_num'); if ($or_num != null) $jo->setORNum($or_num); // coolant $flag_coolant = $req->request->get('flag_coolant', 'false'); if ($flag_coolant == 'true') $jo->setHasCoolant(true); else $jo->setHasCoolant(false); // has motolite battery $cv = $jo->getCustomerVehicle(); $has_motolite = $req->request->get('has_motolite', 'false'); if ($has_motolite == 'true') $cv->setHasMotoliteBattery(true); else $cv->setHasMotoliteBattery(false); $em->persist($cv); // check battery id $batt_id = $req->request->get('batt_id', null); // no battery if ($batt_id == 0 || $batt_id == null) $battery = null; else { $battery = $em->getRepository(Battery::class)->find($batt_id); if ($battery == null) { $res->setError(true) ->setErrorMessage('Invalid battery id - ' . $batt_id); return $res->getReturnResponse(); } } // check trade in $trade_in = $req->request->get('trade_in'); if ((!CMBTradeInType::validate($trade_in)) || (!TradeInType::validate($trade_in))) $trade_in = null; // check mode of payment $mode = $req->request->get('mode_of_payment'); if (!ModeOfPayment::validate($mode)) $mode = ModeOfPayment::CASH; $jo->setModeOfPayment($mode); // generate new invoice $crit = new InvoiceCriteria(); $crit->setServiceType($stype_id); $crit->setCustomerVehicle($cv); $crit->setHasCoolant($jo->hasCoolant()); if ($promo != null) $crit->addPromo($promo); if ($battery != null) { $crit->addEntry($battery, $trade_in, 1); error_log('adding entry for battery - ' . $battery->getID()); } $invoice = $ic->generateInvoice($crit); // remove previous invoice $old_invoice = $jo->getInvoice(); $em->remove($old_invoice); $em->flush(); // save job order $jo->setServiceType($stype_id); // save invoice $jo->setInvoice($invoice); $em->persist($invoice); // add event log $rider = $this->session->getRider(); $event = new JOEvent(); $event->setDateHappen(new DateTime()) ->setTypeID(JOEventType::RIDER_EDIT) ->setJobOrder($jo) ->setRider($rider); $em->persist($event); $em->flush(); // TODO: send mqtt event (?) return $res->getReturnResponse(); } protected function updateVehicleBattery(JobOrder $jo) { // check if new battery if (($jo->getServiceType() != ServiceType::BATTERY_REPLACEMENT_NEW) || ($jo->getServiceType() != CMBServiceType::BATTERY_REPLACEMENT_NEW)) return; // customer vehicle $cv = $jo->getCustomerVehicle(); if ($cv == null) return; // invoice $invoice = $jo->getInvoice(); if ($invoice == null) return; // invoice items $items = $invoice->getItems(); if (count($items) <= 0) return; // get first battery from invoice $battery = null; foreach ($items as $item) { $battery = $item->getBattery(); if ($battery != null) break; } // no battery in order if ($battery == null) return; // warranty expiration $warr_months = 0; $warr = $jo->getWarrantyClass(); if ($warr == WarrantyClass::WTY_PRIVATE) $warr_months = $battery->getWarrantyPrivate(); else if ($warr == WarrantyClass::WTY_COMMERCIAL) $warr_months = $battery->getWarrantyCommercial(); else if ($warr == WarrantyClass::WTY_TNV) $warr_months = 12; $warr_date = new DateTime(); $warr_date->add(new DateInterval('P' . $warr_months . 'M')); // update customer vehicle battery $cv->setCurrentBattery($battery) ->setHasMotoliteBattery(true) ->setWarrantyExpiration($warr_date); } }