acl_gen = $acl_gen; } protected function cleanSerial($serial) { return trim(strtoupper($serial)); } protected function generateWarrantyData(Warranty $warr) { $batt = $warr->getSAPBattery(); $data = [ 'id' => (int) $warr->getID(), 'serial' => (string) $warr->getSerial(), 'warranty_class' => (string) $warr->getWarrantyClass(), 'plate_number' => (string) $warr->getPlateNumber(), 'battery' => [ 'sku' => (string) ($batt == null ? '' : $batt->getID()), 'brand' => (int) ($batt == null ? 0 : $batt->getBrand()->getID()), 'size' => (int) ($batt == null ? 0 : $batt->getSize()->getID()), ], 'customer' => [ 'first_name' => (string) $warr->getFirstName() ?? '', 'last_name' => (string) $warr->getLastName() ?? '', 'mobile_number' => (string) $warr->getMobileNumber() ?? '', ], 'status' => (string) $warr->getStatus(), 'date_create' => (string) $warr->getDateCreate()->format('YmdHis'), 'date_purchase' => (string) $warr->getDatePurchase()->format('Ymd'), 'flag_activated' => (boolean) $warr->isActivated(), ]; $date_claim = $warr->getDateClaim(); if ($date_claim == null) $data['date_claim'] = null; else $data['date_claim'] = (string) $warr->getDateClaim()->format('Ymd'); $date_expire = $warr->getDateExpire(); if ($date_expire == null) $data['date_expire'] = null; else $data['date_expire'] = (string) $warr->getDateExpire()->format('Ymd'); return $data; } public function find($serial, EntityManagerInterface $em) { $this->denyAccessUnlessGranted('warranty.find.serial', null, 'No access.'); $clean_serial = $this->cleanSerial($serial); $warr = $em->getRepository(Warranty::class)->findOneBy(['serial' => $clean_serial]); if ($warr == null) return new APIResponse(false, 'No warranty found with that serial number.', null, 404); $data = [ 'warranty' => $this->generateWarrantyData($warr), ]; return new APIResponse(true, 'Warranty found.', $data); } public function getAll(Request $req, EntityManagerInterface $em) { $this->denyAccessUnlessGranted('warranty.list', null, 'No access.'); $order = $req->query->get('order'); if ($order == null) $order = 'ASC'; $max = $req->query->get('limit'); if ($max == null) $max = 20; $start = $req->query->get('start'); if ($start == null) $start = 0; $qb = $em->createQueryBuilder(); $query = $qb->select('w') ->from('App\\Entity\\Warranty', 'w') ->orderBy('w.date_create', $order) ->setFirstResult($start) ->setMaxResults($max) ->getQuery(); $warrs = $query->getResult(); $warr_data = []; foreach ($warrs as $warr) $warr_data[] = $this->generateWarrantyData($warr); $data = [ 'warranties' => $warr_data, ]; return new APIResponse(true, 'Warranties found.', $data); } public function register(Request $req, EntityManagerInterface $em, WarrantyAPILogger $logger) { $this->denyAccessUnlessGranted('warranty.register.battery', null, 'No access.'); // required parameters $params = [ 'serial', 'warranty_class', 'plate_number', 'date_expire', 'date_purchase', 'sku', /* 'battery_model_id', 'battery_size_id', */ ]; $serial = $req->request->get('serial'); $date_expire_string = $req->request->get('date_expire'); $date_pur_string = $req->request->get('date_purchase'); $warr_class = $req->request->get('warranty_class'); $plate = $req->request->get('plate_number'); $sku = $req->request->get('sku'); $fname = $req->request->get('first_name', null); $lname = $req->request->get('last_name', null); $mnum = $req->request->get('mobile_number', null); // set up information for logging // get user from header $user_id = $_SERVER['HTTP_X_CATA_API_KEY']; $log_data = [ 'serial' => $serial, 'date_expire' => $date_expire_string, 'date_pur_string' => $date_pur_string, 'warranty_class' => $warr_class, 'plate_number' => $plate, 'sku' => $sku, 'first_name' => $fname, 'last_name' => $lname, 'mobile_number' => $mnum, ]; $action = 'create'; $msg = $this->checkRequiredParameters($req, $params); error_log('msg - ' . $msg); if ($msg) { $logger->logWarrantyInfo($log_data, $msg, $user_id, $action); return new APIResponse(false, $msg); } /* $bmodel_id = $req->request->get('battery_model_id'); $bsize_id = $req->request->get('battery_size_id'); */ // wrong date expire format $date_expire = DateTime::createFromFormat('Ymd', $date_expire_string); if ($date_expire === false) { $logger->logWarrantyInfo($log_data, 'Wrong date format: date_expire.', $user_id, $action); return new APIResponse(false, 'Wrong date format: date_expire.'); } // wrong date purchase format $date_pur = DateTime::createFromFormat('Ymd', $date_pur_string); if ($date_pur === false) { $logger->logWarrantyInfo($log_data, 'Wrong date format: date_purchase', $user_id, $action); return new APIResponse(false, 'Wrong date format: date_purchase.'); } // valid warranty class if (!WarrantyClass::validate($warr_class)) { $logger->logWarrantyInfo($log_data, 'Invalid warranty class.', $user_id, $action); return new APIResponse(false, 'Invalid warranty class.'); } // plate number $plate = Warranty::cleanPlateNumber($plate); if (!$plate) { $logger->logWarrantyInfo($log_data, 'Invalid plate number.', $user_id, $action); return new APIResponse(false, 'Invalid plate number.'); } // check if sku is blank if ((empty($sku)) || ($sku == null)) $batt = null; else { // battery $batt = $em->getRepository(SAPBattery::class)->find($sku); if ($batt == null) { $logger->logWarrantyInfo($log_data, 'Invalid battery SKU.', $user_id, $action); return new APIResponse(false, 'Invalid battery SKU.'); } } /* // battery model $model = $em->getRepository(BatteryModel::class)->find($bmodel_id); if ($model == null) return new APIResponse(false, 'Invalid battery model id.'); // battery size $size = $em->getRepository(BatterySize::class)->find($bsize_id); if ($size == null) return new APIResponse(false, 'Invalid battery size id.'); */ // warranty $warr = new Warranty(); $warr->setSerial($serial) ->setWarrantyClass($warr_class) ->setPlateNumber($plate) ->setFirstName($fname) ->setLastName($lname) ->setMobileNumber($mnum) ->setSAPBattery($batt) ->setDatePurchase($date_pur) ->setDateClaim(null) ->setDateExpire($date_expire); try { $em->persist($warr); $this->getCustomerFromMobile($em, $warr); $em->flush(); } catch (UniqueConstraintViolationException $e) { $logger->logWarrantyInfo($log_data, 'Duplicate serial encountered.', $user_id, $action); return new APIResponse(false, 'Duplicate serial encountered.'); } // data $data = [ 'warranty' => $this->generateWarrantyData($warr), ]; // log creation of warranty data $logger->logWarrantyInfo($log_data, '', $user_id, $action); return new APIResponse(true, 'Warranty registered.', $data); } public function claim(Request $req, EntityManagerInterface $em, $id, WarrantyAPILogger $logger) { $this->denyAccessUnlessGranted('warranty.claim', null, 'No access.'); // required parameters $params = [ 'serial', ]; $serial = $req->request->get('serial'); // set up information for logging // get user from header $user_id = $_SERVER['HTTP_X_CATA_API_KEY']; $log_data = [ 'serial' => $serial, 'id' => $id, ]; $action = 'claim'; $msg = $this->checkRequiredParameters($req, $params); if ($msg) { $logger->logWarrantyInfo($log_data, $msg, $user_id, $action); return new APIResponse(false, $msg); } // no warranty $warr = $em->getRepository(Warranty::class)->find($id); if ($warr == null) { $logger->logWarrantyInfo($log_data, 'No warranty found with that id.', $user_id, $action); return new APIResponse(false, 'No warranty found with that id.', null, 404); } // warranty is not active if (!$warr->canClaim()) { $logger->logWarrantyInfo($log_data, 'Warranty is not active.', $user_id, $action); return new APIResponse(false, 'Warranty is not active.'); } // check if new serial has been used $clean_serial = $this->cleanSerial($serial); $check_warr = $em->getRepository(Warranty::class)->findOneBy(['serial' => $clean_serial]); if ($check_warr != null) { $logger->logWarrantyInfo($log_data, 'Serial for replacement has already been used.', $user_id, $action); return new APIResponse(false, 'Serial for replacement has already been used.'); } // set status to claim $warr->setStatus(WarrantyStatus::CLAIMED) ->setDateClaim(new DateTime()); // make replacement warranty $new_warr = new Warranty(); $new_warr->setSerial($clean_serial) ->setWarrantyClass($warr->getWarrantyClass()) ->setPlateNumber($warr->getPlateNumber()) ->setFirstName($warr->getFirstName()) ->setLastName($warr->getLastName()) ->setMobileNumber($warr->getMobileNumber()) ->setSAPBattery($warr->getSAPBattery()) ->setDatePurchase($warr->getDatePurchase()) ->setDateClaim(null) ->setDateExpire($warr->getDateExpire()) ->setClaimedFrom($warr); $em->persist($new_warr); $em->flush(); // TODO: claim log $logger->logWarrantyInfo($log_data, '', $user_id, $action); return new APIResponse(true, 'Warranty claimed successfully.'); } public function getPlateWarranties($plate_number, EntityManagerInterface $em) { $this->denyAccessUnlessGranted('warranty.find.platenumber', null, 'No access.'); $warranties = $em->getRepository(Warranty::class) ->findBy(['plate_number' => $plate_number], ['date_purchase' => 'DESC']); $warr_data = []; foreach ($warranties as $warr) { $warr_data[] = $this->generateWarrantyData($warr); } $data = [ 'warranties' => $warr_data, ]; return new APIResponse(true, 'Warranties loaded.', $data); } public function update(Request $req, EntityManagerInterface $em, $id) { $this->denyAccessUnlessGranted('warranty.update', null, 'No access.'); // find warranty $warr = $em->getRepository(Warranty::class)->find($id); if ($warr == null) return new APIResponse(false, 'No warranty found with that id.', null, 404); // required parameters $params = [ 'serial', 'warranty_class', 'plate_number', 'date_expire', 'date_purchase', 'sku', ]; $msg = $this->checkRequiredParameters($req, $params); error_log('msg - ' . $msg); if ($msg) return new APIResponse(false, $msg); // TODO: refactor this since this snippet is the same for register $serial = $req->request->get('serial'); $date_expire_string = $req->request->get('date_expire'); $date_pur_string = $req->request->get('date_purchase'); $warr_class = $req->request->get('warranty_class'); $plate = $req->request->get('plate_number'); $sku = $req->request->get('sku'); $fname = $req->request->get('first_name', null); $lname = $req->request->get('last_name', null); $mnum = $req->request->get('mobile_number', null); // wrong date expire format $date_expire = DateTime::createFromFormat('Ymd', $date_expire_string); if ($date_expire === false) return new APIResponse(false, 'Wrong date format: date_expire.'); // wrong date purchase format $date_pur = DateTime::createFromFormat('Ymd', $date_pur_string); if ($date_pur === false) return new APIResponse(false, 'Wrong date format: date_purchase.'); // valid warranty class if (!WarrantyClass::validate($warr_class)) return new APIResponse(false, 'Invalid warranty class.'); // plate number $plate = Warranty::cleanPlateNumber($plate); if (!$plate) return new APIResponse(false, 'Invalid plate number.'); // check if sku is blank if ((empty($sku)) || ($sku == null)) $batt = null; else { // battery $batt = $em->getRepository(SAPBattery::class)->find($sku); if ($batt == null) return new APIResponse(false, 'Invalid battery SKU.'); } $warr->setSerial($serial) ->setWarrantyClass($warr_class) ->setPlateNumber($plate) ->setFirstName($fname) ->setLastName($lname) ->setMobileNumber($mnum) ->setSAPBattery($batt) ->setDatePurchase($date_pur) ->setDateClaim(null) ->setDateExpire($date_expire); try { $em->persist($warr); $em->flush(); } catch (UniqueConstraintViolationException $e) { return new APIResponse(false, 'Duplicate serial encountered.'); } // data $data = [ 'warranty' => $this->generateWarrantyData($warr), ]; return new APIResponse(true, 'Warranty updated.', $data); } public function cancel(Request $req, EntityManagerInterface $em, $id) { $this->denyAccessUnlessGranted('warranty.cancel', null, 'No access.'); // find warranty $warr = $em->getRepository(Warranty::class)->find($id); if ($warr == null) return new APIResponse(false, 'No warranty found with that id.', null, 404); if ($warr->getStatus() == WarrantyStatus::CANCELLED) { return new APIResponse(false, 'Warranty already cancelled.'); } // set status to cancelled $warr->setStatus(WarrantyStatus::CANCELLED); $em->persist($warr); $em->flush(); return new APIResponse(true, 'Warranty cancelled successfully.'); } public function delete(EntityManagerInterface $em, $id) { $this->denyAccessUnlessGranted('warranty.delete', null, 'No access.'); // find warranty $warr = $em->getRepository(Warranty::class)->find($id); if ($warr == null) { return new APIResponse(false, 'No warranty found with that id.', null, 404); } // delete the warranty $em->remove($warr); $em->flush(); return new APIResponse(true, 'Warranty deleted successfully.'); } public function setPrivacyPolicy(Request $req, EntityManagerInterface $em, $id) { $this->denyAccessUnlessGranted('warranty.set.privacypolicy', null, 'No access.'); // find warranty $warr = $em->getRepository(Warranty::class)->find($id); if ($warr == null) { return new APIResponse(false, 'No warranty found with that id.', null, 404); } $params = [ 'privacy_policy_id', ]; $msg = $this->checkRequiredParameters($req, $params); error_log('msg - ' . $msg); if ($msg) return new APIResponse(false, $msg); $privacy_policy_id = $req->request->get('privacy_policy_id'); if ($privacy_policy_id == 0) { $warr->setPrivacyPolicy(null); } else { // find privacy policy $privacy_policy = $em->getRepository(PrivacyPolicy::class)->find($privacy_policy_id); if ($privacy_policy == null) { return new APIResponse(false, 'No privacy policy found with that id.', null, 404); } // set privacy policy of warranty $warr->setPrivacyPolicy($privacy_policy); } $em->persist($warr); return new APIResponse(true, 'Privacy policy for warranty set successfully.'); } public function getWarrantiesBySerialList(Request $req, EntityManagerInterface $em) { $this->denyAccessUnlessGranted('warranty.list.serial', null, 'No access.'); error_log('getWarrantiesBySerialList'); // required parameters $params = [ 'serial_list', ]; $msg = $this->checkRequiredParameters($req, $params); error_log('msg - ' . $msg); if ($msg) return new APIResponse(false, $msg); $serial_list = $req->request->get('serial_list'); if (empty($serial_list)) return new APIResponse(false, 'Empty serial numbers list.'); $warranty_list = []; $warr_not_found_list = []; foreach ($serial_list as $serial) { $clean_serial = $this->cleanSerial($serial); $warr = $em->getRepository(Warranty::class)->findOneBy(['serial' => $clean_serial]); if ($warr == null) $warr_not_found_list[] = $clean_serial; else $warranty_list[] = $this->generateWarrantyData($warr); } $data = [ 'warranties_found' => $warranty_list, 'warranties_not_found' => $warr_not_found_list, ]; return new APIResponse(true, 'Warranties found.', $data); } protected function getCustomerFromMobile($em, $warranty) { $w_mobile = $warranty->getMobileNumber(); if (empty($w_mobile)) { return null; } // set values for new customer vehicle $w_plate_number = $this->cleanPlateNumber($warranty->getPlateNumber()); $cust_found = false; $w_mobile_num = trim($w_mobile); // does it fit our 09XXXXXXXXX pattern? if (preg_match('/^09[0-9]{9}$/', $w_mobile_num)) { // remove first '0' $w_mobile_num = substr($w_mobile_num, 1); error_log("CONVERTED TO $w_mobile_num"); } // does it fit our 9XXXXXXXXX pattern? if (!preg_match('/^9[0-9]{9}$/', $w_mobile_num)) return null; /* // min length 2 // TODO: we need to check proper phone number format // format should be '9XXXXXXXXX' // TODO: if format doesn't fit and there's a 0 or 63 prefix, we should be able to detect and convert if (strlen($w_mobile_num <= 2)) continue; */ $customers = $this->findCustomerByNumber($em, $w_mobile_num); if (!empty($customers)) { error_log('found customer for ' . $w_mobile_num); foreach ($customers as $customer) { // get customer vehicles for customer $c_vehicles = $customer->getVehicles(); $cv_found = false; if (!empty($c_vehicles)) { // check if plate number of customer vehicle matches warranty plate number foreach ($c_vehicles as $c_vehicle) { $clean_cv_plate = $this->cleanPlateNumber($c_vehicle->getPlateNumber()); // check if it's already there if ($clean_cv_plate == $w_plate_number) { // customer and customer vehicle already exists $cv_found = true; break; } } } // if there was a customer vehicle matched if ($cv_found) { // vehicle found, do nothing. error_log('vehicle found - ' . $w_plate_number); } else { // customer exists but not customer vehicle // add customer vehicle to existing customer with unknown manufacturer and make error_log('new vehicle - ' . $w_plate_number); $this->createCustomerVehicle($em, $customer, $this->getDefaultVehicle($em), $w_plate_number); } } } // customer not found else { error_log('NEW customer and vehicle - ' . $w_plate_number); // customer not found, add customer and customer vehicle // get warranty first name, last name $w_first_name = $warranty->getFirstName(); $w_last_name = $warranty->getLastName(); $new_cust = new Customer(); // TODO: add customer source $new_cust->setFirstName($w_first_name) ->setLastName($w_last_name) ->setPhoneMobile($w_mobile_num); $em->persist($new_cust); $this->createCustomerVehicle($em, $new_cust, $this->getDefaultVehicle($em), $w_plate_number); } $em->flush(); $em->clear(); } protected function getDefaultVehicle($em) { // get default vehicle $cvu_brand_id = $this->getParameter('cvu_brand_id'); $default_vehicle = $em->getRepository(Vehicle::class)->find($cvu_brand_id); if ($default_vehicle == null) { //$output->writeln("Need to add vehicle with default values."); error_log('Need to add vehicle with default values.'); return null; } return $default_vehicle; } protected function cleanPlateNumber($plate) { // remove spaces and make upper case return strtoupper(str_replace(' ', '', $plate)); } protected function createCustomerVehicle($em, Customer $cust, $vehicle, $plate_number) { $new_cv = new CustomerVehicle(); $new_cv->setCustomer($cust) ->setPlateNumber($plate_number) ->setStatusCondition(VehicleStatusCondition::BRAND_NEW) ->setModelYear('') ->setColor('') ->setFuelType(FuelType::GAS) ->setHasMotoliteBattery(true) ->setVehicle($vehicle); $em->persist($new_cv); } protected function findCustomerByNumber($em, $number) { $customers = $em->getRepository(Customer::class)->findBy(['phone_mobile' => $number]); return $customers; } }