diff --git a/.env.sample b/.env.sample new file mode 100644 index 00000000..6af188a4 --- /dev/null +++ b/.env.sample @@ -0,0 +1,155 @@ +#-------------------------------------------------------------------- +# Example Environment Configuration file +# +# This file can be used as a starting point for your own +# custom .env files, and contains most of the possible settings +# available in a default install. +# +# By default, all of the settings are commented out. If you want +# to override the setting, you must un-comment it by removing the '#' +# at the beginning of the line. +#-------------------------------------------------------------------- + +#-------------------------------------------------------------------- +# ENVIRONMENT +#-------------------------------------------------------------------- + +CI_ENVIRONMENT = development + +#-------------------------------------------------------------------- +# APP +#-------------------------------------------------------------------- + +app.baseURL = 'http://localhost/nhance/' +# If you have trouble with `.`, you could also use `_`. +# app_baseURL = '' +# app.forceGlobalSecureRequests = false +# app.CSPEnabled = false + +#-------------------------------------------------------------------- +# DATABASE +#-------------------------------------------------------------------- + + + +database.default.hostname = 119.18.54.85 +database.default.database = venbaehn_nhance +database.default.username = venbaehn_nhance_user1 +database.default.password = 'iM~X7(cR+}A-' +# database.default.DBDriver = MySQLi +# database.default.DBPrefix = +# database.default.port = 3306 + +database.default.hostname = 119.18.54.85 +database.default.database = venbaehn_nhance +database.default.username = venbaehn_nhance_user1 +database.default.password = 'iM~X7(cR+}A-' +# database.tests.DBDriver = MySQLi +# database.tests.DBPrefix = +# database.tests.port = 3306 + +#-------------------------------------------------------------------- +# CONTENT SECURITY POLICY +#-------------------------------------------------------------------- + +# contentsecuritypolicy.reportOnly = false +# contentsecuritypolicy.defaultSrc = 'none' +# contentsecuritypolicy.scriptSrc = 'self' +# contentsecuritypolicy.styleSrc = 'self' +# contentsecuritypolicy.imageSrc = 'self' +# contentsecuritypolicy.baseURI = null +# contentsecuritypolicy.childSrc = null +# contentsecuritypolicy.connectSrc = 'self' +# contentsecuritypolicy.fontSrc = null +# contentsecuritypolicy.formAction = null +# contentsecuritypolicy.frameAncestors = null +# contentsecuritypolicy.frameSrc = null +# contentsecuritypolicy.mediaSrc = null +# contentsecuritypolicy.objectSrc = null +# contentsecuritypolicy.pluginTypes = null +# contentsecuritypolicy.reportURI = null +# contentsecuritypolicy.sandbox = false +# contentsecuritypolicy.upgradeInsecureRequests = false +# contentsecuritypolicy.styleNonceTag = '{csp-style-nonce}' +# contentsecuritypolicy.scriptNonceTag = '{csp-script-nonce}' +# contentsecuritypolicy.autoNonce = true + +#-------------------------------------------------------------------- +# COOKIE +#-------------------------------------------------------------------- + +# cookie.prefix = '' +# cookie.expires = 0 +# cookie.path = '/' +# cookie.domain = '' +# cookie.secure = false +# cookie.httponly = false +# cookie.samesite = 'Lax' +# cookie.raw = false + +#-------------------------------------------------------------------- +# ENCRYPTION +#-------------------------------------------------------------------- + +# encryption.key = +# encryption.driver = OpenSSL +# encryption.blockSize = 16 +# encryption.digest = SHA512 + +#-------------------------------------------------------------------- +# HONEYPOT +#-------------------------------------------------------------------- + +# honeypot.hidden = 'true' +# honeypot.label = 'Fill This Field' +# honeypot.name = 'honeypot' +# honeypot.template = '' +# honeypot.container = '
{template}
' + +#-------------------------------------------------------------------- +# SECURITY +#-------------------------------------------------------------------- + +# security.csrfProtection = 'cookie' +# security.tokenRandomize = false +# security.tokenName = 'csrf_token_name' +# security.headerName = 'X-CSRF-TOKEN' +# security.cookieName = 'csrf_cookie_name' +# security.expires = 7200 +# security.regenerate = true +# security.redirect = false +# security.samesite = 'Lax' + +#-------------------------------------------------------------------- +# SESSION +#-------------------------------------------------------------------- + +# session.driver = 'CodeIgniter\Session\Handlers\FileHandler' +# session.cookieName = 'ci_session' +# session.expiration = 7200 +# session.savePath = null +# session.matchIP = false +# session.timeToUpdate = 300 +# session.regenerateDestroy = false + +#-------------------------------------------------------------------- +# LOGGER +#-------------------------------------------------------------------- + +# logger.threshold = 4 + +#-------------------------------------------------------------------- +# CURLRequest +#-------------------------------------------------------------------- + +# curlrequest.shareOptions = true + +#-------------------------------------------------------------------- +# Google-OAUTH-Credentials +#-------------------------------------------------------------------- + +GOOGLE_OAUTH_APP_NAME = 'OAuth' +GOOGLE_OAUTH_CLIENT_ID = '696241936560-m2mr272ge7vr2n4q36c22l3d2gdgi90l.apps.googleusercontent.com' +GOOGLE_OAUTH_CLIENT_SECRET = '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' +GOOGLE_OAUTH_REDIRECT_URI = 'http://localhost/nhance/oauth2callback' +GOOGLE_OAUTH_SCOPES = "https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/userinfo.profile" diff --git a/app/Config/Routes.php b/app/Config/Routes.php index c588b97e..a1d8b6a9 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -103,6 +103,7 @@ $routes->group("/employee", ["filter" => "authMVC"], function($routes){ $routes->get("search", "EmployeeController::search"); $routes->get("upload", "EmployeeController::employeesUplodWithEvents"); $routes->post("upload", "EmployeeController::employeesUplodWithEvents"); + $routes->get("excel_error/(:any)", "EmployeeController::getExcelFileErrors/$1"); }); diff --git a/app/Controllers/EmployeeController.php b/app/Controllers/EmployeeController.php index 483e6c61..531eeb86 100644 --- a/app/Controllers/EmployeeController.php +++ b/app/Controllers/EmployeeController.php @@ -110,12 +110,18 @@ class EmployeeController extends AdminController // print_r($this->request->getPost('upload-action-type')); // die(); // $empServiceController = new EmployeeServiceController(); - // $res = $empServiceController->fileFormatValidationController('12'); - // // dd($res); + // $res = $empServiceController->excelFileFormatValidation(['file_id' => '34']); + // dd($res); - // if(isset($res) && count($res)) + // $empServiceController = new EmployeeServiceController(); + // $res = $empServiceController->excelFileDataValidation(['file_id' => '12']); + // dd($res); + + // if(isset($res['error_summary']) && count($res['error_summary'])) // { - // $failure_reason = json_encode((json_encode($res))); + // $res['error_summary'] = (array_count_values($res['error_summary'])); + // $failure_reason = ((json_encode($res))); + // // dd($failure_reason); // $this->fileModel->where('id', '12')->set(['status' => 'failed','reason' => $failure_reason])->update(); // dd($failure_reason); // } @@ -145,6 +151,7 @@ class EmployeeController extends AdminController //process post variable entry in file table $loggedInUserID = get_session_userid(); + // $loggedInUserID = 8; $client_id = $this->request->getPost('client_id'); $policy_id = $this->request->getPost('policy_id'); @@ -155,18 +162,27 @@ class EmployeeController extends AdminController $this->myLogger->logme("error",'{file_id} uploaded success',['file_id' => $file_id]); //start validation process + + $empServiceController = new EmployeeServiceController(); + $result = $empServiceController->excelFileFormatValidation($file_id); + //endof validation process + if(isset($result['error_summary']) && count($result['error_summary'])) + { + return $this->respond(['dataStatus' => false,'code' => 404,'message' => 'file rejected with errors'], 200); + } - //en dof validation process return $this->respond(['dataStatus' => true,'code' => 200,'data' => 'file upload success'], 200); } - $data['actions'] = ['inception' => 'Inception','addition' => 'Addition','deletion' => 'Deletion','correction' =>'Correction','si_enhancement' =>'SI Enhancement']; + $data['actions'] = ['inception' => 'Inception + Addition + Deletion','correction' =>'Correction','si_enhancement' =>'SI Enhancement']; $data['fileList'] = $this->fileModel - ->select(['files.*','up.emp_code','up.first_name']) + ->select(['files.*','up.emp_code','up.first_name','pm.name as policy_name','c.short_name']) ->join('user_profiles up','files.created_by = up.id') + ->join('policies pm','files.policy_id = pm.id') + ->join('clients c','files.client_id = c.id') ->where('files.created_by',8)->orderBy('files.created_at','desc')->findAll(); - // print_r($data['fileList']);die(); + // dd($data['fileList']);die(); if($this->request->getMethod() == "get") { $this->loadLayout('employee_upload',$data); @@ -174,6 +190,13 @@ class EmployeeController extends AdminController } + public function getExcelFileErrors() + { + $file_id = $this->request->uri->getSegment(3); + + echo view('excel_errors'); + } + } diff --git a/app/Controllers/EmployeeServiceController.php b/app/Controllers/EmployeeServiceController.php index 417ee77e..5d97f51b 100644 --- a/app/Controllers/EmployeeServiceController.php +++ b/app/Controllers/EmployeeServiceController.php @@ -11,8 +11,11 @@ use Psr\Log\LoggerInterface; use App\Models\EmployeeModel; use App\Models\EmployeePolicyModel; use App\Models\ClientModel; +use App\Models\ClientPolicyModel; use App\Models\FileModel; +use App\Controllers\Jobs ; + use PhpOffice\PhpSpreadsheet\Spreadsheet; class EmployeeServiceController extends AdminController @@ -23,9 +26,10 @@ class EmployeeServiceController extends AdminController protected $employeePolicyModel; protected $clientModel; protected $fileModel; - protected $general_relationships = ['self' => ['name' => 'Self', 'sex' => 'M','age_min' => 18,'age_max' => null], 'spouse' => ['name' => 'Spouse', 'sex' => 'F','age_min' => 18,'age_max' => null], 'son' => ['name' => 'Son', 'sex' => 'M','age_min' => null,'age_max' => 25], 'daughter' => ['name' => 'Daughter', 'sex' => 'F','age_min' => null,'age_max' => 25], 'father' => ['name' => 'Father', 'sex' => 'M','age_min' => 18,'age_max' => null], 'mother' => ['name' => 'Mother', 'sex' => 'F','age_min' => 18,'age_max' => null], 'father-in-law' => ['name' => 'Father in Law', 'sex' => 'M','age_min' => 18,'age_max' => null], 'mother-in-law' => ['name' => 'Mother in Law', 'sex' => 'F','age_min' => 18,'age_max' => null]]; + protected $clientPolicyModel; + protected $general_relationships = ['self' => ['name' => 'Self', 'gender' => 'M','age_min' => 18,'age_max' => null], 'spouse' => ['name' => 'Spouse', 'gender' => 'F','age_min' => 18,'age_max' => null], 'son' => ['name' => 'Son', 'gender' => 'M','age_min' => null,'age_max' => 25], 'daughter' => ['name' => 'Daughter', 'gender' => 'F','age_min' => null,'age_max' => 25], 'father' => ['name' => 'Father', 'gender' => 'M','age_min' => 18,'age_max' => null], 'mother' => ['name' => 'Mother', 'gender' => 'F','age_min' => 18,'age_max' => null], 'father-in-law' => ['name' => 'Father in Law', 'gender' => 'M','age_min' => 18,'age_max' => null], 'mother-in-law' => ['name' => 'Mother in Law', 'gender' => 'F','age_min' => 18,'age_max' => null]]; - protected $inception_excel_columns = ['sno' => ['col_idx' => 0,'col_cell_name' => 'A','col_name' => 'S.No','is_mandatory' => true,'data_type' => 'str','format' => null,'allowed_values' => null],'emp_id' => ['col_idx' => 1,'col_cell_name' => 'B','col_name' => 'EMP ID','is_mandatory' => true,'data_type' => 'str','format' => null,'allowed_values' => null],'name_of_emp_dep' => ['col_idx' => 2,'col_cell_name' => 'C','col_name' => 'NAME OF EMP/DEP','is_mandatory' => true,'data_type' => 'str','format' => null,'allowed_values' => null],'dob' => ['col_idx' => 3,'col_cell_name' => 'D','col_name' => 'DOB','is_mandatory' => true,'data_type' => 'str','format' => 'd-M-Y','allowed_values' => null,'custom' => 'check_dob_diff','params' => ['row','relationship']],'sex' => ['col_idx' => 4,'col_cell_name' => 'E','col_name' => 'SEX','is_mandatory' => true,'data_type' => 'str','format' => null,'allowed_values' => ['M','F']],'relationship' => ['col_idx' => 5,'col_cell_name' => 'F','col_name' => 'RELATIONSHIP','is_mandatory' => true,'data_type' => 'str','format' => null,'allowed_values' => null,'custom' => 'check_relationship','params' => ['row','relationship']],'basic_cover_si' => ['col_idx' => 6,'col_cell_name' => 'G','col_name' => 'BASIC COVER SI','is_mandatory' => true,'data_type' => 'str','format' => null,'allowed_values' => null],'doj' => ['col_idx' => 7,'col_cell_name' => 'H','col_name' => 'DOJ','is_mandatory' => 'custom','data_type' => 'str','format' => 'd-M-Y','allowed_values' => null,'custom' => 'check_doj','params' => ['row']],'basic_pay' => ['col_idx' => 8,'col_cell_name' => 'I','col_name' => 'Basic Pay','is_mandatory' => 'custom','data_type' => 'str','format' => null,'allowed_values' => null,'custom' => 'check_basic_pay','params' => ['row']],'band_grade' => ['col_idx' => 9,'col_cell_name' => 'J','col_name' => 'Band/Grade','is_mandatory' => 'custom','data_type' => 'str','format' => null,'allowed_values' => null,'custom' => 'check_employee_band','params' => ['row']],'designation' => ['col_idx' => 10,'col_cell_name' => 'K','col_name' => 'Designation','is_mandatory' => false,'data_type' => 'str','format' => null,'allowed_values' => null],'phone' => ['col_idx' => 11,'col_cell_name' => 'L','col_name' => 'Phone','is_mandatory' => false,'data_type' => 'str','format' => null,'allowed_values' => null],'email' => ['col_idx' => 12,'col_cell_name' => 'M','col_name' => 'Email','is_mandatory' => false,'data_type' => 'str','format' => null,'allowed_values' => null],'pre_existing_ailments' => ['col_idx' => 13,'col_cell_name' => 'N','col_name' => 'PRE EXISTING AILMENTS','is_mandatory' => true,'data_type' => 'str','format' => null,'allowed_values' => ['0','1']]]; + protected $inception_excel_columns = ['sno' => ['col_idx' => 0,'col_cell_name' => 'A','col_name' => 'S.No','is_mandatory' => true,'data_type' => 'str','format' => null,'allowed_values' => null],'emp_id' => ['col_idx' => 1,'col_cell_name' => 'B','col_name' => 'EMP ID','is_mandatory' => true,'data_type' => 'str','format' => null,'allowed_values' => null],'name_of_emp_dep' => ['col_idx' => 2,'col_cell_name' => 'C','col_name' => 'NAME OF EMP/DEP','is_mandatory' => true,'data_type' => 'str','format' => null,'allowed_values' => null],'dob' => ['col_idx' => 3,'col_cell_name' => 'D','col_name' => 'DOB','is_mandatory' => ['I','A','DA'],'data_type' => 'str','format' => 'd-M-Y','allowed_values' => null,'custom' => 'check_dob_diff','params' => ['row','relationship']],'gender' => ['col_idx' => 4,'col_cell_name' => 'E','col_name' => 'Gender','is_mandatory' => ['I','A','DA'],'data_type' => 'str','format' => null,'allowed_values' => ['M','F']],'relationship' => ['col_idx' => 5,'col_cell_name' => 'F','col_name' => 'RELATIONSHIP','is_mandatory' => ['I','A','DA'],'data_type' => 'str','format' => null,'allowed_values' => null,'custom' => 'check_relationship','params' => ['row','relationship']],'basic_cover_si' => ['col_idx' => 6,'col_cell_name' => 'G','col_name' => 'BASIC COVER SI','is_mandatory' => ['I','A','DA'],'data_type' => 'str','format' => null,'allowed_values' => null],'doj' => ['col_idx' => 7,'col_cell_name' => 'H','col_name' => 'DOJ','is_mandatory' => false,'data_type' => 'str','format' => 'd-M-Y','allowed_values' => null,'custom' => 'check_doj','params' => ['row']],'basic_pay' => ['col_idx' => 8,'col_cell_name' => 'I','col_name' => 'Basic Pay','is_mandatory' => false,'data_type' => 'str','format' => null,'allowed_values' => null,'custom' => 'check_basic_pay','params' => ['row']],'band_grade' => ['col_idx' => 9,'col_cell_name' => 'J','col_name' => 'Band/Grade','is_mandatory' => false,'data_type' => 'str','format' => null,'allowed_values' => null,'custom' => 'check_employee_band','params' => ['row']],'designation' => ['col_idx' => 10,'col_cell_name' => 'K','col_name' => 'Designation','is_mandatory' => false,'data_type' => 'str','format' => null,'allowed_values' => null],'phone' => ['col_idx' => 11,'col_cell_name' => 'L','col_name' => 'Phone','is_mandatory' => false,'data_type' => 'str','format' => null,'allowed_values' => null],'email' => ['col_idx' => 12,'col_cell_name' => 'M','col_name' => 'Email','is_mandatory' => false,'data_type' => 'str','format' => null,'allowed_values' => null],'pre_existing_ailments' => ['col_idx' => 13,'col_cell_name' => 'N','col_name' => 'PRE EXISTING AILMENTS','is_mandatory' => ['I','A','DA'],'data_type' => 'str','format' => null,'allowed_values' => ['0','1']],'change_event' => ['col_idx' => 14,'col_cell_name' => 'O','col_name' => 'Change event','is_mandatory' => ['A','DA','D'],'data_type' => 'str','format' => null,'allowed_values' => null],'date_of_exit' => ['col_idx' => 15,'col_cell_name' => 'P','col_name' => 'Date of exit','is_mandatory' => ['D'],'data_type' => 'str','format' => 'd-M-Y','allowed_values' => null],'reason_for_exit' => ['col_idx' => 16,'col_cell_name' => 'Q','col_name' => 'Reason for exit','is_mandatory' => ['D'],'data_type' => 'str','format' => null,'allowed_values' => null],'action' => ['col_idx' => 17,'col_cell_name' => 'R','col_name' => 'Action','is_mandatory' => true,'data_type' => 'str','format' => null,'allowed_values' => ['I','A','D','DA'] ]]; public function __construct() { // helper('utility'); @@ -35,13 +39,15 @@ class EmployeeServiceController extends AdminController $this->employeePolicyModel = new EmployeePolicyModel(); $this->clientModel = new ClientModel(); $this->fileModel = new FileModel(); + $this->clientPolicyModel = new ClientPolicyModel(); } - public function fileFormatValidationController($file_id) + public function excelFileFormatValidation($params) { helper('excel_util_helper'); //get file name // check_dob_diff('4-APr-1990');die(); + $file_id = $params['file_id']; $file = $this->fileModel->find($file_id); // dd($file); $return = []; @@ -56,8 +62,11 @@ class EmployeeServiceController extends AdminController if(!file_exists($file_name_with_path)) { //file not found update status and reason - $this->fileModel->where('id', $file_id)->set(['status' => 'failed','reason' => 'file not found'])->update(); - return array('status' => false, 'msg' => 'file not found'); + $message = "Physcial file not found"; + // echo $message; + $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); } //start validation process @@ -91,30 +100,30 @@ class EmployeeServiceController extends AdminController if($total_defined_columns != $excel_columns_count) { //columns count mismatch - $message = "columns count mismatch. Expected - $total_defined_columns and received - $excel_columns"; - echo $message; + $message = "File columns count mismatch. Expected - $total_defined_columns and received - $excel_columns_count"; + // echo $message; $this->myLogger->logme('error',($message . ' for file id ' . $file_id)); - //$model->where('id', $file_id)->set(['status' => 'failed','reason' => $message])->update(); - return array('status' => false, 'msg' => $message); + $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); } //check columns order in excel - $column_count_res = check_columns_count($columns_to_check,$excel_columns); + $column_count_res = check_columns_name($columns_to_check,$excel_columns); if(isset($column_count_res) && count($column_count_res)) { //columns count mismatch $message = implode("\n", $column_count_res); - echo $message; + // echo $message; $this->myLogger->logme('error',($message . ' for file id ' . $file_id)); - // $model->where('id', $file_id)->set(['status' => 'failed','reason' => $message])->update(); - return array('status' => false, 'msg' => $message); + $this->fileModel->where('id', $file_id)->set(['status' => 'failed','reason' => json_encode(['error_summary' => array_count_values([6]), 'error_data' => $message])])->update(); + return array('error_summary' => [6], 'error_data' => $message); } //start other checks - $result = []; - $keys = array_keys($this->inception_excel_columns); + $result = ['error_type' => 1,'error_summary' => [], 'error_data' => [] ]; + $keys = array_keys($columns_to_check); // print_r($keys);die(); //remove header @@ -123,6 +132,9 @@ class EmployeeServiceController extends AdminController foreach ($excel_data as $row_key => $row) { + //define row wise action/event in temporary variable + $current_column_action = null; + if($file['action'] == 'inception'){ $current_column_action = $row[17]; } //1. avoid empty rows if(check_row_is_empty_or_null($row)) { @@ -131,14 +143,71 @@ class EmployeeServiceController extends AdminController //iterate each row foreach ($row as $col_key => $col) { + + $is_mandatory = $this->inception_excel_columns[$keys[$col_key]]['is_mandatory']; + $format = $this->inception_excel_columns[$keys[$col_key]]['format']; + $allowed_values = $this->inception_excel_columns[$keys[$col_key]]['allowed_values']; + $custom_function = isset($this->inception_excel_columns[$keys[$col_key]]['custom']) ? $this->inception_excel_columns[$keys[$col_key]]['custom'] : null; + $binding_params = isset($this->inception_excel_columns[$keys[$col_key]]['params']) ? $this->inception_excel_columns[$keys[$col_key]]['params'] : null; + $column_dispaly_name = $this->inception_excel_columns[$keys[$col_key]]['col_name']; + $column_index = $this->inception_excel_columns[$keys[$col_key]]['col_idx']; + $column_cell = $this->inception_excel_columns[$keys[$col_key]]['col_cell_name']; + + //mandatory check - if(isset($this->inception_excel_columns[$keys[$col_key]]['custom'])) + if(is_bool($is_mandatory) && $is_mandatory === true) + { + if($col == "" || $col == NULL) + { + array_push($result['error_summary'],1); //push error code for summary + $result['error_data'][$row_key][$keys[$col_key]]['col_name'] = $column_dispaly_name; //push column name + $result['error_data'][$row_key][$keys[$col_key]]['col_idx'] = $column_index; //push column index + $result['error_data'][$row_key][$keys[$col_key]]['error'][] = 'Value is mandatory'; //push exact error desc + } + } + + //if is_mandatory is array (action based mandatory check) + if($current_column_action != null && is_array($is_mandatory) && in_array(strtoupper(trim($current_column_action)),$is_mandatory)) + { + $allowed_actions = $this->inception_excel_columns[$keys[$col_key]]['is_mandatory']; + if($col == "" || $col == NULL) + { + array_push($result['error_summary'],1); + $result['error_data'][$row_key][$keys[$col_key]]['col_name'] = $column_dispaly_name; //push column name + $result['error_data'][$row_key][$keys[$col_key]]['col_idx'] = $column_index; //push column index + $result['error_data'][$row_key][$keys[$col_key]]['error'][] = 'Value is mandatory for this action/event'; + } + } + + //format check + if(isset($format)) + { + $format_error = check_excel_date_format($col,$format); + if(!$format_error['status']) + { + array_push($result['error_summary'],2); + $result['error_data'][$row_key][$keys[$col_key]]['col_name'] = $column_dispaly_name; //push column name + $result['error_data'][$row_key][$keys[$col_key]]['col_idx'] = $column_index; //push column index + $result['error_data'][$row_key][$keys[$col_key]]['error'][] = $format_error['error']; + } + } + + //allowed values check + if($is_mandatory === true && isset($allowed_values) && is_array($allowed_values)) { - $custom_function = $this->inception_excel_columns[$keys[$col_key]]['custom']; - // echo $custom_function; - - $binding_params = $this->inception_excel_columns[$keys[$col_key]]['params']; + if(!in_array(trim($col),$allowed_values)) + { + array_push($result['error_summary'],3); + $result['error_data'][$row_key][$keys[$col_key]]['col_name'] = $column_dispaly_name; //push column name + $result['error_data'][$row_key][$keys[$col_key]]['col_idx'] = $column_index; //push column index + $result['error_data'][$row_key][$keys[$col_key]]['error'][] = "Value not allowed: Expected ".implode(",",$allowed_values)." and received $col"; + } + } + + //custom function check + if(isset($custom_function)) + { //convert string params into PHP variables // Create an array of variables to pass custom helper funcitons $param_values = []; @@ -146,43 +215,169 @@ class EmployeeServiceController extends AdminController // dd(($param_values));//die(); $res = call_user_func_array($custom_function,$param_values); // print_r($res['status']);die(); - if($res['status'] === false) { $result[$row_key][$keys[$col_key]][] = $res['error']; } + if($res['status'] === false) + { + array_push($result['error_summary'],4); + $result['error_data'][$row_key][$keys[$col_key]]['col_name'] = $column_dispaly_name; //push column name + $result['error_data'][$row_key][$keys[$col_key]]['col_idx'] = $column_index; //push column index + $result['error_data'][$row_key][$keys[$col_key]]['error'][] = $res['error']; + } } - - if($this->inception_excel_columns[$keys[$col_key]]['is_mandatory'] === true) - { - if($col == "" || $col == NULL) { $result[$row_key][$keys[$col_key]][] = 'value is mandatory'; } - } - //format check - if(isset($this->inception_excel_columns[$keys[$col_key]]['format'])) - { - $format_error = check_excel_date_format($col,$this->inception_excel_columns[$keys[$col_key]]['format']); - if(!$format_error['status']) - { - $result[$row_key][$keys[$col_key]][] = $format_error['error']; - } - } - - //allowed values check - if(isset($this->inception_excel_columns[$keys[$col_key]]['allowed_values']) && is_array($this->inception_excel_columns[$keys[$col_key]]['allowed_values'])) - { - $allowed_values = $this->inception_excel_columns[$keys[$col_key]]['allowed_values']; - if(!in_array($col,$allowed_values)) - { - $result[$row_key][$keys[$col_key]][] = "Value not allowed: Expected ".implode(",",$allowed_values)." and received $col"; - } - } - } } + if(isset($result['error_summary']) && count($result['error_summary'])) + { + $result['error_summary'] = array_count_values($result['error_summary']); + $status = 'failed'; + $failure_reason = ((json_encode($result))); + $this->fileModel->where('id', $file_id)->set(['status' => $status,'reason' => $failure_reason])->update(); + $this->myLogger->logme("error",'{file_id} uploaded failed',['file_id' => $file_id]); + //return $this->respond(['dataStatus' => true,'code' => 404,'data' => 'file upload failed with errors'], 200); + // dd($failure_reason); + + + //print_r($r); + } + else //trigger next data validation via job queue server + { + //proceed next data level validation in JOB queue + $job_details = new Jobs(); + + $r = Jobs::addJob(['job_name' => 'excelFileDataValidation','payload' => ['file_id' => $file_id]]); + } return $result; } + public function excelFileDataValidation($params) + { + helper('excel_util_helper'); + //get file name + $file_id = $params['file_id']; + $file = $this->fileModel->find($file_id); + // dd($file); + $return = []; + if(!isset($file)) + { + //file not found in DB + return array('status' => false, 'msg' => 'file not found in DB'); + } + $file_name_with_path = WRITEPATH."/uploads/excel/".$file['file_name']; + + //check physical file + if(!file_exists($file_name_with_path)) + { + //file not found update status and reason + $message = "Physical file not found"; + // echo $message; + $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); + } + + $columns_to_check = []; + if($file['action'] == 'inception'){ $columns_to_check = $this->inception_excel_columns; } + + // get policy and rack details + $policy_terms = $this->clientPolicyModel->getPolicyTermsJson($file['client_id'],$file['policy_id']); + // dd($policy_terms); + $policy_terms = json_decode($policy_terms[0]->policy_terms); + $policy_terms = (array) $policy_terms;// convert obj to array + // dd($policy_terms); + //get excel data + $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_name_with_path); + $sheet = $spreadsheet->getActiveSheet(); + + $highestRowAndColumn = $sheet->getHighestRowAndColumn(); + $excel_data = $sheet->rangeToArray('A1:' . $highestRowAndColumn['column'] . $highestRowAndColumn['row']); + // dd($excel_data); + $result = ['error_type' => 2,'error_summary' => [], 'error_data' => [] ]; + $keys = array_keys($columns_to_check); + // print_r($keys);die(); + + //remove header + unset($excel_data[0]); + $relationship = $this->general_relationships; + + $employee_data_group_by_family = data_group_by_family($excel_data); + // dd($employee_data_group_by_family); + foreach ($employee_data_group_by_family as $emp_id => $family) + { + + + //check name dup within a family + $res = name_dup_check_within_family($family); + if(count($res)) + { + foreach($res as $k => $rowid) + { + array_push($result['error_summary'],7); // dup entry in excel file + $result['error_data'][$rowid]['name_of_emp_dep']['error'][] = "Twofold Name found within family"; + } + } + //check allowed dependent count and relationship conflict within family at policy level + // if($policy_terms['family_floater'] == true) + // { + // dd($policy_terms['family_floaters']); + // } + // die('check'); + $res = check_dependent_conflict($family,$policy_terms); + // dd($res); + if(!$res['status']) + { + foreach($res['error_data'] as $key => $value) + { + array_push($result['error_summary'],$value['code']); //record not avail for deletion + $result['error_data'][$rowid][($value['col_name'])]['error'][] = $value['msg']; + } + } + + //check dup with empid and name with db + $res = name_and_empid_check_in_db($family,$file['client_id'],$file['policy_id']); + // print_r($result); + // echo '
'; + // print_r($res); + if(count($res['del'])) + { + foreach($res['del'] as $k => $rowid) + { + array_push($result['error_summary'],10); //record not avail for deletion + $result['error_data'][$rowid]['name_of_emp_dep']['error'][] = "Record Not found for deletion"; + } + } + if(count($res['i'])) + { + foreach($res['i'] as $k => $rowid) + { + array_push($result['error_summary'],9); //dup entry + $result['error_data'][$rowid]['name_of_emp_dep']['error'][] = "Record already exists"; + } + } + } + + // dd($result); + if(isset($result['error_summary']) && count($result['error_summary'])) + { + $result['error_summary'] = array_count_values($result['error_summary']); + $status = 'failed'; + $failure_reason = ((json_encode($result))); + $this->fileModel->where('id', $file_id)->set(['status' => $status,'reason' => $failure_reason])->update(); + $this->myLogger->logme("error",'{file_id} uploaded failed',['file_id' => $file_id]); + //return $this->respond(['dataStatus' => true,'code' => 404,'data' => 'file upload failed with errors'], 200); + // dd($failure_reason); + + + + } + return $result; + + } + + } diff --git a/app/Controllers/JobWorker.php b/app/Controllers/JobWorker.php index 98e851dc..f3a2ab2a 100644 --- a/app/Controllers/JobWorker.php +++ b/app/Controllers/JobWorker.php @@ -14,7 +14,7 @@ class JobWorker extends AdminController * Constructs the class */ - private static $event_class_mapping = ['add' => ['type' => 'HC','handler' => 'App\\Helpers\\HttpRequestHelper'], 'sub' => ['type' => 'CC','handler' => 'App\\Controllers\\Jobs\SubJob'],'fancy_date_time_format' => [ 'type' => 'HF','handler' => 'fancy_date_time_format'],'addNumber' => ['type' => 'HC','handler' => 'App\\Model\\HttpRequestHelper']]; + private static $event_class_mapping = ['add' => ['type' => 'HC','handler' => 'App\\Helpers\\HttpRequestHelper'], 'sub' => ['type' => 'CC','handler' => 'App\\Controllers\\Jobs\SubJob'],'fancy_date_time_format' => [ 'type' => 'HF','handler' => 'fancy_date_time_format'],'addNumber' => ['type' => 'HC','handler' => 'App\\Model\\HttpRequestHelper'],'excelFileFormatValidation' => ['type' => 'CC','handler' => 'App\\Controllers\\EmployeeServiceController'],'excelFileDataValidation' => ['type' => 'CC','handler' => 'App\\Controllers\\EmployeeServiceController'],'employeeOnboard' => ['type' => 'CC','handler' => 'App\\Controllers\\EmployeeServiceController']]; public function __construct() { // echo 'HiC';//die(); @@ -143,7 +143,8 @@ class JobWorker extends AdminController $job->id,$job->uuid ]); - echo "Job $job->id $job_status. Response - $response \n"; + // echo "Job $job->id $job_status. Response - $response \n"; + echo "Job $job->id $job_status \n"; } else { diff --git a/app/Controllers/Jobs.php b/app/Controllers/Jobs.php index 33eee1fb..56855efd 100644 --- a/app/Controllers/Jobs.php +++ b/app/Controllers/Jobs.php @@ -57,6 +57,7 @@ class Jobs extends AdminController catch(\Exception $e) { $message = $e->getMessage(); + return $message; $myLogger->logme('error','{messgae}',['messgae' => $message]); } } diff --git a/app/Helpers/excel_util_helper.php b/app/Helpers/excel_util_helper.php index 1e628dbe..1f1e9b47 100644 --- a/app/Helpers/excel_util_helper.php +++ b/app/Helpers/excel_util_helper.php @@ -1,7 +1,9 @@ "; } } @@ -55,39 +57,48 @@ if(!function_exists('check_relationship')) { // print_r($col);print_r($relationship); // echo '
'; - if($row[5] != null && $row[4] != null) + if($row[17] != null && in_array(strtoupper($row[17]), ['I','A','DA']))// check rule only of action column data available { - $slug = \Config\Services::slug(); - $col = $slug->slugify($row[5]); - // echo $col;die(); - if($col != 'self' && $col != 'spouse') + if($row[5] != null && $row[4] != null)//$row[5] = relationship $row[4] = Gender { - if($relationship[ $col ]['sex'] != $row[4]) + $slug = \Config\Services::slug(); + $col = $slug->slugify($row[5]); + // echo $col;die(); + if($col != 'self' && $col != 'spouse') { - $error = "Gender relationship conflict: Expected ".$relationship[ $col ]['sex'].", received $row[4]"; - return array('status' => false,'error' => $error); + if($relationship[ $col ]['gender'] != $row[4]) + { + $error = "Gender relationship conflict: Expected ".$relationship[ $col ]['gender'].", received $row[4]"; + return array('status' => false,'error' => $error); + } + } - + return array('status' => true); + } + else + { + return array('status' => false,'error' => 'Rule Conflict: Both Relationship and Gender required for check relationship conflict'); } - return array('status' => true); - } - else - { - return array('status' => false,'error' => 'Rule Conflict: Both Relationship or Gender required'); } + else { return array('status' => true); } // in else condition no need to check rule, just return true } } if(!function_exists('check_doj')) { + function check_doj($row) { - $slug = \Config\Services::slug(); - $relationship = $slug->slugify($row[5]); - // echo $relationship;echo $row[7]; - if($relationship == 'self' && $row[7] == "") { return array('status' => false,'error' => "DOJ mandantory for self"); } - return array('status' => true); + if($row[17] != null && in_array(strtoupper($row[17]), ['I','A','DA']))// check rule only of action column data available + { + $slug = \Config\Services::slug(); + $relationship = $slug->slugify($row[5]); + // echo $relationship;echo $row[7]; + if($relationship == 'self' && $row[7] == "") { return array('status' => false,'error' => "DOJ mandantory for self"); } + return array('status' => true); + } + else { return array('status' => true); } // in else condition no need to check rule, just return true } } @@ -96,11 +107,14 @@ if(!function_exists('check_employee_band')) { function check_employee_band($row) { - $slug = \Config\Services::slug(); - $relationship = $slug->slugify($row[5]); - // echo $relationship;echo $row[7]; - if($relationship == 'self' && $row[9] == "") { return array('status' => false,'error' => "Band mandantory for self"); } - return array('status' => true); + if($row[17] != null && in_array(strtoupper($row[17]), ['I','A','DA']))// check rule only of action column data available + { + $slug = \Config\Services::slug(); + $relationship = $slug->slugify($row[5]); + // echo $relationship;echo $row[7]; + if($relationship == 'self' && $row[9] == "") { return array('status' => false,'error' => "Band mandantory for self"); } + return array('status' => true); + }else { return array('status' => true); } // in else condition no need to check rule, just return true } } @@ -108,11 +122,14 @@ if(!function_exists('check_basic_pay')) { function check_basic_pay($row) { - $slug = \Config\Services::slug(); - $relationship = $slug->slugify($row[5]); - // echo $relationship;echo $row[7]; - if($relationship == 'self' && $row[8] == "") { return array('status' => false,'error' => "Basic pay mandantory for self"); } - return array('status' => true); + if($row[17] != null && in_array(strtoupper($row[17]), ['I','A','DA']))// check rule only of action column data available + { + $slug = \Config\Services::slug(); + $relationship = $slug->slugify($row[5]); + // echo $relationship;echo $row[7]; + if($relationship == 'self' && $row[8] == "") { return array('status' => false,'error' => "Basic pay mandantory for self"); } + return array('status' => true); + }else { return array('status' => true); } // in else condition no need to check rule, just return true } } @@ -121,39 +138,230 @@ if (!function_exists('check_dob_diff')) { function check_dob_diff($row,$relationships) { // echo 'called'; - if($row[3] != null && $row[5] != null) + if($row[17] != null && in_array(strtoupper($row[17]), ['I','A','DA']))// check rule only of action column data available { - $dob = change_date_format($row[3],'d-M-Y','Y-m-d'); - // echo $row[3].' - '.$dob;echo '
'; - $currentDateTime = new DateTime();//die(); - $passedDateTime = new DateTime($dob); - $interval = $currentDateTime->diff($passedDateTime); + if($row[3] != null && $row[5] != null) + { + $dob = change_date_format($row[3],'d-M-Y','Y-m-d'); + // echo $row[3].' - '.$dob;echo '
'; + $currentDateTime = new DateTime();//die(); + $passedDateTime = new DateTime($dob); + $interval = $currentDateTime->diff($passedDateTime); - $slug = \Config\Services::slug(); - $relationship = $slug->slugify($row[5]); - $age_min = $relationships[$relationship]['age_min']; - $age_max = $relationships[$relationship]['age_max']; - // echo $relationship.','.$age_min.'-'.$age_max; - if($age_min !== null && $age_min > $interval->y) - { - return array('status' => false,'error' => "Age conflict : minimum $age_min yrs allowed, received $interval->y"); - } - if($age_max !== null && $age_max < $interval->y) - { - return array('status' => false,'error' => "Age conflict : maximum $age_max yrs allowed, received $interval->y"); - } - return array('status' => true); - } - else + $slug = \Config\Services::slug(); + $relationship = $slug->slugify($row[5]); + $age_min = $relationships[$relationship]['age_min']; + $age_max = $relationships[$relationship]['age_max']; + // echo $relationship.','.$age_min.'-'.$age_max; + if($age_min !== null && $age_min > $interval->y) + { + return array('status' => false,'error' => "Age conflict : minimum $age_min yrs allowed, received $interval->y"); + } + if($age_max !== null && $age_max < $interval->y) + { + return array('status' => false,'error' => "Age conflict : maximum $age_max yrs allowed, received $interval->y"); + } + return array('status' => true); + } + else + { + return array('status' => false,'error' => 'Rule Conflict: Both DOB and Relationship required for age check'); + } + }else { return array('status' => true); } // in else condition no need to check rule, just return true + } +} + +if (!function_exists('data_group_by_family')) +{ + function data_group_by_family($emp_data) + { + $result = []; + foreach ($emp_data as $rkey => $row) { - return array('status' => false,'error' => 'Rule Conflict: Both DOB or Relationship required'); + if(!check_row_is_empty_or_null($row)) + { + $result[$row[1]][] = $row; + } + } + + return $result; + } +} + +if (!function_exists('name_dup_check_within_family')) +{ + function name_dup_check_within_family($family_data) + { + $result = []; + $temp = []; + foreach ($family_data as $rkey => $row) + { + if(in_array($row[2],$temp)) + { + array_push($result,$row[0]); + } + else + { + array_push($temp, $row[2]); + } + + } + + return $result; } } - +if (!function_exists('name_and_empid_check_in_db')) +{ + function name_and_empid_check_in_db($family_data,$client_id,$policy_id) + { + $employeeModel = new EmployeeModel(); + $result = ['del' => [],'i' => []]; + foreach ($family_data as $rkey => $row) + { + $res = $employeeModel + ->join('client_policy cp',"employees.client_id = cp.client_id") + ->join('employee_polices ep',"cp.id = ep.client_policy_id AND employees.id = ep.employee_id") + ->where("cp.policy_id",$policy_id) + ->where("employees.client_id",$client_id) + ->like('name',$row[2],'both')->like('emp_code',$row[1],'both') + ->findAll(); + + + if(count($res)) + { + if($row[17] == 'D') + { + array_push($result['del'],$row[0]); + } + else + { + array_push($result['i'],$row[0]); + } + + } + } + + return $result; + } +} + +if (!function_exists('check_dependent_conflict')) +{ + function check_dependent_conflict($family_data,$policy_terms) + { + $result = ['status' => true]; + + $self_gender = null; + $spouse_gender = null; + + $allowed_spouse_count = 0; + $received_spouse_count = 0; + $allowed_child_count = 0; + $received_child_count = 0; + $allowed_parents_count = 0; + $received_parents_count = 0; + $allowed_parent_in_laws_count = 0; + $received_parent_in_laws_count = 0; + $overall_famility_relationships = []; + $temp_counts = [2,3,4,5,6,7,8,9,10]; //temp variable for check relation repetaed count + $slug = \Config\Services::slug(); + + if($policy_terms['family_floater'] == true) + { + + // $temp_string = implode(" ",$policy_terms['family_floaters']); + $temp = $policy_terms['family_floaters']; + $allowed_child_count = count(preg_grep('/child/',$temp)); + $allowed_spouse_count = count(preg_grep('/spouse/',$temp)); + $allowed_parents_count = count(preg_grep('/parent[12]/',$temp)); + $allowed_parent_in_laws_count = count(preg_grep('/parent_in_law[12]/',$temp)); + + foreach ($family_data as $key => $row) + { + $relationship = $slug->slugify($row[5]); + + if($row[17] != 'D' && $relationship != 'son' && $relationship != 'daughter') + { + array_push($overall_famility_relationships, $relationship); + } + + + if($relationship == 'self') + { + $self_gender = $row[4]; + } + if($relationship == 'spouse') + { + $spouse_gender = $row[4]; + $received_spouse_count = $received_spouse_count + 1; + } + if($relationship == 'son' || $relationship == 'daughter') + { + $received_child_count = $received_child_count + 1; + } + if($relationship == 'father' || $relationship == 'mother') + { + $received_parents_count = $received_parents_count + 1; + } + if($relationship == 'father-in-law' || $relationship == 'mother-in-law') + { + $received_parent_in_laws_count = $received_parent_in_laws_count + 1; + } + + } + + // print_r($overall_famility_relationships); + // echo '
'; + if($row[17] != 'D') + { + $repeated_relationships_count = array_count_values($overall_famility_relationships); + // print_r($repeated_relationships_count); + // echo '
'; + $repeated_count = array_intersect($repeated_relationships_count,$temp_counts); + if(is_array($repeated_count) && count($repeated_count)) + { + $result['status'] = false; + $result['error_data'][] = ['code' => 13,'col_name' => 'relationship','msg' => 'Rule conflict: Twofold relationship found within family']; + } + } + // print_r($repeated_count); + // echo "==============="; + // echo "
"; + + + // print_r(array_values(array_count_values($overall_famility_relationships))); + // print_r(in_array(2,array_values(array_count_values($overall_famility_relationships)))); + + if($self_gender == $spouse_gender) + { + $result['status'] = false; + $result['error_data'][] = ['code' => 4,'col_name' => 'gender','msg' => 'Rule conflict: Self and Spouse cannot be same gender']; + } + if(($allowed_spouse_count < $received_spouse_count) || ($allowed_child_count < $received_child_count) || ($allowed_parents_count < $received_parents_count) || ($allowed_parent_in_laws_count < $received_parent_in_laws_count)) + { + $result['status'] = false; + $result['error_data'][] = ['code' => 12,'col_name' => null,'msg' => 'Rule conflict: Dependent count greater than allowed dependent count'];//dependent count mismatch + } + + + } + else + { + if(count($family_data) > 1) + { + $result['status'] = false; + $result['error_data'][] = ['code' => 11,'col_name' => null,'msg' => 'Rule conflict: Dependents not allowed'];//dependents not allowed + } + } + + return $result; + + } +} diff --git a/app/Models/ClientPolicyModel.php b/app/Models/ClientPolicyModel.php index bd8b4f10..e6955601 100644 --- a/app/Models/ClientPolicyModel.php +++ b/app/Models/ClientPolicyModel.php @@ -17,11 +17,8 @@ class ClientPolicyModel extends Model "tpa_id", "tpa_branch_id", "policy_type_id", - - "policy_start_date", "policy_end_date", - "insured", "no_of_employees", "no_of_lives", @@ -34,7 +31,6 @@ class ClientPolicyModel extends Model "policy_status", "earned_premium_amount", "claims_incurred_amount", - "policy_terms", "created_by", "updated_by", @@ -99,6 +95,18 @@ class ClientPolicyModel extends Model ->get() ->getResult(); } + + + public function getPolicyTermsJson($client_id,$policy_id) + { + return $this->select('policy_terms') + ->where('client_id',$client_id) + ->where('policy_id',$policy_id) + ->get() + ->getResult(); + + } + public function getinsurerswithclientid($id){ return $this->db->table('client_policy') @@ -218,4 +226,5 @@ public function getDepositlistsummary($id) ->getResult(); } + } diff --git a/app/Views/employee_upload.php b/app/Views/employee_upload.php index 23e463d4..3fe85db6 100644 --- a/app/Views/employee_upload.php +++ b/app/Views/employee_upload.php @@ -58,7 +58,7 @@
- +
@@ -101,7 +101,7 @@ - + + + + + + + + diff --git a/app/Views/file_list.php b/app/Views/file_list.php index 99ead9b4..d4a4cd28 100644 --- a/app/Views/file_list.php +++ b/app/Views/file_list.php @@ -12,6 +12,8 @@ SNO File name + Client + policy User/Time Status @@ -30,6 +32,8 @@ + + '.$file['first_name'].''?> toastr.options = { - "timeOut": 2000, + "timeOut": 5000, "closeButton": true, }; diff --git a/public/assets/images/simple_loader.gif b/public/assets/images/simple_loader.gif new file mode 100644 index 00000000..aaac0761 Binary files /dev/null and b/public/assets/images/simple_loader.gif differ