diff --git a/config/api_acl.yaml b/config/api_acl.yaml index ae1a9bfb..5d5dcfce 100644 --- a/config/api_acl.yaml +++ b/config/api_acl.yaml @@ -69,3 +69,8 @@ access_keys: acls: - id: dealer.list label: List + - id: warrantyserial + label: Warranty Serial + acls: + - id: warrantyserial.upload + label: Upload diff --git a/config/routes/capi.yaml b/config/routes/capi.yaml index 472da5c2..de9bf872 100644 --- a/config/routes/capi.yaml +++ b/config/routes/capi.yaml @@ -184,3 +184,9 @@ capi_dealer_list: path: /capi/dealers controller: App\Controller\CAPI\DealerController::getAll methods: [GET] + +# warranty serial api +capi_warranty_serial_upload: + path: /capi/warranty_serial + controller: App\Controller\CAPI\WarrantySerialController::upload + methods: [POST] diff --git a/src/Controller/CAPI/WarrantySerialController.php b/src/Controller/CAPI/WarrantySerialController.php new file mode 100644 index 00000000..c5e27f33 --- /dev/null +++ b/src/Controller/CAPI/WarrantySerialController.php @@ -0,0 +1,267 @@ +acl_gen = $acl_gen; + } + + public function upload(Request $req, EntityManagerInterface $em, WarrantySerialUploadLogger $upload_logger + WarrantySerialLoadLogger $load_logger) + { + $this->denyAccessUnlessGranted('warrantyserial.upload', null, 'No access.'); + + $required_params = [ + 'serial_file', + ]; + + $user_id = $_SERVER['HTTP_X_CATA_API_KEY']; + + $res = $this->checkRequiredParams($req, $required_params, $upload_logger, $user_id); + + if (!$res) + return $res; + + // get the csv file + $csv_file = $req->files->get('serial_file'); + + $res = $this->processWarrantySerialFile($csv_file, $upload_logger, $load_logger); + if (!$res) + return $res; + } + + protected function processWarrantySerialFile($csv_file, $upload_logger, $load_logger) + { + // attempt to open file + try + { + $fh = fopen($csv_file, "r"); + } + catch (Exception $e) + { + $error = 'The file ' . $csv_file . 'could not be read.'; + $log_data = [ + 'user_id' => $user_id, + 'is_uploaded' => false, + 'error' => $error; + ]; + $this->upload_logger->logWarrantySerialUploadInfo($log_data); + return new APIResponse(false, $error); + } + + while(($row = $fgetcsv($fh)) !== false) + { + $is_valid = $this->validateRow($row[0], $load_logger, $user_id); + if ($is_valid) + { + // valid entry, we parse and insert + $serial = trim(strtoupper($row[0])); + $sku = trim(strtoupper($row[1])); + $dispatch_status = trim($row[2]); + $str_date_create = trim($row[3]); + $inventory_status = trim($row[4]); + $cat_id = trim($row[5]); + $cat_name = trim(strtoupper($row[6])); + + // we are sure that this is a valid date at this point + $created_date = $this->convertDateCreate($str_date_create); + + $meta_info = [ + 'dispatch_status' => $dispatch_status, + 'inventory_status' => $inventory_status, + 'category_id' => $cat_id, + 'category_name' => $cat_name, + ]; + + $info = json_encode($meta_info); + + // insert the data. Still need to figure out how to do this fast + + // log the successful insert + $log_data = [ + 'user_id' => $user_id, + 'is_loaded' => true, + 'serial' => $serial, + 'error' => ''; + ]; + + $this->upload_logger->logWarrantySeriaLoadInfo($log_data); + } + } + + return true; + } + + protected function validateRow($entry, $load_logger, $user_id) + { + // possible lines: + // (1) header in csv file - ignore + // SerialNumber,Sku,DispatchStatus,CreatedDate,InventoryStatus,CategoryID,CategoryName + // (2) No available data - ignore + // (3) CH2000012071,WCHD23BL-CPN00-LX,0,2020-08-11 04:05:27.090,0,4,CHAMPION MF - valid + // (4) MG2000313690,N/A,1,2021-05-14T23:47:30.6430000+08:00,0,10,GOLD - valid + // (5) Empty line - ignore + // (6) empty sku - log + + // check if the line is a header + if ($row[0] == 'SerialNumber') + { + // no need to log, just ignore and skip + return false; + } + + // check if empty line + if ($row == array(null)) + { + // no need to log, just ignore and skip + return false; + } + + // check if empty serial + if (empty($row[0])) + { + // this one, we log + $error = 'Empty serial'; + $log_data = [ + 'user_id' => $user_id, + 'is_loaded' => false, + 'serial' => '', + 'error' => $error; + ]; + $this->upload_logger->logWarrantySeriaLoadInfo($log_data); + + return false; + } + + // validate the date created + $str_date_create = trim($row[3]); + + $date_create = $this->convertDateCreate($str_date_create) + if ($date_create == null) + { + // log + $error = 'Invalid date create'; + $serial = trim($row[0]); + $log_data = [ + 'user_id' => $user_id, + 'is_loaded' => false, + 'serial' => $serial, + 'error' => $error; + ]; + + $this->upload_logger->logWarrantySeriaLoadInfo($log_data); + + return false; + } + + // valid entry + return true; + } + + protected convertDateCreate($str_date_create) + { + // since some people cannot follow simple instructions... + // check the date format on the string + // try 2021-05-15T08:35:46+08:00 format on str_date_create + $date_create = DateTime::createFromFormat('Y-m-d\TH:i:sP', $str_date_create); + + if ($date_create == false) + { + // try this format: 2021-05-15T08:47:20.3330000+08:00 + // get the date, time and timezone from str_date_create + $str_date_time = substr($str_date_create, 0, 19); + $str_timezone = substr($str_date_create, 27); + $str_datetime_tz = $str_date_time . $str_timezone; + + // create DateTime object + // sample: 2021-05-15T12:16:06+08:00 + $date_create = DateTime::createFromFormat('Y-m-d\TH:i:sP', $str_datetime_tz); + + // check if datetime object was created + // if not, someone f*cked up and we have no date create + if ($date_create == false) + { + return null; + } + } + + // if you reach this part, then date string is valid and can be converted + $created_date = $date_create->format('Y-m-d H:i:s'); + + return $created_date; + } + + protected function checkRequiredParams(Request $req, $params, $upload_logger, $user_id) + { + // check required parameters + $missing = $this->checkMissingParameters($req, $params); + if (count($missing) > 0) + { + // log the error + $miss_string = implode(', ', $missing); + $log_data = [ + 'user_id' => $user_id, + 'is_uploaded' => false, + 'error' => 'Missing parameter(s): ' . $miss_string + ]; + + $this->upload_logger->logWarrantySerialUploadInfo($log_data); + + return new APIResponse(false, 'Missing parameter(s): ' . $miss_string); + } + + return true; + } + + protected function checkMissingParameters(Request $req, $params = []) + { + $missing = []; + + // check if parameters are there + foreach ($params as $param) + { + if ($req->getMethod() == 'GET') + { + $check = $req->query->get($param); + if (empty($check)) + $missing[] = $param; + } + else if ($req->getMethod() == 'POST') + { + $check = $req->request->get($param); + if (empty($check)) + $missing[] = $param; + } + else + return $params; + } + + return $missing; + } +} diff --git a/src/Entity/WarrantySerialLoadLog.php b/src/Entity/WarrantySerialLoadLog.php new file mode 100644 index 00000000..ece58ffb --- /dev/null +++ b/src/Entity/WarrantySerialLoadLog.php @@ -0,0 +1,120 @@ +date_create = new DateTime(); + $this->api_user = ''; + $this->serial = ''; + $this->flag_loaded = false; + $this->error = null; + } + + public function getID() + { + return $this->id; + } + + public function setDateCreate(DateTime $date_create) + { + $this->date_create = $date_create; + return $this; + } + + public function getDateCreate() + { + return $this->date_create; + } + + public function setApiUser($api_user) + { + $this->api_user = $api_user; + return $this; + } + + public function getApiUser() + { + return $this->api_user; + } + + public function setSerial($serial) + { + $this->serial = $serial; + return $this; + } + + public function getSerial() + { + return $this->serial; + } + + public function setLoaded($flag_loaded = true) + { + $this->flag_loaded = $flag_loaded; + return $this; + } + + public function isLoaded() + { + return $this->flag_loaded; + } + + public function setError($error) + { + $this->error = $error; + return $this; + } + + public function getError() + { + return $this->error; + } +} diff --git a/src/Entity/WarrantySerialUploadLog.php b/src/Entity/WarrantySerialUploadLog.php new file mode 100644 index 00000000..e9e916b3 --- /dev/null +++ b/src/Entity/WarrantySerialUploadLog.php @@ -0,0 +1,101 @@ +date_create = new DateTime(); + $this->api_user = ''; + $this->flag_uploaded = false; + $this->error = null; + } + + public function getID() + { + return $this->id; + } + + public function setDateCreate(DateTime $date_create) + { + $this->date_create = $date_create; + return $this; + } + + public function getDateCreate() + { + return $this->date_create; + } + + public function setApiUser($api_user) + { + $this->api_user = $api_user; + return $this; + } + + public function getApiUser() + { + return $this->api_user; + } + + public function setUploaded($flag_uploaded = true) + { + $this->flag_uploaded = $flag_uploaded; + return $this; + } + + public function isUploaded() + { + return $this->flag_uploaded; + } + + public function setError($error) + { + $this->error = $error; + return $this; + } + + public function getError() + { + return $this->error; + } diff --git a/src/Service/WarrantySerialLoadLogger.php b/src/Service/WarrantySerialLoadLogger.php new file mode 100644 index 00000000..c20486a3 --- /dev/null +++ b/src/Service/WarrantySerialLoadLogger.php @@ -0,0 +1,37 @@ +em = $em; + } + + public function logWarrantySerialLoadInfo($log_data) + { + $log_entry = new WarrantySerialLoadLog(); + + $user_id = $log_data['user_id']; + $serial = $log_data['serial']; + $is_loaded = $log_data['is_loaded']; + $error = $log_data['error']; + + $log_entry->setApiUser($user_id) + ->setSerial($serial) + ->setLoaded($is_loaded) + ->setError($error); + + $this->em->persist($log_entry); + $this->em->flush(); + + } + +} diff --git a/src/Service/WarrantySerialUploadLogger.php b/src/Service/WarrantySerialUploadLogger.php new file mode 100644 index 00000000..4172e78d --- /dev/null +++ b/src/Service/WarrantySerialUploadLogger.php @@ -0,0 +1,35 @@ +em = $em; + } + + public function logWarrantySerialUploadInfo($log_data) + { + $log_entry = new WarrantySerialUploadLog(); + + $user_id = $log_data['user_id']; + $is_uploaded = $log_data['is_uploaded']; + $error = $log_data['error']; + + $log_entry->setApiUser($user_id) + ->setLoaded($is_uploaded) + ->setError($error); + + $this->em->persist($log_entry); + $this->em->flush(); + + } + +}