diff --git a/app/Config/Filters.php b/app/Config/Filters.php index ecf5672..31f27ad 100755 --- a/app/Config/Filters.php +++ b/app/Config/Filters.php @@ -19,6 +19,7 @@ use App\Filters\Cors; use App\Filters\GlobalPostFileUploadGuard; use App\Filters\SecurityInputFilter; use App\Filters\AclFilter; +use App\Filters\RateLimitFilter; @@ -47,6 +48,7 @@ class Filters extends BaseConfig 'GlobalPostFileUploadGuard' => GlobalPostFileUploadGuard::class, 'SecurityInputFilter' => SecurityInputFilter::class, 'AclFilter' => AclFilter::class, + 'ratelimit' => RateLimitFilter::class, ]; @@ -60,9 +62,9 @@ class Filters extends BaseConfig public array $globals = [ 'before' => [ 'HttpRequestLog' => ['except' => 'cli/*'], - 'AclFilter' => ['except' => ['login', 'logout', 'auth/*', 'oauth2callback','claim-form-download', 'claims-feedback-form', 'autobookstackLogin','/employeeRest/*','processjob']], + 'AclFilter' => ['except' => ['login', 'logout', 'auth/*', 'oauth2callback','claim-form-download', 'claims-feedback-form', 'autobookstackLogin','/employeeRest/*','processjob', 'getPreEmployeePolicyCount']], 'Cors', - 'SecurityInputFilter' => ['except' => ['notification/create','test_mail'] ], + 'SecurityInputFilter' => ['except' => ['/client/notification/create','test_mail'] ], 'GlobalPostFileUploadGuard', // 'invalidchars', ], diff --git a/app/Config/Routes.php b/app/Config/Routes.php index cccdc3d..a0eb3e0 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -442,7 +442,7 @@ $routes->cli('cli/check_env', 'MasterController::checkEnv'); -$routes->group("/api", ["filter" => "authJWT"], function ($routes) { +$routes->group("/api", ["filter" => [ 'ratelimit' , 'authJWT' ] ], function ($routes) { $routes->post("logined", "RestAuthenticationController::logined"); $routes->post("getId", "RestAuthenticationController::getUserIdFromToken"); }); @@ -454,7 +454,7 @@ $routes->group("/api", ["filter" => "authJWT"], function ($routes) { // $routes->post("employeeRest/createOrUpdateEmployeePolicySiAmount", "EmployeeRestController::createOrUpdateEmployeePolicySiAmount"); // $routes->post("employeeRest/calculatePremium", "EmployeeRestController::calculatePremium"); // $routes->post("updateMpin", "RestAuthenticationController::updateMpin"); -$routes->group("employeeRest", ['filter' => ['appSignature' , 'authJWT'] ], function ($routes) { +$routes->group("employeeRest", ['filter' => [ 'GlobalPostFileUploadGuard', 'ratelimit' , 'appSignature' , 'authJWT' ] ], function ($routes) { $routes->post('logout', 'RestAuthenticationController::logout'); @@ -503,10 +503,11 @@ $routes->group("employeeRest", ['filter' => ['appSignature' , 'authJWT'] ], func $routes->post("hrFileUpload", "EmployeeRestController::hrFileUpload"); $routes->get("copyActiveEmployeeAndDependentDetails", "EmployeeRestController::copyActiveEmployeeAndDependentDetails"); + $routes->get("getExcelFileErrors/(:any)", "EmployeeController::getExcelFileErrors/$1"); }); -$routes->group("employeeRest", ['filter' => ['appSignature'] ], function ($routes) { +$routes->group("employeeRest", ['filter' => ['ratelimit' , 'appSignature'] ], function ($routes) { //Employee login api's $routes->post("verifyEmployeeNumber", "RestAuthenticationController::verifyEmployeeWithMobileNumber"); @@ -539,7 +540,7 @@ $routes->group("employeeRest", ['filter' => ['appSignature'] ], function ($route }); -$routes->post("getPreEmployeePolicyCount","EmployeeRestController::getPreEmployeePolicyCount", ['filter' => ['appSignature']]); +$routes->post("getPreEmployeePolicyCount","EmployeeRestController::getPreEmployeePolicyCount", ['filter' => ['ratelimit','appSignature']]); $routes->get("getEmployeeActiveOrInactivePolicy", "EmployeeRestController::getEmployeeActiveOrInactivePolicy"); $routes->get("sendPushNotification", "EmployeeRestController::sendPushNotification"); diff --git a/app/Controllers/EmployeeController.php b/app/Controllers/EmployeeController.php index 936d914..0f40f94 100755 --- a/app/Controllers/EmployeeController.php +++ b/app/Controllers/EmployeeController.php @@ -180,7 +180,14 @@ class EmployeeController extends AdminController //handles employee & dependent bulk upload with events like inception,addition,deletion, correction and SI enhancements public function employeesUplodWithEvents($post_data = []) - { + { + if(empty($post_data)){ + $post_data = $this->request->getPost(); + $post_data = array_merge($post_data, $this->request->getFiles()); + $is_post_request = true; + }else{ + $is_post_request = false; + } // $empDataServiceController = new EmpDataServiceController(); // !dd($empDataServiceController->importInceptionUpdateTPAandUHID(['file_id' => 79])); @@ -336,7 +343,7 @@ class EmployeeController extends AdminController $avatar = isset($post_data['emplist']) ? $post_data['emplist'] : $this->request->getFile('emplist'); if (!$avatar) { $this->myLogger->logme("error", 'File not found'); - if (!empty($post_data)) { + if (!$is_post_request) { return ['status' => false, 'message' => 'File not found']; } else { return $this->respond(['dataStatus' => false, 'code' => 400, 'message' => 'File not found'], 400); @@ -352,7 +359,7 @@ class EmployeeController extends AdminController $this->myLogger->logme("error", 'File move successful'); } else { $this->myLogger->logme("error", 'File move failed'); - if (!empty($post_data)) { + if (!$is_post_request) { return ['status' => false, 'message' => 'File move failed']; } else { return $this->respond(['dataStatus' => false, 'code' => 500, 'message' => 'File move failed'], 500); @@ -360,7 +367,7 @@ class EmployeeController extends AdminController } } else { $this->myLogger->logme("error", 'Upload failed Invalid file'); - if (!empty($post_data)) { + if (!$is_post_request) { return ['status' => false, 'message' => 'Invalid file']; } else { return $this->respond(['dataStatus' => false, 'code' => 404, 'message' => 'Invalid file'], 404); @@ -370,12 +377,21 @@ class EmployeeController extends AdminController //process post variable entry in file table $loggedInUserID = $post_data['created_by'] ?? get_session_userid(); - $client_id = isset($post_data['client_id']) ? $post_data['client_id'] : $this->request->getPost('client_id'); - $policy_id = isset($post_data['policy_id']) ? $post_data['policy_id'] : $this->request->getPost('policy_id'); - $branch_id = isset($post_data['client_branch_id']) ? $post_data['client_branch_id'] : $this->request->getPost('branch_id'); - $action = isset($post_data['file_action']) ? $post_data['file_action'] : $this->request->getPost('upload-action-type'); - $enrollment_open_date = isset($post_data['enrollment_open_date']) ? $post_data['enrollment_open_date'] : $this->request->getPost('enrollment_open_date') ?? null; - $enrollment_close_date = isset($post_data['enrollment_close_date']) ? $post_data['enrollment_close_date'] : $this->request->getPost('enrollment_close_date') ?? null; + // $client_id = isset($post_data['client_id']) ? $post_data['client_id'] : $this->request->getPost('client_id'); + // $policy_id = isset($post_data['policy_id']) ? $post_data['policy_id'] : $this->request->getPost('policy_id'); + // $branch_id = isset($post_data['client_branch_id']) ? $post_data['client_branch_id'] : $this->request->getPost('branch_id'); + // $action = isset($post_data['file_action']) ? $post_data['file_action'] : $this->request->getPost('upload-action-type'); + // $enrollment_open_date = isset($post_data['enrollment_open_date']) ? $post_data['enrollment_open_date'] : $this->request->getPost('enrollment_open_date') ?? null; + // $enrollment_close_date = isset($post_data['enrollment_close_date']) ? $post_data['enrollment_close_date'] : $this->request->getPost('enrollment_close_date') ?? null; + // $status = 'inprogress'; + // $hr_id = $post_data['created_by'] ?? null; + + $client_id = $post_data['client_id'] ?? null; + $policy_id = $post_data['policy_id'] ?? null; + $branch_id = $post_data['client_branch_id'] ?? null; + $action = "enrollment"; + $enrollment_open_date = $post_data['enrollment_open_date'] ?? null; + $enrollment_close_date = $post_data['enrollment_close_date'] ?? null; $status = 'inprogress'; $hr_id = $post_data['created_by'] ?? null; @@ -393,8 +409,8 @@ class EmployeeController extends AdminController $this->myLogger->logme("error", '{file_id} is less than 1MB, validating on the fly', ['file_id' => $file_id]); //endof validation process if (isset($result['error_summary']) && count($result['error_summary'])) { - if(!empty($post_data)){ - return ['status' => true, 'message' => 'file rejected with errors', 'file_id' => $file_id]; + if(!$is_post_request){ + return ['status' => false, 'message' => 'file rejected with errors', 'file_id' => $file_id]; }else{ return $this->respond(['dataStatus' => false, 'code' => 404, 'message' => 'file rejected with errors'], 200); } @@ -406,7 +422,7 @@ class EmployeeController extends AdminController $this->myLogger->logme("error", '{file_id} is greather than 1MB, validating with job queue', ['file_id' => $file_id]); } - if (!empty($post_data)) { + if (!$is_post_request) { return ['status' => true, 'message' => 'File upload successs, Data validation is in-progress', 'file_id' => $file_id]; } else { return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => 'file upload success'], 200); @@ -495,13 +511,39 @@ class EmployeeController extends AdminController // dd($data['fileList']);die(); - if ($this->request->getMethod() == "get") { + if ($_SERVER['REQUEST_METHOD'] == "GET") { $this->loadLayout('import_export', $data); } } public function getExcelFileErrors($file_id, $retun_type = null) - { + { + + $file_data = $this->fileModel->where('id', $file_id)->first(); + $error = json_decode($file_data['reason'] ?? '{}', true); + if(!empty($error) && $retun_type == 'api' && $file_data['status'] == 'failed'){ + $send = isset($error['error_summary'][5]) || isset($error['error_summary'][6]) ? true : false; + if($send){ + + $string = $error['error_data'] ?? 'System error'; + + $errorMap = [ + "Column order conflict" => "Invalid file format. Please use the sample file.", + ]; + + $message = $string; // Default to the original error + + foreach ($errorMap as $keyword => $friendlyMessage) { + if (strpos($string, $keyword) !== false) { + $message = $friendlyMessage; + break; // Stop looking once we find a match + } + } + + return $this->respond(['status' => false, 'code' => 404, 'message' => $message, 'data' => []], 200); + } + } + // $file_id = $this->request->uri->getSegment(3); $empServiceController = new EmployeeServiceController(); diff --git a/app/Controllers/EmployeeRestController.php b/app/Controllers/EmployeeRestController.php index d8ffc24..01492da 100755 --- a/app/Controllers/EmployeeRestController.php +++ b/app/Controllers/EmployeeRestController.php @@ -141,7 +141,7 @@ class EmployeeRestController extends AdminController return $this->respond(['status' => 'success','code' => 200,'data' => $result, 'AccountManagerDetails'=> isset($AccountManagerDetails[0]) ? $AccountManagerDetails[0] : null ],200); } else { $result = "No Match's"; - return $this->respond(['status' => 'failed','code' => 404,'data' => $result],404); + return $this->respond(['status' => 'failed','code' => 404,'data' => $result],200); } } catch (\Throwable $th) { return $this->respond(['status' => 'failed','code' => 500,'data' => $th],500); @@ -162,7 +162,7 @@ class EmployeeRestController extends AdminController return $this->respond(['status' => 'success','code' => 200,'data' => $result],200); } else { $result = "No Match's"; - return $this->respond(['status' => 'failed','code' => 404,'data' => $result],404); + return $this->respond(['status' => 'failed','code' => 404,'data' => $result],200); } } } catch (\Throwable $th) { @@ -190,7 +190,7 @@ class EmployeeRestController extends AdminController } else { - return $this->respond(['status' => 'failed','code' => 404,'data' => []],404); + return $this->respond(['status' => 'failed','code' => 404,'data' => []],200); } } catch (\Throwable $th) { return $this->respond(['status' => 'failed','code' => 500,'data' => $th],500); @@ -220,7 +220,7 @@ class EmployeeRestController extends AdminController return $this->respond(['status' => 'success','code' => 200,'data' => $result], 200); } else { $result = "No Matches"; - return $this->respond(['status' => 'failed','code' => 404,'data' => $result], 404); + return $this->respond(['status' => 'failed','code' => 404,'data' => $result], 200); } } } catch (\Exception $e) { @@ -584,7 +584,7 @@ class EmployeeRestController extends AdminController return $this->respond(['status' => 'success','code' => 200,'data' =>[] ], 200); }else{ - return $this->respond(['status' => 'failed','code' => 404,'data' => [] ], 404); + return $this->respond(['status' => 'failed','code' => 404,'data' => [] ], 200); } @@ -615,7 +615,7 @@ class EmployeeRestController extends AdminController $openForEnrollment = $this->findThePolicyIsOpenForEnrollment($requestData[0]->client_policy_id, $requestData[0]->emp_code); } - if($openForEnrollment == false){ return $this->respond(['status' => 'failed','code' => 404,'data' => 'Enrollment closed'], 404); } + if($openForEnrollment == false){ return $this->respond(['status' => 'failed','code' => 404,'data' => 'Enrollment closed'], 200); } foreach ($requestData as $key => $value) { @@ -687,12 +687,12 @@ class EmployeeRestController extends AdminController public function getEmployeeAndDependenceByClientId() { try { - $empData = $this->employeePolicyModel->getEmployeePolicy( client_id:$this->request->getGet('client_id'),policy_id: $this->request->getGet('client_policy_id'),status:0,branch_id:$this->request->getGet('client_branch_id')); + $empData = $this->employeePolicyModel->getEmployeePolicy( client_id:$this->request->getGet('client_id'),policy_id: $this->request->getGet('client_policy_id'),status:0,branch_id:$this->request->getGet('client_branch_id'), status_type: 'hr'); if ($empData) { return $this->respond(['status' => 'success', 'code' => 200, 'data' => $empData], 200); } else { - return $this->respond(['status' => 'failed', 'code' => 404, 'data' => []], 404); + return $this->respond(['status' => 'failed', 'code' => 404, 'data' => []], 200); } @@ -805,7 +805,7 @@ class EmployeeRestController extends AdminController if ($ClientPolicyData) { return $this->respond(['status' => 'success', 'code' => 200, 'data' => $result], 200); } else { - return $this->respond(['status' => 'failed', 'code' => 404, 'data' => []], 404); + return $this->respond(['status' => 'failed', 'code' => 404, 'data' => []], 200); } @@ -826,9 +826,16 @@ class EmployeeRestController extends AdminController 'enrollment_open_date' => $this->request->getPost('enrollment_open_date'), 'enrollment_close_date' => $this->request->getPost('enrollment_close_date'), 'file_action' => "enrollment", - 'created_by' => $this->request->getPost('created_by'), + 'created_by' => $this->request->getPost('created_by') ?? null, 'emplist' => $this->request->getFile('file') ]; + + if (is_string($post_data['client_id']) && preg_match('/^[a-f0-9]{32}$/i', $post_data['client_id'])) { + $client_data = $this->clientModel->where('MD5(id)', $post_data['client_id'])->first(); + $post_data['client_id'] = $client_data['id']; + } + + // print_r($post_data); die; if(empty($post_data['client_id'])){ @@ -839,14 +846,16 @@ class EmployeeRestController extends AdminController $responce = $employeeController->employeesUplodWithEvents($post_data); // print_r($responce); die; - if($responce['status']){ - $file_data = $this->getDataFromFilesTable(['file_id' => $responce['file_id']]); - $responce['data'] = $file_data; - return $this->respond($responce, 200); - }else{ - $responce['data'] = []; - return $this->respond($responce, 200); - } + return $this->respond($responce, 200); + + // if(!$responce['status']){ + // $file_data = $this->getDataFromFilesTable(['file_id' => $responce['file_id']]); + // $responce['data'] = $file_data; + // return $this->respond($responce, 200); + // }else{ + // $responce['data'] = []; + // return $this->respond($responce, 200); + // } @@ -864,6 +873,11 @@ class EmployeeRestController extends AdminController $client_branch_id = $this->request->getPost('client_branch_id'); $policy_id = $this->request->getPost('policy_id'); + if (is_string($client_id) && preg_match('/^[a-f0-9]{32}$/i', $client_id)) { + $client_data = $this->clientModel->where('MD5(id)', $client_id)->first(); + $client_id = $client_data['id']; + } + $client_data = $this->clientModel->where('id', $client_id)->first(); $notification = $this->notificationModel->where('client_id',$client_id)->where('template_name','member_welcome_mail')->first(); @@ -1197,7 +1211,7 @@ class EmployeeRestController extends AdminController $this->fileModel->where('id', $file_id)->set(['status' => 'success','reason' => '','error_data' => ''])->update(); return $this->respond(['status' => 'success', 'code' => 200, 'message' => "Success" ], 200); }else{ - return $this->respond(['status' => 'failed', 'code' => 404, 'message' => "Client id and Client Policy id is Not Match!" ], 404); + return $this->respond(['status' => 'failed', 'code' => 404, 'message' => "Client id and Client Policy id is Not Match!" ], 200); } } catch (\Throwable $th) { $this->myLogger->logme("error", ($th->getMessage().' --- '.$th->getLine() . '----' . $th->getTraceAsString())); @@ -1227,7 +1241,7 @@ class EmployeeRestController extends AdminController files.policy_id, cp.policy_no, files.file_name, - files.action, + files.action as file_action, files.created_at, files.created_by, files.updated_at, @@ -1261,7 +1275,11 @@ class EmployeeRestController extends AdminController } if (isset($search_data['client_id']) && !empty($search_data['client_id'])) { - $builder->where("files.client_id", $search_data['client_id']); + if (is_string($search_data['client_id']) && preg_match('/^[a-f0-9]{32}$/i', $search_data['client_id'])) { + $builder->where("MD5(files.client_id)", $search_data['client_id']); + } else { + $builder->where("files.client_id", $search_data['client_id']); + } } if (isset($search_data['file_id']) && !empty($search_data['file_id'])) { @@ -1279,6 +1297,11 @@ class EmployeeRestController extends AdminController return []; } + public function getHrFileUploadErrorDetails($file_id) + { + + } + //------------------------------------- public function getAgeRange($terms,$familyFloatesValue) @@ -2145,10 +2168,10 @@ class EmployeeRestController extends AdminController // return $restAuthController->callThirdPartyGETAPI($queryParams, 'getClientDetails'); // } else { - // return $this->respond(['status' => 'failed', 'code' => 404, 'data' => []], 404); + // return $this->respond(['status' => 'failed', 'code' => 404, 'data' => []], 200); // } // } else { - // return $this->respond(['status' => 'failed', 'code' => 404, 'data' => []], 404); + // return $this->respond(['status' => 'failed', 'code' => 404, 'data' => []], 200); // } // } catch (\Exception $e) { // return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $e->getMessage()], 500); @@ -2190,7 +2213,7 @@ class EmployeeRestController extends AdminController ], 200); } else { - return $this->respond(['status' => 'failed', 'code' => 404, 'data' => []], 404); + return $this->respond(['status' => 'failed', 'code' => 404, 'data' => []], 200); } } elseif (!empty($post_client_id)) { @@ -2204,7 +2227,7 @@ class EmployeeRestController extends AdminController } else { - return $this->respond(['status' => 'failed', 'code' => 404, 'data' => []], 404); + return $this->respond(['status' => 'failed', 'code' => 404, 'data' => []], 200); } } catch (\Exception $e) { @@ -3072,7 +3095,7 @@ class EmployeeRestController extends AdminController return $employee_data_group_by_family; }else{ // dd ($employee_data_group_by_family); - return $this->respond(['status' => 'success','code' => (count($employee_data_group_by_family) ? 200 : 404),'data' => [$employee_data_group_by_family] ], 200); + return $this->respond(['status' => 'success','code' => (count($employee_data_group_by_family) ? 200 : 200),'data' => [$employee_data_group_by_family] ], 200); } } @@ -3098,7 +3121,7 @@ class EmployeeRestController extends AdminController } if(count($policyId) == 0){ - return $this->respond(['status' => 'failed','code' => (count($policyId) ? 200 : 404),'data' => [] ], 200); + return $this->respond(['status' => 'failed','code' => (count($policyId) ? 200 : 200),'data' => [] ], 200); } @@ -3146,9 +3169,9 @@ class EmployeeRestController extends AdminController if($result) { - return $this->respond(['status' => 'success','code' => (count($result) ? 200 : 404),'data' => $result ], 200); + return $this->respond(['status' => 'success','code' => (count($result) ? 200 : 200),'data' => $result ], 200); }else{ - return $this->respond(['status' => 'failed','code' => (count($result) ? 200 : 404),'data' => [] ], 200); + return $this->respond(['status' => 'failed','code' => (count($result) ? 200 : 200),'data' => [] ], 200); } } @@ -3549,7 +3572,7 @@ class EmployeeRestController extends AdminController } else { - return $this->respond(['status' => 'failed','code' => 404,'data' => 'No Data'],404); + return $this->respond(['status' => 'failed','code' => 404,'data' => 'No Data'],200); } } catch (\Throwable $th) { return $this->respond(['status' => 'failed','code' => 500,'data' => $th],500); @@ -3573,7 +3596,7 @@ class EmployeeRestController extends AdminController } else { - return $this->respond(['status' => 'failed','code' => 404,'data' => 'No Data'],404); + return $this->respond(['status' => 'failed','code' => 404,'data' => 'No Data'],200); } } catch (\Throwable $th) { return $this->respond(['status' => 'failed','code' => 500,'data' => $th],500); @@ -3634,7 +3657,7 @@ class EmployeeRestController extends AdminController return $this->respond(['status' => 'failed', 'code' => 400, 'message' => 'Firebase Token is required'], 400); } } else { - return $this->respond(['status' => 'failed', 'code' => 404, 'message' => 'Employee not found'], 404); + return $this->respond(['status' => 'failed', 'code' => 404, 'message' => 'Employee not found'], 200); } } catch (\Throwable $th) { log_message('error', 'An error occurred: ' . $th->getMessage()); @@ -4222,13 +4245,13 @@ class EmployeeRestController extends AdminController $file_id = $this->request->getGet('id') ?? $id; // Find record - $record = $this->hrFileUploadModel->find($file_id); + $record = $this->fileModel->where('id', $file_id)->first(); if (!$record) { return $this->failNotFound("File record not found"); } - $uploadPath = WRITEPATH . 'uploads/hr_files/'; + $uploadPath = WRITEPATH . 'uploads/excel/'; $filePath = $uploadPath . $record['file_name']; if (!file_exists($filePath)) { @@ -4236,8 +4259,8 @@ class EmployeeRestController extends AdminController } // Force file download - return $this->response->download($filePath, null) - ->setFileName($record['file_name']); + return $this->response->download($filePath, null)->setFileName($record['file_name']); + } catch (\Exception $e) { return $this->failServerError($e->getMessage()); } @@ -4246,6 +4269,28 @@ class EmployeeRestController extends AdminController public function hrFileList() { try { + + $request = service('request'); + $search_data = $request->getGetPost() ?? []; + + // Fetch results + $data = $this->getDataFromFilesTable($search_data); + + return $this->respond([ + 'status' => true, + 'message' => 'File list fetched successfully', + 'data' => $data + ]); + + } catch (\Exception $e) { + return $this->failServerError($e->getMessage()); + } + } + + public function hrFileListOld() + { + try { + $request = service('request'); $builder = $this->hrFileUploadModel; diff --git a/app/Controllers/EmployeeServiceController.php b/app/Controllers/EmployeeServiceController.php index c52ebd7..69c1d0f 100755 --- a/app/Controllers/EmployeeServiceController.php +++ b/app/Controllers/EmployeeServiceController.php @@ -765,6 +765,14 @@ class EmployeeServiceController extends AdminController // get policy and rack details $policy_details = $this->clientPolicyModel->getPolicyDetails($file['client_id'],$file['policy_id']); + + if(empty($policy_details)){ + $message = "Policy configuration is incomplete. Cannot proceed."; + $this->myLogger->logme('error',($message . ' for file id ' . $file_id)); + $this->fileModel->where('id', $file_id)->set(['status' => 'failed','reason' => json_encode(['error_summary' => array_count_values([5]),'error_data' => $message])])->update(); + return array('error_summary' => [5], 'error_data' => $message); + } + $policy_terms = json_decode($policy_details[0]->policy_terms); $policy_terms = (array) $policy_terms;// convert obj to array $default_age_ratio = isset($policy_terms['age_ratio']) ? json_decode(json_encode($policy_terms['age_ratio']),true) : []; @@ -775,6 +783,13 @@ class EmployeeServiceController extends AdminController $slab_details = $this->policiesModel->getPolicySlabRatesForEmpOnboard($file['policy_id'],$file['client_id']); // dd($slab_details); + if(empty($slab_details) || (isset($slab_details['slab_rates']) && empty($slab_details['slab_rates']))){ + $message = "Policy configuration is incomplete. Cannot proceed."; + $this->myLogger->logme('error',($message . ' for file id ' . $file_id)); + $this->fileModel->where('id', $file_id)->set(['status' => 'failed','reason' => json_encode(['error_summary' => array_count_values([5]),'error_data' => $message])])->update(); + return array('error_summary' => [5], 'error_data' => $message); + } + //remove header unset($excel_data[0]); $relationship = $this->general_relationships; diff --git a/app/Controllers/RestAuthenticationController.php b/app/Controllers/RestAuthenticationController.php index 89ec1de..b15d191 100755 --- a/app/Controllers/RestAuthenticationController.php +++ b/app/Controllers/RestAuthenticationController.php @@ -171,7 +171,7 @@ class RestAuthenticationController extends AdminController //check the resend otp (with in 60 seconds don't allow another otp to send) $check = canSendOtp($employeeData); if (!$check['allowed']) { - return $this->respond(['status' => false,'message' => 'OTP already sent. Please wait before retrying.','retry_after_seconds' => $check['retry_after'] ])->setStatusCode(429); // Too Many Requests + return $this->respond(['status' => false,'message' => 'OTP already sent. Please wait before retrying.','retry_after_seconds' => $check['retry_after']], 429); // Too Many Requests } $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyEmployeeWithMobileNumber: Employee verified with ID = " . $employeeData['employee_id']); @@ -338,7 +338,7 @@ class RestAuthenticationController extends AdminController //check the resend otp (with in 60 seconds don't allow another otp to send) $check = canSendOtp($employeeData); if (!$check['allowed']) { - return $this->respond(['status' => false,'message' => 'OTP already sent. Please wait before retrying.','retry_after_seconds' => $check['retry_after'] ])->setStatusCode(429); // Too Many Requests + return $this->respond(['status' => false,'message' => 'OTP already sent. Please wait before retrying.','retry_after_seconds' => $check['retry_after']], 429); // Too Many Requests } $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyEmployeeWithEmailId: Valid employee found, generating OTP"); @@ -597,7 +597,7 @@ class RestAuthenticationController extends AdminController //check the resend otp (with in 60 seconds don't allow another otp to send) $check = canSendOtp($HrData); if (!$check['allowed']) { - return $this->respond(['status' => false,'message' => 'OTP already sent. Please wait before retrying.','retry_after_seconds' => $check['retry_after'] ])->setStatusCode(429); // Too Many Requests + return $this->respond(['status' => false,'message' => 'OTP already sent. Please wait before retrying.','retry_after_seconds' => $check['retry_after']], 429); // Too Many Requests } $sql = "UPDATE level_contacts SET otp = ? WHERE mobile = ? AND contact_type = 'client' AND is_active = 1"; @@ -662,7 +662,7 @@ class RestAuthenticationController extends AdminController //check the resend otp (with in 60 seconds don't allow another otp to send) $check = canSendOtp($HrData); if (!$check['allowed']) { - return $this->respond(['status' => false,'message' => 'OTP already sent. Please wait before retrying.','retry_after_seconds' => $check['retry_after'] ])->setStatusCode(429); // Too Many Requests + return $this->respond(['status' => false,'message' => 'OTP already sent. Please wait before retrying.','retry_after_seconds' => $check['retry_after']], 429); // Too Many Requests } diff --git a/app/Filters/Cors.php b/app/Filters/Cors.php index bb8d5b8..c9ea212 100644 --- a/app/Filters/Cors.php +++ b/app/Filters/Cors.php @@ -38,7 +38,7 @@ class Cors implements FilterInterface * * @var string */ - protected string $allowedMethods = 'GET,POST,PUT,PATCH,DELETE,OPTIONS'; + protected string $allowedMethods = 'GET,POST,OPTIONS'; /** * HTTP headers allowed in CORS requests diff --git a/app/Filters/GlobalPostFileUploadGuard.php b/app/Filters/GlobalPostFileUploadGuard.php index 4cc82ba..35476b6 100644 --- a/app/Filters/GlobalPostFileUploadGuard.php +++ b/app/Filters/GlobalPostFileUploadGuard.php @@ -39,7 +39,7 @@ class GlobalPostFileUploadGuard implements FilterInterface ]; protected array $blockedExtensions = [ - 'php', 'phtml', 'pht', 'phar', 'php3', 'php4', 'php5', 'php7', 'php8', 'phps', + 'php', 'phtml', 'html', 'pht', 'phar', 'php3', 'php4', 'php5', 'php7', 'php8', 'phps', 'cgi', 'fcgi', 'pl', 'py', 'rb', 'lua', 'tcl', 'go', 'rs', 'jar', 'class', 'exe', 'dll', 'com', 'bat', 'cmd', 'msi', 'vbs', 'ps1', 'scr', 'sh', 'bash', 'zsh', 'apk', 'app', 'deb', 'rpm', 'bin', 'run', @@ -100,7 +100,7 @@ class GlobalPostFileUploadGuard implements FilterInterface } // --- 2. Double Extension Attack Check --- - if (preg_match('/\.(php|phtml|phar|exe|sh|bat|cmd|js|jsp|asp|aspx|py|pl)\./i', $originalName)) { + if (preg_match('/\.(php|phtml|html|phar|exe|sh|bat|cmd|js|jsp|asp|aspx|py|pl)\./i', $originalName)) { $this->block("Double extension attack", $clientIp, $uri, $inputName, $originalName, $mime, $extension, $size); } diff --git a/app/Filters/RateLimitFilter.php b/app/Filters/RateLimitFilter.php new file mode 100644 index 0000000..31efe81 --- /dev/null +++ b/app/Filters/RateLimitFilter.php @@ -0,0 +1,34 @@ +getIPAddress()); + + if ($throttler->check($key, 25, MINUTE) === false) { + return service('response') + ->setStatusCode(429) + ->setJSON([ + 'status' => 'error', + 'message' => 'Too many requests. Try again later.' + ]); + } + } + + + public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) + { + // nothing + } +} diff --git a/app/Helpers/EmployeeHelper.php b/app/Helpers/EmployeeHelper.php index e33e6dd..15a3f36 100644 --- a/app/Helpers/EmployeeHelper.php +++ b/app/Helpers/EmployeeHelper.php @@ -43,12 +43,16 @@ class EmployeeHelper if($is_addon_value == 1){ $is_addon_value = 0 ; }else{ $is_addon_value = 1 ; } - $employeeData = $this->employeeModel->where('emp_code',$data[0]->emp_code) - ->where('client_id',$data[0]->client_id) - ->where('client_branch_id',$data[0]->client_branch_id) - ->where('is_active', 1 ) - ->where('is_addon_value',$is_addon_value) - ->findAll(); + $employeeData = $this->employeeModel + ->join('employee_polices', 'employees.id = employee_polices.employee_id') + ->where('employees.emp_code',$data[0]->emp_code) + ->where('employees.client_id',$data[0]->client_id) + ->where('employees.client_branch_id',$data[0]->client_branch_id) + ->where('employees.is_active', 1 ) + ->where('employee_polices.client_policy_id', $client_policy_id) + ->where('employee_polices.is_active', 1) + ->where('is_addon_value',$is_addon_value) + ->findAll(); $array = $array[0]; diff --git a/app/Helpers/JWTToken.php b/app/Helpers/JWTToken.php index d110444..f7b32ba 100755 --- a/app/Helpers/JWTToken.php +++ b/app/Helpers/JWTToken.php @@ -31,16 +31,16 @@ class JWTToken try{ $token = JWT::encode($request_data ,$secret_Key,'HS512'); $id = $request_data['id']; - $data["token_time_out"] = time() + getenv('TOKENTIMEOUT'); + $update["token_time_out"] = time() + getenv('TOKENTIMEOUT'); if(isset($data['emp_code'])){ $model = new EmployeeModel(); - $model->update($id, $data); + $model->update($id, $update); }else{ $models = new LevelContactModel(); $id = $request_data['pre_hr_id']; - $models->update($id, $data); + $models->update($id, $update); } diff --git a/app/Helpers/utility_helper.php b/app/Helpers/utility_helper.php index d1f858b..71eeb49 100755 --- a/app/Helpers/utility_helper.php +++ b/app/Helpers/utility_helper.php @@ -739,12 +739,14 @@ if (!function_exists('validateExcelFile')) { function validateExcelFile($file) { - $allowed = [ - 'application/vnd.ms-excel', + $allowed = [ + 'application/vnd.ms-excel','application/vnd', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'application/vnd.oasis.opendocument.spreadsheet' + 'application/vnd.oasis.opendocument.spreadsheet', + 'application/octet-stream' ]; + // if ($file->getError() !== UPLOAD_ERR_OK) return 'Upload error'; // if ($file->getSize() > (16 * 1024 * 1024)) return 'File too large'; // if (!in_array($file->getClientMimeType(), $allowed, true)) return 'Invalid file type'; diff --git a/app/Models/EmployeePolicyModel.php b/app/Models/EmployeePolicyModel.php index 72b8ba9..92c2905 100755 --- a/app/Models/EmployeePolicyModel.php +++ b/app/Models/EmployeePolicyModel.php @@ -82,10 +82,19 @@ class EmployeePolicyModel extends Model } // ---------------------------------------------------------------------------------------------------------- - public function getEmployeePolicy($client_id = 0, $policy_id = 0, $status = [], $branch_id = 0, $emp_code = "", $emp_name = "") + public function getEmployeePolicy($client_id = 0, $policy_id = 0, $status = [], $branch_id = 0, $emp_code = "", $emp_name = "", $status_type = "") { // dd($status); + $status_query = "employee_polices.status"; // Default fallback + + if ($status_type == "hr") { + $status_query = "CASE + WHEN employee_polices.status = 'enrolled' THEN 'under process' + ELSE employee_polices.status + END as status"; + } + $result = $this->select([ 'employee_polices.*', 'policy_type.policy_type as policy_name', @@ -147,8 +156,8 @@ class EmployeePolicyModel extends Model THEN "Newly Added" ELSE NULL END) AS newly_added', - - ]) + $status_query + ], false) ->join('employees emp', 'employee_polices.employee_id = emp.id') ->join('client_policy cp', 'employee_polices.client_policy_id = cp.id') //cp - client policy ->join('policies pm', 'cp.policy_id = pm.id', 'left') //pm - policy master diff --git a/app/Views/employee_list.php b/app/Views/employee_list.php index c4c2baa..6761bd8 100755 --- a/app/Views/employee_list.php +++ b/app/Views/employee_list.php @@ -302,14 +302,51 @@ function init() { function handleItemClick(e, item) { e.preventDefault(); - // Execute the stored onclick handler const onclickAttr = item.getAttribute('data-onclick'); if (onclickAttr) { - eval(onclickAttr); + // Regex to separate function name from the inside of the parentheses + // Example: myFunc(this, '123') -> match[1]="myFunc", match[2]="this, '123'" + const match = onclickAttr.match(/^(\w+)\((.*)\)$/); + + if (match) { + const funcName = match[1]; + const argsRaw = match[2]; + + if (typeof window[funcName] === 'function') { + // Parse the arguments string into a real array + const args = argsRaw.split(',').map(arg => { + let cleaned = arg.trim(); + + // 1. Handle the 'this' keyword + if (cleaned === 'this') return item; + + // 2. Handle 'event' keyword + if (cleaned === 'event') return e; + + // 3. Handle strings (remove single or double quotes) + if ((cleaned.startsWith("'") && cleaned.endsWith("'")) || + (cleaned.startsWith('"') && cleaned.endsWith('"'))) { + return cleaned.substring(1, cleaned.length - 1); + } + + // 4. Handle numbers + if (!isNaN(cleaned) && cleaned !== "") { + return Number(cleaned); + } + + return cleaned; + }); + + // Execute function: + // .apply(item, args) sets the 'this' inside the function to the clicked element + window[funcName].apply(item, args); + } + } } + // Handle standard navigation if it's a link const href = item.getAttribute('href'); - if (href && href !== '#') { + if (href && href !== '#' && !href.includes('javascript:void(0)')) { window.location.href = href; } diff --git a/app/Views/employee_upload.php b/app/Views/employee_upload.php index cb2147e..2409597 100755 --- a/app/Views/employee_upload.php +++ b/app/Views/employee_upload.php @@ -38,7 +38,7 @@ option:disabled {

-
diff --git a/app/Views/file_list.php b/app/Views/file_list.php index 84c1a8b..993ebe6 100755 --- a/app/Views/file_list.php +++ b/app/Views/file_list.php @@ -179,7 +179,7 @@ enctype="multipart/form-data"> - + diff --git a/app/Views/layout/footer.php b/app/Views/layout/footer.php index ec1ca32..a412cef 100755 --- a/app/Views/layout/footer.php +++ b/app/Views/layout/footer.php @@ -62,69 +62,88 @@ - +
- - - - + + - - - - + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + - + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + - - - - + + + - - - + + + + - - - - - - - - + + + + + + + - - - - + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + + + + + - - - + + + + - - - - + + + + + + + - - - + + + + + + - - + + - - + + - - + + @@ -77,7 +77,7 @@ --> - + diff --git a/app/Views/layout/header_new.php b/app/Views/layout/header_new.php index 297f7f2..e021d8a 100644 --- a/app/Views/layout/header_new.php +++ b/app/Views/layout/header_new.php @@ -50,34 +50,34 @@ /assets/css/jodit.css" rel="stylesheet" type="text/css" /> - - + + - - + + - - + + - - + + - + - + @@ -329,84 +329,8 @@ }); - - @@ -420,24 +344,219 @@ -
+
+ + +
+ + + +