checkMissingParameters($req, $required_params); if (count($missing) > 0) { $params = implode(', ', $missing); return new APIResponse(false, 'Missing parameter(s): ' . $params); } // get capi user to link to rider api user $capi_user_id = $this->getUser()->getID(); // check if capi user already has a rider api session $rapi_session = $em->getRepository(RiderAPISession::class)->findOneBy(['capi_user_id' => $capi_user_id]); if ($rapi_session != null) return new APIResponse(false, 'User already registered'); // retry until we get a unique id while (true) { try { // instantiate session $sess = new RiderAPISession(); $sess->setPhoneNumber($req->request->get('phone_number')) ->setDevicePushID($req->request->get('device_push_id')) ->setCapiUserId($capi_user_id); // reopen in case we get an exception if (!$em->isOpen()) { $em = $em->create( $em->getConnection(), $em->getConfiguration() ); } // save $em->persist($sess); $em->flush(); // create redis entry for the session $redis_client = $redis->getRedisClient(); $redis_key = 'rider.id.' . $sess->getID(); error_log('redis_key: ' . $redis_key); $redis_client->set($redis_key, ''); } catch (DBALException $e) { error_log($e->getMessage()); // delay one second and try again sleep(1); continue; } break; } // return data $data = [ 'session_id' => $sess->getID() ]; return new APIResponse(true, 'Rider API user created.', $data); } */ public function login(Request $req, EntityManagerInterface $em, EncoderFactoryInterface $ef, RiderCache $rcache, RiderTracker $rider_tracker, MQTTClient $mclient, RedisClientProvider $redis) { $required_params = [ 'user', 'pass', ]; $missing = $this->checkMissingParameters($req, $required_params); if (count($missing) > 0) { $params = implode(', ', $missing); return new APIResponse(false, 'Missing parameter(s): ' . $params); } // NOTE: we retain the username and password in rider for backward compatibility // look for rider with username $rider = $em->getRepository(Rider::class)->findOneBy(['username' => $req->request->get('user')]); if ($rider == null) return new APIResponse(false, 'Invalid username or password.'); // check if rider password is correct // NOTE: we use $encoder = $ef->getEncoder(new User()); if (!$encoder->isPasswordValid($rider->getPassword(), $req->request->get('pass'), '')) return new APIResponse(false, 'Invalid username or password.'); // user will be the one linked to the rider $user = $rider->getAPIUser(); // no linked user, cannot login if ($user == null) return new APIResponse(false, 'Rider cannot login, no associated user.'); // set rider to available $rider->setAvailable(true); $rider_id = $rider->getID(); // cache rider location (default to hub) // TODO: figure out longitude / latitude default $rcache->addActiveRider($rider_id, 0, 0); // send mqtt event to put rider on map // get rider coordinates from redis $coord = $rider_tracker->getRiderLocation($rider->getID()); $lng = $coord->getLongitude(); $lat = $coord->getLatitude();; $channel = 'rider/' . $rider->getID() . '/availability'; $payload = [ 'status' => 'rider_online', 'longitude' => $lng, 'latitude' => $lat, ]; $mclient->publish($channel, json_encode($payload)); // TODO: log rider logging in $em->flush(); // NOTE; commenting this out since this doesn't seem to be needed. // this is being set in utils/mqtt_rider_convert/mqtt_rider_convert.py // update redis rider.id. with the rider id //$redis_client = $redis->getRedisClient(); //$redis_key = 'rider.id.' . $rapi_session->getID(); //$rider_id = $rider->getID(); //$redis_client->set($redis_key, $rider_id); $rider_id = $rider->getID(); $hub = $rider->getHub(); if ($hub == null) $hub_data = null; else { $coord = $hub->getCoordinates(); $hub_data = [ 'id' => $hub->getID(), 'name' => $hub->getName(), 'branch' => $hub->getBranch(), 'longitude' => $coord->getLongitude(), 'latitude' => $coord->getLatitude(), 'contact_nums' => $hub->getContactNumbers(), ]; } // data $data = [ 'hub' => $hub_data, 'rider_id' => $rider_id, 'api_key' => $user->getAPIKey(), 'secret_key' => $user->getSecretKey(), ]; return new APIResponse(true, 'Rider logged in.', $data); } public function logout(Request $req, EntityManagerInterface $em, RiderCache $rcache, MQTTClient $mclient) { $required_params = []; $missing = $this->checkMissingParameters($req, $required_params); if (count($missing) > 0) { $params = implode(', ', $missing); return new APIResponse(false, 'Missing parameter(s): ' . $params); } // get capi user $capi_user = $this->getUser(); if ($capi_user == null) return new APIResponse(false, 'User not found.'); // get rider id from capi user metadata $rider = $this->getRiderFromCAPI($capi_user, $em); if ($rider == null) return new APIResponse(false, 'No rider found.'); // make rider unavailable $rider->setAvailable(false); // remove from cache $rcache->removeActiveRider($rider->getID()); // TODO: log rider logging out $em->flush(); // send mqtt event to remove rider from map $channel = 'rider/' . $rider->getID() . '/availability'; $payload = [ 'status' => 'rider_offline' ]; $mclient->publish($channel, json_encode($payload)); $data = []; return new APIResponse(true, 'Rider logged out', $data); } public function getJobOrder(Request $req, EntityManagerInterface $em) { // get the job order of the rider assigned to this session $required_params = []; $missing = $this->checkMissingParameters($req, $required_params); if (count($missing) > 0) { $params = implode(', ', $missing); return new APIResponse(false, 'Missing parameter(s): ' . $params); } // get capi user $capi_user = $this->getUser(); if ($capi_user == null) return new APIResponse(false, 'User not found.'); // get rider id from capi user metadata $rider = $this->getRiderFromCAPI($capi_user, $em); if ($rider == null) return new APIResponse(false, 'No rider found.'); // do we have a job order? // $jo = $rider->getActiveJobOrder(); $jo = $rider->getCurrentJobOrder(); if ($jo == null) { $data = [ 'job_order' => null ]; } else { $coord = $jo->getCoordinates(); $cust = $jo->getCustomer(); $cv = $jo->getCustomerVehicle(); $v = $cv->getVehicle(); $inv = $jo->getInvoice(); $promo = $inv->getPromo(); // invoice items $inv_items = []; foreach ($inv->getItems() as $item) { $item_batt = $item->getBattery(); if ($item_batt == null) $batt_id = null; else $batt_id = $item_batt->getID(); $inv_items[] = [ 'id' => $item->getID(), 'title' => $item->getTitle(), 'qty' => $item->getQuantity(), 'price' => $item->getPrice(), 'batt_id' => $batt_id, ]; } // promo if ($promo != null) { $promo_data = [ 'id' => $promo->getID(), 'name' => $promo->getName(), 'code' => $promo->getCode(), 'discount_rate' => $promo->getDiscountRate(), 'discount_apply' => $promo->getDiscountApply(), ]; } else { $promo_data = null; } $trade_in_type = $jo->getTradeInType(); if (empty($trade_in_type)) $trade_in_type = 'none'; $data = [ 'job_order' => [ 'id' => $jo->getID(), 'service_type' => $jo->getServiceType(), 'date_schedule' => $jo->getDateSchedule()->format('Ymd H:i:s'), 'longitude' => $coord->getLongitude(), 'latitude' => $coord->getLatitude(), 'status' => $jo->getStatus(), 'customer' => [ 'title' => $cust->getTitle(), 'first_name' => $cust->getFirstName(), 'last_name' => $cust->getLastName(), 'phone_mobile' => $this->getParameter('country_code') . $cust->getPhoneMobile(), ], 'vehicle' => [ 'manufacturer' => $v->getManufacturer()->getName(), 'make' => $v->getMake(), 'model' => $cv->getModelYear(), 'plate_number' => $cv->getPlateNumber(), 'color' => $cv->getColor(), ], 'or_num' => $jo->getORNum(), 'or_name' => $jo->getORName(), 'delivery_instructions' => $jo->getDeliveryInstructions(), 'delivery_address' => $jo->getDeliveryAddress(), 'landmark' => $jo->getLandmark(), 'invoice' => [ 'discount' => $inv->getDiscount(), 'trade_in' => $inv->getTradeIn(), 'total_price' => $inv->getTotalPrice(), 'vat' => $inv->getVat(), 'items' => $inv_items, ], 'mode_of_payment' => $jo->getModeOfPayment(), 'trade_in_type' => $trade_in_type, 'promo' => $promo_data, // TODO: load the actual 'has_warranty_doc' => false, 'flag_coolant' => $jo->hasCoolant(), 'has_motolite' => $cv->hasMotoliteBattery(), 'delivery_status' => $jo->getDeliveryStatus(), ] ]; } return new APIResponse(true, 'Job order found.', $data); } public function acceptJobOrder(Request $req, EntityManagerInterface $em) { $required_params = ['jo_id']; // get capi user $capi_user = $this->getUser(); if ($capi_user == null) return new APIResponse(false, 'User not found.'); // get rider id from capi user metadata $rider = $this->getRiderFromCAPI($capi_user, $em); if ($rider == null) return new APIResponse(false, 'No rider found.'); $msg = $this->checkJO($req, $required_params, $jo, $rider); if (!empty($msg)) return new APIResponse(false, $msg); // TODO: refactor this into a jo handler class, so we don't have to repeat for control center // set jo status to in transit $jo->setStatus(JOStatus::IN_TRANSIT); // set delivery status $jo->setDeliveryStatus(DeliveryStatus::RIDER_ACCEPT); // TODO: send mqtt event (?) // set rider's current job order $rider->setCurrentJobOrder($jo); // set rider to unavailable $rider->setAvailable(false); // add event log $event = new JOEvent(); $event->setDateHappen(new DateTime()) ->setTypeID(JOEventType::RIDER_ACCEPT) ->setJobOrder($jo) ->setRider($rider); $em->persist($event); $em->flush(); $data = []; return new APIResponse(true, 'Job order accepted.', $data); } public function cancelJobOrder(Request $req, EntityManagerInterface $em, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient) { $required_params = ['jo_id']; // get capi user $capi_user = $this->getUser(); if ($capi_user == null) return new APIResponse(false, 'User not found.'); // get rider id from capi user metadata $rider = $this->getRiderFromCAPI($capi_user, $em); if ($rider == null) return new APIResponse(false, 'No rider found.'); $msg = $this->checkJO($req, $required_params, $jo, $rider); if (!empty($msg)) // TODO: this is a workaround for requeue, because rider app gets stuck in accept / decline screen return new APIResponse(true, $msg); // requeue it, instead of cancelling it $jo->requeue(); // set delivery status to requeued $jo->setDeliveryStatus(DeliveryStatus::REQUEUE); // set rider's current job order to null $rider->setCurrentJobOrder(); // add event log $event = new JOEvent(); $event->setDateHappen(new DateTime()) ->setTypeID(JOEventType::REQUEUE) ->setJobOrder($jo) ->setRider($rider); $em->persist($event); $em->flush(); // send mqtt event // send outlet assign since order should go back to hub and await reassignment to another rider $payload = [ 'event' => 'outlet_assign', 'jo_id' => $jo->getID(), ]; $mclient->sendEvent($jo, $payload); // NOTE: for resq2 app $mclientv2->sendEvent($jo, $payload); $fcmclient->sendJoEvent($jo, "jo_fcm_title_outlet_assign", "jo_fcm_body_outlet_assign"); $data = []; return new APIResponse(true, 'Job order requeued.', $data); } public function hubDepart(Request $req, EntityManagerInterface $em) { $required_params = []; $missing = $this->checkMissingParameters($req, $required_params); if (count($missing) > 0) { $params = implode(', ', $missing); return new APIResponse(false, 'Missing parameter(s): ' . $params); } // get capi user $capi_user = $this->getUser(); if ($capi_user == null) return new APIResponse(false, 'User not found.'); // get rider id from capi user metadata $rider = $this->getRiderFromCAPI($capi_user, $em); if ($rider == null) return new APIResponse(false, 'No rider found.'); // get rider's current job order $jo = $rider->getCurrentJobOrder(); // set delivery status $jo->setDeliveryStatus(DeliveryStatus::RIDER_DEPART_HUB); // create time stamp event for JO event $event = new JOEvent(); $event->setDateHappen(new DateTime()) ->setTypeID(JOEventType::RIDER_DEPART_HUB) ->setJobOrder($jo) ->setRider($rider); $em->persist($event); $em->flush(); $data = []; return new APIResponse(true, 'Rider leave hub.', $data); } public function preHubArrive(Request $req, EntityManagerInterface $em) { $required_params = []; $missing = $this->checkMissingParameters($req, $required_params); if (count($missing) > 0) { $params = implode(', ', $missing); return new APIResponse(false, 'Missing parameter(s): ' . $params); } // get capi user $capi_user = $this->getUser(); if ($capi_user == null) return new APIResponse(false, 'User not found.'); // get rider id from capi user metadata $rider = $this->getRiderFromCAPI($capi_user, $em); if ($rider == null) return new APIResponse(false, 'No rider found.'); // get rider's current job order $jo = $rider->getCurrentJobOrder(); // set delivery status $jo->setDeliveryStatus(DeliveryStatus::RIDER_ARRIVE_HUB_PRE_JO); // create time stamp event for JO event $event = new JOEvent(); $event->setDateHappen(new DateTime()) ->setTypeID(JOEventType::RIDER_ARRIVE_HUB_PRE_JO) ->setJobOrder($jo) ->setRider($rider); $em->persist($event); $em->flush(); $data = []; return new APIResponse(true, 'Rider arrive at hub pre jo.', $data); } public function preHubDepart(Request $req, EntityManagerInterface $em) { $required_params = []; $missing = $this->checkMissingParameters($req, $required_params); if (count($missing) > 0) { $params = implode(', ', $missing); return new APIResponse(false, 'Missing parameter(s): ' . $params); } // get capi user $capi_user = $this->getUser(); if ($capi_user == null) return new APIResponse(false, 'User not found.'); // get rider id from capi user metadata $rider = $this->getRiderFromCAPI($capi_user, $em); if ($rider == null) return new APIResponse(false, 'No rider found.'); // get rider's current job order $jo = $rider->getCurrentJobOrder(); // set delivery status $jo->setDeliveryStatus(DeliveryStatus::RIDER_DEPART_HUB_PRE_JO); // create time stamp event for JO event $event = new JOEvent(); $event->setDateHappen(new DateTime()) ->setTypeID(JOEventType::RIDER_DEPART_HUB_PRE_JO) ->setJobOrder($jo) ->setRider($rider); $em->persist($event); $em->flush(); $data = []; return new APIResponse(true, 'Rider depart from hub pre jo.', $data); } public function startJobOrder(Request $req, EntityManagerInterface $em) { $required_params = []; $missing = $this->checkMissingParameters($req, $required_params); if (count($missing) > 0) { $params = implode(', ', $missing); return new APIResponse(false, 'Missing parameter(s): ' . $params); } // get capi user $capi_user = $this->getUser(); if ($capi_user == null) return new APIResponse(false, 'User not found.'); // get rider id from capi user metadata $rider = $this->getRiderFromCAPI($capi_user, $em); if ($rider == null) return new APIResponse(false, 'No rider found.'); // get rider's current job order $jo = $rider->getCurrentJobOrder(); // set delivery status $jo->setDeliveryStatus(DeliveryStatus::RIDER_START); // create time stamp event for JO event $event = new JOEvent(); $event->setDateHappen(new DateTime()) ->setTypeID(JOEventType::RIDER_START) ->setJobOrder($jo) ->setRider($rider); $em->persist($event); $em->flush(); $data = []; return new APIResponse(true, 'Rider start job order.', $data); } public function arrive(Request $req, EntityManagerInterface $em, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient) { $required_params = ['jo_id']; // get capi user $capi_user = $this->getUser(); if ($capi_user == null) return new APIResponse(false, 'User not found.'); // get rider id from capi user metadata $rider = $this->getRiderFromCAPI($capi_user, $em); if ($rider == null) return new APIResponse(false, 'No rider found.'); $msg = $this->checkJO($req, $required_params, $jo, $rider); if (!empty($msg)) return new APIResponse(false, $msg); // TODO: refactor this into a jo handler class, so we don't have to repeat for control center // set jo status to in progress $jo->setStatus(JOStatus::IN_PROGRESS); // set delivery status $jo->setDeliveryStatus(DeliveryStatus::RIDER_ARRIVE); // add event log $event = new JOEvent(); $event->setDateHappen(new DateTime()) ->setTypeID(JOEventType::RIDER_ARRIVE) ->setJobOrder($jo) ->setRider($rider); $em->persist($event); $em->flush(); // send mqtt event $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' => 'driver_arrived', 'jo_id' => $jo->getID(), 'driver_image' => $image_url, 'driver_name' => $rider->getFullName(), 'driver_id' => $rider->getID(), ]; $mclient->sendEvent($jo, $payload); // NOTE: for resq2 app $mclientv2->sendEvent($jo, $payload); $fcmclient->sendJoEvent($jo, "jo_fcm_title_driver_arrived", "jo_fcm_body_driver_arrived"); $data = []; return new APIResponse(true, 'Rider arrived at customer location.', $data); } public function hubArrive(Request $req, EntityManagerInterface $em) { $required_params = []; $missing = $this->checkMissingParameters($req, $required_params); if (count($missing) > 0) { $params = implode(', ', $missing); return new APIResponse(false, 'Missing parameter(s): ' . $params); } // get capi user $capi_user = $this->getUser(); if ($capi_user == null) return new APIResponse(false, 'User not found.'); // get rider id from capi user metadata $rider = $this->getRiderFromCAPI($capi_user, $em); if ($rider == null) return new APIResponse(false, 'No rider found.'); // get rider's current job order $jo = $rider->getCurrentJobOrder(); // set delivery status $jo->setDeliveryStatus(DeliveryStatus::RIDER_ARRIVE_HUB); $timestamp_event = new JOEvent(); $timestamp_event->setDateHappen(new DateTime()) ->setTypeID(JOEventType::RIDER_ARRIVE_HUB) ->setJobOrder($jo) ->setRider($rider); $em->persist($timestamp_event); // tag rider as available $rider->setAvailable(true); // set rider's current job order to null $rider->setCurrentJobOrder(); $em->flush(); $data = []; return new APIResponse(true, 'Rider arrive at hub.', $data); } public function payment(Request $req, EntityManagerInterface $em, JobOrderHandlerInterface $jo_handler, RisingTideGateway $rt, WarrantyHandler $wh, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient, TranslatorInterface $translator) { $required_params = ['jo_id']; // get capi user $capi_user = $this->getUser(); if ($capi_user == null) return new APIResponse(false, 'User not found.'); // get rider id from capi user metadata $rider = $this->getRiderFromCAPI($capi_user, $em); if ($rider == null) return new APIResponse(false, 'No rider found.'); $msg = $this->checkJO($req, $required_params, $jo, $rider); if (!empty($msg)) return new APIResponse(false, $msg); // set invoice to paid $jo->getInvoice()->setStatus(InvoiceStatus::PAID); /* // set jo status to fulfilled $jo->setStatus(JOStatus::FULFILLED); */ $jo->fulfill(); // set delivery status $jo->setDeliveryStatus(DeliveryStatus::RIDER_END); // add event log $event = new JOEvent(); $event->setDateHappen(new DateTime()) ->setTypeID(JOEventType::FULFILL) ->setJobOrder($jo) ->setRider($rider); $timestamp_event = new JOEvent(); $timestamp_event->setDateHappen(new DateTime()) ->setTypeID(JOEventType::RIDER_END) ->setJobOrder($jo) ->setRider($rider); $em->persist($event); $em->persist($timestamp_event); // NOTE: fix for the rider being assigned to other JO // while on another JO. // TODO: comment this out. Rider needs to be set to unavailable // when rider accepts the JO // tag rider as unavailable $rider->setAvailable(false); // save to customer vehicle battery record $jo_handler->updateVehicleBattery($jo); // send SMS to customer $phone_number = $jo->getCustomer()->getPhoneMobile(); if (!empty($phone_number)) { $message = $translator->trans('message.joborder_completed'); $rt->sendSMS($phone_number, $translator->trans('message.battery_brand_allcaps'), $message); } $em->flush(); // create warranty if($jo_handler->checkIfNewBattery($jo)) { $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(); // use date_schedule for warranty expiration computation $date_purchase = $jo->getDateSchedule(); $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(); } } } // for riders, use rider id $user_id = $rider->getID(); $source = WarrantySource::RAPI; $wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class, $user_id, $source, $jo->getCustomer(), $jo->getCustomerVehicle()->getVehicle()); } // send mqtt event (fulfilled) $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); // NOTE: for resq2 app $mclientv2->sendEvent($jo, $payload); $fcmclient->sendJoEvent($jo, "jo_fcm_title_fulfilled", "jo_fcm_body_fulfilled"); $data = []; return new APIResponse(true, 'Job order paid and fulfilled.', $data); } public function postHubArrive(Request $req, EntityManagerInterface $em) { $required_params = []; $missing = $this->checkMissingParameters($req, $required_params); if (count($missing) > 0) { $params = implode(', ', $missing); return new APIResponse(false, 'Missing parameter(s): ' . $params); } // get capi user $capi_user = $this->getUser(); if ($capi_user == null) return new APIResponse(false, 'User not found.'); // get rider id from capi user metadata $rider = $this->getRiderFromCAPI($capi_user, $em); if ($rider == null) return new APIResponse(false, 'No rider found.'); // get rider's current job order $jo = $rider->getCurrentJobOrder(); // set delivery status $jo->setDeliveryStatus(DeliveryStatus::RIDER_ARRIVE_HUB_POST_JO); // create time stamp event for JO event $event = new JOEvent(); $event->setDateHappen(new DateTime()) ->setTypeID(JOEventType::RIDER_ARRIVE_HUB_POST_JO) ->setJobOrder($jo) ->setRider($rider); $em->persist($event); $em->flush(); $data = []; return new APIResponse(true, 'Rider arrive hub post jo.', $data); } public function postHubDepart(Request $req, EntityManagerInterface $em) { $required_params = []; $missing = $this->checkMissingParameters($req, $required_params); if (count($missing) > 0) { $params = implode(', ', $missing); return new APIResponse(false, 'Missing parameter(s): ' . $params); } // get capi user $capi_user = $this->getUser(); if ($capi_user == null) return new APIResponse(false, 'User not found.'); // get rider id from capi user metadata $rider = $this->getRiderFromCAPI($capi_user, $em); if ($rider == null) return new APIResponse(false, 'No rider found.'); // get rider's current job order $jo = $rider->getCurrentJobOrder(); // set delivery status $jo->setDeliveryStatus(DeliveryStatus::RIDER_DEPART_HUB_POST_JO); // create time stamp event for JO event $event = new JOEvent(); $event->setDateHappen(new DateTime()) ->setTypeID(JOEventType::RIDER_DEPART_HUB_POST_JO) ->setJobOrder($jo) ->setRider($rider); $em->persist($event); $em->flush(); $data = []; return new APIResponse(true, 'Rider depart hub post jo.', $data); } public function available(Request $req, EntityManagerInterface $em) { $required_params = []; $missing = $this->checkMissingParameters($req, $required_params); if (count($missing) > 0) { $params = implode(', ', $missing); return new APIResponse(false, 'Missing parameter(s): ' . $params); } // get capi user $capi_user = $this->getUser(); if ($capi_user == null) return new APIResponse(false, 'User not found.'); // get rider id from capi user metadata $rider = $this->getRiderFromCAPI($capi_user, $em); if ($rider == null) return new APIResponse(false, 'No rider found.'); $rider->setAvailable(true); $em->flush(); $data = []; return new APIResponse(true, 'Rider available.', $data); } public function getPromos(Request $req, EntityManagerInterface $em) { $required_params = []; $missing = $this->checkMissingParameters($req, $required_params); if (count($missing) > 0) { $params = implode(', ', $missing); return new APIResponse(false, 'Missing parameter(s): ' . $params); } // get capi user $capi_user = $this->getUser(); if ($capi_user == null) return new APIResponse(false, 'User not found.'); // get rider id from capi user metadata $rider = $this->getRiderFromCAPI($capi_user, $em); if ($rider == null) return new APIResponse(false, 'No rider found.'); $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, ]; return new APIResponse(true, 'Promos found.', $data); } public function getBatteries(Request $req, EntityManagerInterface $em) { $required_params = []; $missing = $this->checkMissingParameters($req, $required_params); if (count($missing) > 0) { $params = implode(', ', $missing); return new APIResponse(false, 'Missing parameter(s): ' . $params); } // get capi user $capi_user = $this->getUser(); if ($capi_user == null) return new APIResponse(false, 'User not found.'); // get rider id from capi user metadata $rider = $this->getRiderFromCAPI($capi_user, $em); if ($rider == null) return new APIResponse(false, 'No rider found.'); $batts = $em->getRepository(Battery::class)->findBy(['flag_active' => true]); $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, ]; return new APIResponse(true, 'Batteries found.', $data); } public function changeService(Request $req, EntityManagerInterface $em, InvoiceGeneratorInterface $ic) { // $this->debugRequest($req); // allow rider to change service, promo, battery and trade-in options $required_params = ['jo_id', 'stype_id', 'promo_id']; // get capi user $capi_user = $this->getUser(); if ($capi_user == null) return new APIResponse(false, 'User not found.'); // get rider id from capi user metadata $rider = $this->getRiderFromCAPI($capi_user, $em); if ($rider == null) return new APIResponse(false, 'No rider found.'); $msg = $this->checkJO($req, $required_params, $jo, $rider); if (!empty($msg)) return new APIResponse(false, $msg); // check service type $stype_id = $req->request->get('stype_id'); if (!ServiceType::validate($stype_id)) { $data = [ 'error' => 'Invalid service type - ' . $stype_id ]; return $data; } // 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) { $data = [ 'error' => 'Invalid promo id - ' . $promo_id ]; return $data; } } // 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) { $data = [ 'error' => 'Invalid battery id - ' . $batt_id ]; return $data; } } // check trade in $trade_in = $req->request->get('trade_in'); if (!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()); $crit->setIsTaxable(); 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 $event = new JOEvent(); $event->setDateHappen(new DateTime()) ->setTypeID(JOEventType::RIDER_EDIT) ->setJobOrder($jo) ->setRider($rider); $em->persist($event); $em->flush(); // TODO: send mqtt event (?) $data = []; return new APIResponse(true, 'Job order service changed.', $data); } protected function getCAPIUser($id, EntityManagerInterface $em) { $capi_user = $em->getRepository(APIUser::class)->find($id); return $capi_user; } protected function getRiderFromCAPI($capi_user, $em) { /* //get rider id from metadata $metadata = $capi_user->getMetadata(); $rider_id = $metadata['rider_id']; // get rider $rider = $em->getRepository(Rider::class)->find($rider_id); return $rider; */ return $capi_user->getRider(); } 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; } protected function checkJO(Request $req, $required_params, &$jo = null, $rider) { // set jo status to in transit $msg = ''; $missing = $this->checkMissingParameters($req, $required_params); if (count($missing) > 0) { $params = implode(', ', $missing); $msg = 'Missing parameter(s): ' . $params; return $msg; } // check if we have an active JO // $jo = $rider->getActiveJobOrder(); $jo = $rider->getCurrentJobOrder(); if ($jo == null) { $msg = 'No active job order.'; return $msg; } // check if the jo_id sent is the same as our active jo if ($req->request->get('jo_id') != $jo->getID()) { $msg = 'Job order selected is not active job order.'; return $msg; } return $msg; } protected function debugRequest(Request $req) { $all = $req->request->all(); error_log(print_r($all, true)); } }