diff --git a/app/Config/Database.php b/app/Config/Database.php index f59b49f..d1632d6 100755 --- a/app/Config/Database.php +++ b/app/Config/Database.php @@ -20,6 +20,7 @@ class Database extends Config * use if no other is specified. */ public string $defaultGroup = 'default'; + public string $enableSSL; /** * The default database connection. @@ -38,6 +39,7 @@ class Database extends Config 'DBCollat' => 'utf8_general_ci', 'swapPre' => '', 'encrypt' => false, + // 'encrypt' => ['ssl_verify' => true,'ssl_ca' => ROOTPATH .'ca.pem'], 'compress' => false, 'strictOn' => false, 'failover' => [], @@ -95,5 +97,17 @@ class Database extends Config if (ENVIRONMENT === 'testing') { $this->defaultGroup = 'tests'; } + + $this->enableSSL = env('DB_SSL_ENABLE') ?? false; + + if ($this->enableSSL === true || $this->enableSSL === 'true' || $this->enableSSL === 1 || $this->enableSSL === '1') { + + + // Enable SSL authentication + $this->default['encrypt'] = [ + 'ssl_ca' => ROOTPATH . 'ca.pem', + 'ssl_verify' => true, + ]; + } } } diff --git a/app/Config/Feature.php b/app/Config/Feature.php index 0bc45c6..af76291 100755 --- a/app/Config/Feature.php +++ b/app/Config/Feature.php @@ -21,7 +21,7 @@ class Feature extends BaseConfig * - property $filtersInfo, instead of $filterInfo * - CodeIgniter\Router\RouteCollection::getFiltersForRoute(), instead of getFilterForRoute() */ - public bool $multipleFilters = false; + public bool $multipleFilters = true; /** * Use improved new auto routing instead of the default legacy version. diff --git a/app/Config/Filters.php b/app/Config/Filters.php index 0855ec3..76924a2 100755 --- a/app/Config/Filters.php +++ b/app/Config/Filters.php @@ -12,8 +12,10 @@ use CodeIgniter\Filters\SecureHeaders; use App\Filters\AuthMVC; use App\Filters\HttpRequestLog; use App\Filters\CloseDbConnection; +use App\Filters\VerifyAppSignature; use App\Filters\AuthJWT; +use App\Filters\Cors; class Filters extends BaseConfig { @@ -34,7 +36,10 @@ class Filters extends BaseConfig 'authMVC' => AuthMVC::class, 'HttpRequestLog' => HttpRequestLog::class, 'authJWT' => AuthJWT::class, - 'CloseDbConnection' => CloseDbConnection::class + 'CloseDbConnection' => CloseDbConnection::class, + 'Cors' => Cors::class, + 'appSignature' => VerifyAppSignature::class, + ]; /** @@ -47,11 +52,13 @@ class Filters extends BaseConfig public array $globals = [ 'before' => [ 'HttpRequestLog' => ['except' => 'cli/*'], + 'Cors', // 'csrf', // 'invalidchars', ], 'after' => [ - 'CloseDbConnection' + 'CloseDbConnection', + 'Cors', // 'secureheaders', ], ]; diff --git a/app/Config/Routes.php b/app/Config/Routes.php index d5cc961..eaf7741 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -3,6 +3,14 @@ use CodeIgniter\Router\RouteCollection; + +// Allow OPTIONS for all routes +$routes->options('(:any)', function() { + // This will never be called because the CORS filter returns early + // But having this route ensures OPTIONS isn't rejected as 404 +}); + + /** * @var RouteCollection $routes */ @@ -431,45 +439,21 @@ $routes->cli('cli/check_bounce_mail_cli', 'MasterController::testCheckBounceMail $routes->cli('cli/app_check_list', 'MasterController::appCheckList'); $routes->cli('cli/new_gdrive_token', 'GoogleDriveController::generateNewGoogleDriveAccessToken'); -//Employee login api's -$routes->post("/employeeRest/verifyEmployeeNumber", "RestAuthenticationController::verifyEmployeeWithMobileNumber"); -$routes->post("/employeeRest/getVerifiedUserData", "RestAuthenticationController::getVerifiedUserData"); -$routes->post("/employeeRest/verifyEmployeeEmailId", "RestAuthenticationController::verifyEmployeeWithEmailId"); -// $routes->post("/employeeRest/saveMpin", "RestAuthenticationController::saveMpin"); -//HR login api's -$routes->post("/employeeRest/verifyHrWithMobileNumber", "RestAuthenticationController::verifyHrWithMobileNumber"); -$routes->post("/employeeRest/verifyHrWithEmail", "RestAuthenticationController::verifyHrWithEmail"); -$routes->post("/employeeRest/getVerifiedHrData", "RestAuthenticationController::getVerifiedHrData"); - $routes->group("/api", ["filter" => "authJWT"], function ($routes) { $routes->post("logined", "RestAuthenticationController::logined"); $routes->post("getId", "RestAuthenticationController::getUserIdFromToken"); }); -// MPIN api's -$routes->post("employeeRest/saveMpin", "RestAuthenticationController::saveMpin"); -$routes->post("employeeRest/updateMpin", "RestAuthenticationController::updateMpin"); -$routes->post("/employeeRest/verifyMpin", "RestAuthenticationController::verifyMpin"); -$routes->post("/employeeRest/checkMpin", "RestAuthenticationController::checkMpin"); -$routes->post("employeeRest/forgotMPIN", "RestAuthenticationController::forgotMPIN"); -$routes->post("employeeRest/updateMobileNumber", "RestAuthenticationController::updateMobileNumber"); -// PASSWORD api's -$routes->post("employeeRest/savePassword", "RestAuthenticationController::savePassword"); -$routes->post("employeeRest/changePassword", "RestAuthenticationController::changePassword"); -$routes->post("employeeRest/verifyPassword", "RestAuthenticationController::verifyPassword"); -$routes->post("employeeRest/verifyOtp", "RestAuthenticationController::verifyOtp"); -$routes->post("employeeRest/checkPassword", "RestAuthenticationController::checkPassword"); -$routes->get("employeeRest/downloadSampleExcel", "EmployeeRestController::downloadSampleExcel"); // $routes->post("employeeRest/createOrUpdateEmployeePolicySiAmount", "EmployeeRestController::createOrUpdateEmployeePolicySiAmount"); // $routes->post("employeeRest/calculatePremium", "EmployeeRestController::calculatePremium"); -$routes->group("employeeRest", ["filter" => "authJWT"], function ($routes) { +$routes->group("employeeRest", ['filter' => ['appSignature' , 'authJWT'] ], function ($routes) { // $routes->post("getVerifiedUserData", "RestAuthenticationController::getVerifiedUserData"); @@ -515,6 +499,41 @@ $routes->group("employeeRest", ["filter" => "authJWT"], function ($routes) { $routes->get("hrFileDownload", "EmployeeRestController::hrFileDownload"); $routes->post("hrFileUpload", "EmployeeRestController::hrFileUpload"); + $routes->get("copyActiveEmployeeAndDependentDetails", "EmployeeRestController::copyActiveEmployeeAndDependentDetails"); + +}); + +$routes->group("employeeRest", ['filter' => ['appSignature'] ], function ($routes) { + + //Employee login api's + $routes->post("verifyEmployeeNumber", "RestAuthenticationController::verifyEmployeeWithMobileNumber"); + $routes->post("getVerifiedUserData", "RestAuthenticationController::getVerifiedUserData"); + $routes->post("verifyEmployeeEmailId", "RestAuthenticationController::verifyEmployeeWithEmailId"); + // $routes->post("saveMpin", "RestAuthenticationController::saveMpin"); + + + //HR login api's + $routes->post("verifyHrWithMobileNumber", "RestAuthenticationController::verifyHrWithMobileNumber"); + $routes->post("verifyHrWithEmail", "RestAuthenticationController::verifyHrWithEmail"); + $routes->post("getVerifiedHrData", "RestAuthenticationController::getVerifiedHrData"); + + // MPIN api's + $routes->post("saveMpin", "RestAuthenticationController::saveMpin"); + $routes->post("updateMpin", "RestAuthenticationController::updateMpin"); + $routes->post("verifyMpin", "RestAuthenticationController::verifyMpin"); + $routes->post("checkMpin", "RestAuthenticationController::checkMpin"); + $routes->post("forgotMPIN", "RestAuthenticationController::forgotMPIN"); + $routes->post("updateMobileNumber", "RestAuthenticationController::updateMobileNumber"); + + // PASSWORD api's + $routes->post("savePassword", "RestAuthenticationController::savePassword"); + $routes->post("changePassword", "RestAuthenticationController::changePassword"); + $routes->post("verifyPassword", "RestAuthenticationController::verifyPassword"); + $routes->post("verifyOtp", "RestAuthenticationController::verifyOtp"); + $routes->post("checkPassword", "RestAuthenticationController::checkPassword"); + $routes->get("downloadSampleExcel", "EmployeeRestController::downloadSampleExcel"); + + }); $routes->get("getEmployeeActiveOrInactivePolicy", "EmployeeRestController::getEmployeeActiveOrInactivePolicy"); @@ -530,7 +549,7 @@ $routes->cli("cli/sendCroneRemainderMail", "DashboardController::sendCroneRemain $routes->get('enrollOpendAndClose', 'DashboardController::updatePolicyEnrollmentStatus'); $routes->get("sendCroneRemainderMail", "DashboardController::sendCroneRemainderMail"); -$routes->get("getEmployeePolicy", "EmployeeRestController::getEmployeePolicy"); +// $routes->get("getEmployeePolicy", "EmployeeRestController::getEmployeePolicy"); $routes->get("getAddOnPolicy", "EmployeeRestController::getAddOnPolicy"); $routes->post("addEmployeeAndDependence", "EmployeeRestController::addEmployeeAndDependence"); $routes->post("getPreEmployeePolicyCount", "EmployeeRestController::getPreEmployeePolicyCount"); diff --git a/app/Controllers/EmployeeRestController.php b/app/Controllers/EmployeeRestController.php index 0cd0fdd..348b42a 100755 --- a/app/Controllers/EmployeeRestController.php +++ b/app/Controllers/EmployeeRestController.php @@ -369,7 +369,7 @@ class EmployeeRestController extends AdminController $basic_cover_si = $policy_terms->sum_insured; } - $checkDataExist = $this->employeePolicyModel->where('employee_id',$employee_id)->where('client_policy_id',$client_policy_id)->first(); + $checkDataExist = $this->employeePolicyModel->where('employee_id',$employee_id)->where('client_policy_id',$client_policy_id)->where('is_active', 1)->first(); if($checkDataExist){ @@ -526,16 +526,30 @@ class EmployeeRestController extends AdminController try { if($this->request->getGet('id')) - { - $this->employeeModel->where('id', $this->request->getGet('id') ) - ->where('is_active', 1 ) - ->set(array('is_active'=> 0 )) - ->update(); + { + $is_from_copy = $this->request->getGet('is_from_copy') ?? null; + + if($is_from_copy == 'false' || $is_from_copy == false || $is_from_copy == 'null' || $is_from_copy == null){ + + $this->employeeModel->where('id', $this->request->getGet('id') ) + ->where('is_active', 1 ) + ->set(array('is_active'=> 0 )) + ->update(); + } + + $query = $this->employeePolicyModel + ->where('employee_id', $this->request->getGet('id')) + ->where('is_active', 1); + + // 👉 Add condition only if client_policy_id exists + $clientPolicyId = $this->request->getGet('client_policy_id') ?? null; + if (!empty($clientPolicyId)) { + $query->where('client_policy_id', $clientPolicyId); + } + + $query->set(['is_active' => 0])->update(); + - $this->employeePolicyModel->where('employee_id',$this->request->getGet('id') ) - ->where('is_active', 1 ) - ->set(array('is_active'=> 0 )) - ->update(); return $this->respond(['status' => 'success','code' => 200,'data' =>[] ], 200); }else{ @@ -803,12 +817,9 @@ class EmployeeRestController extends AdminController { if(isset($result['error_type'])){ $result = $empServiceController->getExcelErrorData($file_id); - return $this->respond(['status' => 'failed', 'code' => 404, 'message' => "file upload failed with errors",'data' => $result], 200); + return $this->respond(['status' => 'failed', 'code' => 404, 'message' => 'The data format is invalid. Click "Next" to view details.','data' => $result], 200); }else { - $message = "file upload failed with errors"; - if(isset($result['error_data'])){ - $message = $result['error_data']; - } + $message = "The import file is in an incorrect format. Please compare it with our template file to correct it."; return $this->respond(['status' => 'failed', 'code' => 404, 'message' => $message,'data' => $result], 200); } } @@ -1163,13 +1174,25 @@ class EmployeeRestController extends AdminController if ($empPolicy) { - + + $latest_gmc_policy_id = getLatestGMCPolicy((array)$empPolicy); $result = []; foreach ($empPolicy as $array) { - // Reset employee array - $empData = $employeeData; - + // Reset employee array + // $empData = $employeeData; + $empData = $this->employeeModel + ->select('employees.*') + ->join('employee_polices', 'employee_polices.employee_id = employees.id') + ->where('employees.emp_code',$emp_code) + ->where('employees.client_id',$client_id) + ->where('employees.client_branch_id',$client_branch_id) + ->where('employee_polices.client_policy_id',$array->ClientPolicyId) + ->where('employees.is_active', 1 ) + ->where('employee_polices.is_active', 1 ) + ->where('employees.is_addon_value',0) + ->findAll(); + // Removes specific keys from the decoded array and assigns the result to $refusingData $decodedArray = json_decode($array->Policy_Terms); $refusingData = (object) array_diff_key((array) $decodedArray, array_flip($keysToRemove)); @@ -1248,7 +1271,14 @@ class EmployeeRestController extends AdminController }else if($array->policy_type_id == 2 && $this->request->getGet('policy') == 'GMC' ) { + $array->to_be_added_relationship = []; + $array->existing_relationship = []; + if(!empty($latest_gmc_policy_id) && $latest_gmc_policy_id == $array->ClientPolicyId){ + $array->copy_dependence_data_enable = true; + }else{ + $array->copy_dependence_data_enable = false; + } // Map family floaters that already exist in the employee table $familyFloates = $array->Policy_Terms->family_floaters; @@ -1259,7 +1289,7 @@ class EmployeeRestController extends AdminController if($getSlabAndGridData['slab_rates'][0]['premium_type'] == 1 || $getSlabAndGridData['slab_rates'][0]['premium_type'] == 3) { $array->floter_text_heading = 'Floater Sum Insured'; - $array->floter_text_description = 'This is a floater sum insured. A floater is a type of sum insured that provides coverage to more than one member ot a family at the same time. Simply put, its a single insurance cover for the entire family.'; + $array->floter_text_description = 'This is a floater sum insured. A floater is a type of sum insured that provides coverage to more than one member of a family at the same time. Simply put, its a single insurance cover for the entire family.'; }else{ $array->floter_text_heading = 'Sum Insured'; $array->floter_text_description = ''; @@ -1302,6 +1332,8 @@ class EmployeeRestController extends AdminController $temp['data']['age_validation'] = $this->getAgeRange($decodedArray,$familyFloatesValue); + + array_push($array->existing_relationship,$temp['data']['relationship']); array_push($data,$temp); unset($empData[$key]); @@ -1350,6 +1382,7 @@ class EmployeeRestController extends AdminController $temp2['is_value_exist'] = false; $temp2['data']['family_floater_key'] = $familyFloatesValue; + $temp2['data']['relationship'] = ucfirst(str_replace('_', ' ', preg_replace('/\d/', '', $familyFloatesValue))); $temp2['data']['client_policy_id'] = $array->ClientPolicyId; $temp2['data']['button_name'] = 'Add '.ucfirst(str_replace('_', ' ', preg_replace('/\d/', '', $familyFloatesValue))); $temp2['data']['form_type'] = preg_replace('/\d/', '', $familyFloatesValue); @@ -1359,9 +1392,58 @@ class EmployeeRestController extends AdminController array_push($data,$temp2); + array_push($array->to_be_added_relationship,['relationship'=>$temp2['data']['relationship'],'age_validation'=>$temp2['data']['age_validation']]); + $array->to_be_added_relationship = array_values( + array_map('unserialize', + array_unique( + array_map('serialize', $array->to_be_added_relationship) + ) + ) + ); + } } + + $array->relationship = []; + foreach ($array->to_be_added_relationship as $key => $value) { + if($value['relationship'] == 'Spouse'){ + array_push($array->relationship,['relationship'=>'Spouse','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]); + }else if($value['relationship'] == 'Child'){ + array_push($array->relationship, ['relationship'=>'Son','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]); + array_push($array->relationship, ['relationship'=>'Daughter','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]); + }else if($value['relationship'] == 'Parent'){ + $Father = array_search('Father',$array->existing_relationship); + $Mother = array_search('Mother',$array->existing_relationship); + if ($Father === false && $Mother === false) { + array_push($array->relationship, ['relationship'=>'Father','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]); + array_push($array->relationship, ['relationship'=>'Mother','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]); + }else if ($Father !== false && $Mother === false) { + array_push($array->relationship, ['relationship'=>'Mother','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]); + } else if ($Mother !== false && $Father === false) { + array_push($array->relationship, ['relationship'=>'Father','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]); + } + }else if($value['relationship'] == 'Parent in law'){ + $FatherinLaw = array_search('Father in Law',$array->existing_relationship); + $MotherinLaw = array_search('Mother in Law',$array->existing_relationship); + if ($FatherinLaw === false && $MotherinLaw === false) { + array_push($array->relationship, ['relationship'=>'Father in Law','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]); + array_push($array->relationship, ['relationship'=>'Mother in Law','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]); + }else if ($FatherinLaw !== false && $MotherinLaw === false) { + array_push($array->relationship, ['relationship'=>'Mother in Law','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]); + } else if ($MotherinLaw !== false && $FatherinLaw === false) { + array_push($array->relationship, ['relationship'=>'Father in Law','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]); + } + } + } + + // echo '
';
+ // print_r($array->existing_relationship);
+ // print_r($array->to_be_added_relationship);
+ // print_r($array->relationship);
+ // die;
+
+
$array->mapped_family_floaters = $data;
$array->type = "GMC";
$array->family_floaters_of_dependent_and_si_value = $dependent_and_si_value > 0 ? $dependent_and_si_value : 0;
@@ -1386,12 +1468,14 @@ class EmployeeRestController extends AdminController
if($checkGmcParentsPolicyExist)
{
$GmcParrentsData = $this->getGmcParrentsPolicy($checkGmcParentsPolicyExist,$emp_code,$client_id,$client_branch_id);
- return $this->respond(['status' => 'success','code' => 200,'data' => [$array,$GmcParrentsData]], 200);
-
+ // return $this->respond(['status' => 'success','code' => 200,'data' => [$array,$GmcParrentsData]], 200);
+ $result[] = $array;
+ $result[] = $GmcParrentsData;
}
- if($this->request->getGet('policy') == 'GMC'){
- return $this->respond(['status' => 'success','code' => 200,'data' => [$array]], 200);
+ if($this->request->getGet('policy') == 'GMC' && !$checkGmcParentsPolicyExist){
+ // return $this->respond(['status' => 'success','code' => 200,'data' => [$array]], 200);
+ $result[] = $array;
}
}
@@ -1399,14 +1483,31 @@ class EmployeeRestController extends AdminController
// $result[] = $array;
}
- return $this->respond(['status' => 'success','code' => 200,'data' => []], 200);
+ if(!empty($result) && $this->request->getGet('policy') == 'GMC'){
+ return $this->respond(['status' => 'success','code' => 200,'data' => $result], 200);
+ }else{
+ return $this->respond(['status' => 'success','code' => 200,'data' => []], 200);
+ }
}else{
return $this->respond(['status' => 'failed','code' => 404,'data' => []], 200);
}
+
} catch (\Exception $e) {
- return $this->respond(['status' => 'failed','code' => 500,'data' => $e->getLine()], 500);
+
+ $errorData = [
+ 'message' => $e->getMessage(),
+ 'file' => $e->getFile(),
+ 'line' => $e->getLine(),
+ 'code' => $e->getCode(),
+ 'trace' => $e->getTraceAsString(),
+ 'trace_array' => $e->getTrace(), // full array version (optional)
+ 'function' => $e->getTrace()[0]['function'] ?? null,
+ 'class' => $e->getTrace()[0]['class'] ?? null,
+ ];
+
+ return $this->respond(['status' => 'failed','code' => 500,'data' => $e->getLine(), 'error_data' => $errorData], 500);
}
}
@@ -1414,19 +1515,31 @@ class EmployeeRestController extends AdminController
public function getGmcParrentsPolicy($GmcParrentsPolicy,$emp_code,$client_id,$client_branch_id)
{
- $employeeData = $this->employeeModel->where('emp_code',$emp_code)
- ->where('client_id',$client_id)
- ->where('client_branch_id',$client_branch_id)
- ->where('is_active', 1 )
- ->where('is_addon_value',0)->findAll();
+ // $employeeData = $this->employeeModel->where('emp_code',$emp_code)
+ // ->where('client_id',$client_id)
+ // ->where('client_branch_id',$client_branch_id)
+ // ->where('is_active', 1 )
+ // ->where('is_addon_value',0)->findAll();
// return $employeeData;
foreach ($GmcParrentsPolicy as $key => $array) {
+ $array->to_be_added_relationship = [];
+ $array->existing_relationship = [];
// Reset employee array
- $empData = $employeeData;
-
+ // $empData = $employeeData;
+ $empData = $this->employeeModel
+ ->select('employees.*')
+ ->join('employee_polices', 'employee_polices.employee_id = employees.id')
+ ->where('employees.emp_code',$emp_code)
+ ->where('employees.client_id',$client_id)
+ ->where('employees.client_branch_id',$client_branch_id)
+ ->where('employee_polices.client_policy_id',$array->ClientPolicyId)
+ ->where('employees.is_active', 1 )
+ ->where('employee_polices.is_active', 1 )
+ ->where('employees.is_addon_value',0)
+ ->findAll();
$array->Policy_Terms = json_decode($array->Policy_Terms);
@@ -1440,6 +1553,7 @@ class EmployeeRestController extends AdminController
->join('employee_polices', 'employee_polices.employee_id = employees.id')
->where('employees.emp_code',$emp_code)
->where('employees.is_active',1)
+ ->where('employee_polices.is_active',1)
->where('employee_polices.client_policy_id',$array->ClientPolicyId)
->get()
->getResult();
@@ -1513,6 +1627,7 @@ class EmployeeRestController extends AdminController
$temp['data']['basic_cover_si'] = isset($employee_policy->basic_cover_si) ? $employee_policy->basic_cover_si : 0;
$temp['data']['age_validation'] = $this->getAgeRange($array->Policy_Terms,$familyFloatesValue);
+ array_push($array->existing_relationship,$temp['data']['relationship']);
array_push($data,$temp);
unset($empData[$key]);
@@ -1555,16 +1670,59 @@ class EmployeeRestController extends AdminController
// Add family floter buttons placement data for FE validation
if(count($floters)){
- foreach ($floters as $familyFloatesValue) {
+ foreach ($floters as $familyFloatesValue) {
- $temp2['is_value_exist'] = false;
- $temp2['data']['family_floater_key'] = $familyFloatesValue;
- $temp2['data']['client_policy_id'] = $array->ClientPolicyId;
- $temp2['data']['button_name'] = 'Add '.ucfirst(str_replace('_', ' ', preg_replace('/\d/', '', $familyFloatesValue)));
- $temp2['data']['form_type'] = preg_replace('/\d/', '', $familyFloatesValue);
- $temp2['data']['age_validation'] = $this->getAgeRange($array->Policy_Terms,$familyFloatesValue);
- array_push($data,$temp2);
+ $temp2['is_value_exist'] = false;
+ $temp2['data']['family_floater_key'] = $familyFloatesValue;
+ $temp2['data']['relationship'] = ucfirst(str_replace('_', ' ', preg_replace('/\d/', '', $familyFloatesValue)));
+ $temp2['data']['client_policy_id'] = $array->ClientPolicyId;
+ $temp2['data']['button_name'] = 'Add '.ucfirst(str_replace('_', ' ', preg_replace('/\d/', '', $familyFloatesValue)));
+ $temp2['data']['form_type'] = preg_replace('/\d/', '', $familyFloatesValue);
+ $temp2['data']['age_validation'] = $this->getAgeRange($array->Policy_Terms,$familyFloatesValue);
+ array_push($data,$temp2);
+
+ array_push($array->to_be_added_relationship,['relationship'=>$temp2['data']['relationship'],'age_validation'=>$temp2['data']['age_validation']]);
+ $array->to_be_added_relationship = array_values(
+ array_map('unserialize',
+ array_unique(
+ array_map('serialize', $array->to_be_added_relationship)
+ )
+ )
+ );
+
+ }
+ }
+
+ $array->relationship = [];
+ foreach ($array->to_be_added_relationship as $key => $value) {
+ if($value['relationship'] == 'Spouse'){
+ array_push($array->relationship,['relationship'=>'Spouse','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]);
+ }else if($value['relationship'] == 'Child'){
+ array_push($array->relationship, ['relationship'=>'Son','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]);
+ array_push($array->relationship, ['relationship'=>'Daughter','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]);
+ }else if($value['relationship'] == 'Parent'){
+ $Father = array_search('Father',$array->existing_relationship);
+ $Mother = array_search('Mother',$array->existing_relationship);
+ if ($Father === false && $Mother === false) {
+ array_push($array->relationship, ['relationship'=>'Father','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]);
+ array_push($array->relationship, ['relationship'=>'Mother','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]);
+ }else if ($Father !== false && $Mother === false) {
+ array_push($array->relationship, ['relationship'=>'Mother','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]);
+ } else if ($Mother !== false && $Father === false) {
+ array_push($array->relationship, ['relationship'=>'Father','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]);
+ }
+ }else if($value['relationship'] == 'Parent in law'){
+ $FatherinLaw = array_search('Father in Law',$array->existing_relationship);
+ $MotherinLaw = array_search('Mother in Law',$array->existing_relationship);
+ if ($FatherinLaw === false && $MotherinLaw === false) {
+ array_push($array->relationship, ['relationship'=>'Father in Law','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]);
+ array_push($array->relationship, ['relationship'=>'Mother in Law','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]);
+ }else if ($FatherinLaw !== false && $MotherinLaw === false) {
+ array_push($array->relationship, ['relationship'=>'Mother in Law','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]);
+ } else if ($MotherinLaw !== false && $FatherinLaw === false) {
+ array_push($array->relationship, ['relationship'=>'Father in Law','age_validation'=>$value['age_validation'] , 'client_policy_id' => $array->ClientPolicyId]);
+ }
}
}
@@ -2013,6 +2171,10 @@ class EmployeeRestController extends AdminController
$siArray = $this->getSiMappedArray($array['id'],$array['base_policy']);
$responce['SlabRates'] = is_array($siArray) ? $siArray : $responce['SlabRates'];
+
+ $array['to_be_added_relationship'] = [];
+ $array['existing_relationship'] = [];
+
// Map family floaters that already exist in the employee table
$familyFloates = $policy_terms->family_floaters;
@@ -2051,7 +2213,9 @@ class EmployeeRestController extends AdminController
$temp['data']['form_type'] = $dependent;
$temp['data']['basic_cover_si'] = isset($employee_policy->basic_cover_si) ? $employee_policy->basic_cover_si : null;
$temp['data']['premium'] = isset($employee_policy->premium) ? $employee_policy->premium : null;
- $temp['data']['age_validation'] = $this->getAgeRange($decodedArray,$familyFloatesValue);
+ $temp['data']['age_validation'] = $this->getAgeRange($decodedArray,$familyFloatesValue);
+
+ array_push($array['existing_relationship'],$temp['data']['relationship']);
array_push($data,$temp);
unset($addOnEmployeeData[$key]);
@@ -2103,6 +2267,7 @@ class EmployeeRestController extends AdminController
$temp2['is_value_exist'] = false;
$temp2['data']['family_floater_key'] = $familyFloatesValue;
+ $temp2['data']['relationship'] = ucfirst(str_replace('_', ' ', preg_replace('/\d/', '', $familyFloatesValue)));
$temp2['data']['client_policy_id'] = $array['id'];
$temp2['data']['button_name'] = 'Add '.ucfirst(str_replace('_', ' ', preg_replace('/\d/', '', $familyFloatesValue)));
$temp2['data']['form_type'] = preg_replace('/\d/', '', $familyFloatesValue);
@@ -2111,8 +2276,51 @@ class EmployeeRestController extends AdminController
array_push($data,$temp2);
+
+ array_push($array['to_be_added_relationship'],['relationship'=>$temp2['data']['relationship'],'age_validation'=>$temp2['data']['age_validation']]);
+ $array['to_be_added_relationship'] = array_values(
+ array_map('unserialize',
+ array_unique(
+ array_map('serialize', $array['to_be_added_relationship'])
+ )
+ )
+ );
+
}
}
+
+
+ $responce['relationship'] = [];
+ foreach ($array['to_be_added_relationship'] as $key => $value) {
+ if($value['relationship'] == 'Spouse'){
+ array_push($responce['relationship'],['relationship' => 'Spouse','age_validation' => $value['age_validation'],'client_policy_id'=>$array['id']]);
+ }else if($value['relationship'] == 'Child'){
+ array_push($responce['relationship'], ['relationship' => 'Son','age_validation' => $value['age_validation'],'client_policy_id'=>$array['id']]);
+ array_push($responce['relationship'], ['relationship' => 'Daughter','age_validation' => $value['age_validation'],'client_policy_id'=>$array['id']]);
+ }else if($value['relationship'] == 'Parent'){
+ $Father = array_search('Father',$array['existing_relationship']);
+ $Mother = array_search('Mother',$array['existing_relationship']);
+ if ($Father === false && $Mother === false) {
+ array_push($responce['relationship'], ['relationship' => 'Father','age_validation' => $value['age_validation'],'client_policy_id'=>$array['id']]);
+ array_push($responce['relationship'], ['relationship' => 'Mother','age_validation' => $value['age_validation'],'client_policy_id'=>$array['id']]);
+ }else if ($Father !== false && $Mother === false) {
+ array_push($responce['relationship'], ['relationship' => 'Mother','age_validation' => $value['age_validation'],'client_policy_id'=>$array['id']]);
+ } else if ($Mother !== false && $Father === false) {
+ array_push($responce['relationship'], ['relationship' => 'Father','age_validation' => $value['age_validation'],'client_policy_id'=>$array['id']]);
+ }
+ }else if($value['relationship'] == 'Parent in law'){
+ $FatherinLaw = array_search('Father in Law',$array['existing_relationship']);
+ $MotherinLaw = array_search('Mother in Law',$array['existing_relationship']);
+ if ($FatherinLaw === false && $MotherinLaw === false) {
+ array_push($responce['relationship'], ['relationship' => 'Father in Law','age_validation' => $value['age_validation'],'client_policy_id'=>$array['id']]);
+ array_push($responce['relationship'], ['relationship' => 'Mother in Law','age_validation' => $value['age_validation'],'client_policy_id'=>$array['id']]);
+ }else if ($FatherinLaw !== false && $MotherinLaw === false) {
+ array_push($responce['relationship'], ['relationship' => 'Mother in Law','age_validation' => $value['age_validation'],'client_policy_id'=>$array['id']]);
+ } else if ($MotherinLaw !== false && $FatherinLaw === false) {
+ array_push($responce['relationship'], ['relationship' => 'Father in Law','age_validation' => $value['age_validation'],'client_policy_id'=>$array['id']]);
+ }
+ }
+ }
$responce['family_floaters_of_dependent_and_si_array'] = $data;
$responce['family_floaters_of_dependent_and_si_value'] = $dependent_and_si_value > 0 ? $dependent_and_si_value : 0;
@@ -2290,7 +2498,7 @@ class EmployeeRestController extends AdminController
$empData = $this->employeeModel->where('emp_code', $emp_code )->where('client_id', $client_id ) ->where('is_active', 1 )->findAll();
$employeeIds = array_column($empData, 'id');
//for mail common parameter
- $filteredEmpData = array_filter($empData, fn($item) => $item['relationship'] === 'Self');
+ $filteredEmpData = array_values(array_filter($empData, fn($item) => $item['relationship'] === 'Self'));
if (!is_null($client_policy_id) && is_array($client_policy_id))
{
@@ -3437,7 +3645,7 @@ class EmployeeRestController extends AdminController
}
- public function getPreEmployeePolicyCount()
+ public function getPreEmployeePolicyCountOld()
{
log_message('error', 'STEP 1: getPreEmployeePolicyCount API called');
@@ -3485,6 +3693,7 @@ class EmployeeRestController extends AdminController
->join('client_policy cp', 'employee_polices.client_policy_id = cp.id')
->where('employees.is_active', 1)
->whereIn('employees.emp_status', ['draft', 'enrolled'])
+ ->where('employees.family_floater_key', 'self')
->where('employee_polices.is_active', 1)
->whereIn('employee_polices.status', ['draft', 'enrolled'])
->where('cp.enrolment_visibility', 1)
@@ -3521,156 +3730,410 @@ class EmployeeRestController extends AdminController
}
}
+ public function getPreEmployeePolicyCount()
+ {
+ log_message('error', 'STEP 1: getPreEmployeePolicyCount API called');
+
+ $request = $this->request->getJSON(true);
+ $mobile_no = $request['mobile_number'] ?? null;
+ $email_id = $request['email_id'] ?? null;
+ $client_short_name = $request['client_short_name'] ?? null;
+
+ log_message('error', 'STEP 2: Received input - ' . json_encode($request));
+
+ /** ---------------------------------------------------------------
+ * STEP 3: Resolve Client ID (If client_short_name passed)
+ * --------------------------------------------------------------- */
+ $clientId = null;
+ if (!empty($client_short_name)) {
+ log_message('error', 'STEP 3: Looking up client with short_name: ' . $client_short_name);
+
+ $client = $this->clientModel
+ ->select('id')
+ ->where('is_active', 1)
+ ->where('short_name', $client_short_name)
+ ->first();
+
+ if (!empty($client)) {
+ $clientId = $client['id'];
+ log_message('error', 'STEP 4: Found client ID: ' . $clientId);
+ } else {
+ log_message('error', 'STEP 4: No client found for short_name: ' . $client_short_name);
+ }
+ } else {
+ log_message('error', 'STEP 3: client_short_name is empty.');
+ }
+
+ /** ---------------------------------------------------------------
+ * STEP 4: Validate Request (either mobile or email is required)
+ * --------------------------------------------------------------- */
+ if (empty($mobile_no) && empty($email_id)) {
+ log_message('error', 'STEP 5: Mobile number and Email both empty. Returning 0.');
+ return $this->respond(['data' => 0, 'empNotEnrolledCount' => 0]);
+ }
+
+ try {
+ /** ---------------------------------------------------------------
+ * STEP 6: Base Query Builder (extract common conditions)
+ * --------------------------------------------------------------- */
+ $baseQuery = $this->employeeModel
+ ->join('employee_polices', 'employees.id = employee_polices.employee_id')
+ ->join('client_policy cp', 'employee_polices.client_policy_id = cp.id')
+ ->where('employees.is_active', 1)
+ ->where('employee_polices.is_active', 1)
+ ->where('cp.enrolment_visibility', 1)
+ ->where('cp.open_for_enrollment', 1)
+ ->where('cp.policy_status', 1)
+ ->whereIn('cp.policy_type_id', [1, 2, 3, 6, 7])
+ ->orderBy('employees.created_at', 'desc')
+ ->groupBy('employee_polices.client_policy_id');
+
+ // 🔹 Apply Client Filter if Provided
+ if (!empty($clientId)) {
+ $baseQuery->where('employees.client_id', $clientId);
+ log_message('error', 'Applied client ID filter: ' . $clientId);
+ }
+
+ // 🔹 Apply Mobile Filter if Provided
+ if (!empty($mobile_no)) {
+ $baseQuery->where('employees.mobile', $mobile_no);
+ log_message('error', 'Applied mobile_no filter: ' . $mobile_no);
+ }
+
+ // 🔹 Apply Email Filter if Provided
+ if (!empty($email_id)) {
+ $baseQuery->where('employees.email_corporate', $email_id);
+ log_message('error', 'Applied email_id filter: ' . $email_id);
+ }
+
+ /** ---------------------------------------------------------------
+ * STEP 7: Count Enrolled + Draft (eligible)
+ * --------------------------------------------------------------- */
+ $baseQuery->whereIn('employees.emp_status', ['draft', 'enrolled'])
+ ->whereIn('employee_polices.status', ['draft', 'enrolled'])
+ ->where('employees.family_floater_key', 'self');
+
+ $count = $baseQuery->get()->getNumRows();
+ log_message('error', 'Eligible policy count = ' . $count);
+
+ /** ---------------------------------------------------------------
+ * STEP 8: Count Only Draft (Not Enrolled yet)
+ * --------------------------------------------------------------- */
+ $notEnrolledQuery = $this->employeeModel
+ ->select("
+ (
+ SELECT COUNT(e2.id)
+ FROM employees AS e2
+ WHERE e2.is_active = 1
+ AND e2.emp_status = 'draft'
+ AND e2.emp_code = employees.emp_code
+ ) AS draft_count
+ ")
+ ->join('employee_polices', 'employees.id = employee_polices.employee_id')
+ ->join('client_policy cp', 'employee_polices.client_policy_id = cp.id')
+ ->where('employees.is_active', 1)
+ ->where('employee_polices.is_active', 1)
+ ->where('cp.enrolment_visibility', 1)
+ ->where('cp.open_for_enrollment', 1)
+ ->where('cp.policy_status', 1)
+ ->whereIn('cp.policy_type_id', [1, 2, 3, 6, 7])
+ ->orderBy('employees.created_at', 'desc');
+
+ // 🔹 Apply Client Filter if Provided
+ if (!empty($clientId)) {
+ $notEnrolledQuery->where('employees.client_id', $clientId);
+ log_message('error', 'Applied client ID filter: ' . $clientId);
+ }
+
+ // 🔹 Apply Mobile Filter if Provided
+ if (!empty($mobile_no)) {
+ $notEnrolledQuery->where('employees.mobile', $mobile_no);
+ log_message('error', 'Applied mobile_no filter: ' . $mobile_no);
+ }
+
+ // 🔹 Apply Email Filter if Provided
+ if (!empty($email_id)) {
+ $notEnrolledQuery->where('employees.email_corporate', $email_id);
+ log_message('error', 'Applied email_id filter: ' . $email_id);
+ }
+
+ $notEnrolledQuery->whereIn('employees.emp_status', ['draft'])
+ ->whereIn('employee_polices.status', ['draft']);
+
+ $not_enrolled_count = $notEnrolledQuery->get()->getRowArray()['draft_count'] ?? 0;
+ log_message('error', 'Not enrolled policy count = ' . $not_enrolled_count);
+
+ /** ---------------------------------------------------------------
+ * STEP 9: Final Response
+ * --------------------------------------------------------------- */
+ return $this->respond([
+ 'pre_policy_count' => $count,
+ 'emp_not_enrolled_count' => (int) $not_enrolled_count
+ ]);
+
+ } catch (\Throwable $e) {
+ log_message('error', 'Exception occurred: ' . $e->getMessage());
+ return $this->respond([
+ 'pre_policy_count' => 0,
+ 'emp_not_enrolled_count' => 0
+ ]);
+ }
+ }
- //--------------------------------------------------------------------------------------------
- public function hrFileUpload()
- {
- try {
- // Check file
- $file = $this->request->getFile('file_name');
- if (!$file) {
- return $this->response->setJSON([
- 'status' => false,
- 'message' => "Invalid file or file not uploaded.",
- 'data' => "No Data"
- ]);
- }
+
+ //--------------------------------------------------------------------------------------------
- // Upload folder path
- $uploadPath = WRITEPATH . 'uploads/hr_files/';
-
- // If directory not exists, create it
- if (!is_dir($uploadPath)) {
- mkdir($uploadPath, 0777, true);
- }
-
- // New file name with timestamp
- $newFileName = time() . '_' . $file->getRandomName();
-
- // Move file
- $file->move($uploadPath, $newFileName);
-
- // Prepare data
- $data = [
- 'client_id' => $this->request->getPost('client_id'),
- 'client_branch_id' => $this->request->getPost('client_branch_id'),
- 'policy_no' => $this->request->getPost('policy_no'),
- 'file_name' => $newFileName,
- 'file_action' => $this->request->getPost('file_action'),
- 'status' => $this->request->getPost('status'),
- 'created_by' => $this->request->getPost('created_by'),
- 'updated_by' => $this->request->getPost('created_by'),
- ];
-
- // Save into DB
- $this->hrFileUploadModel->insert($data);
-
- return $this->respondCreated([
- 'status' => true,
- 'message' => 'File uploaded successfully',
- 'data' => $data
+ public function hrFileUpload()
+ {
+ try {
+ // Check file
+ $file = $this->request->getFile('file_name');
+ if (!$file) {
+ return $this->response->setJSON([
+ 'status' => false,
+ 'message' => "Invalid file or file not uploaded.",
+ 'data' => "No Data"
]);
-
- } catch (\Exception $e) {
- return $this->failServerError($e->getMessage());
}
-
- }
-
- public function hrFileDownload($id = null)
- {
- try {
-
- $file_id = $this->request->getGet('id') ?? $id;
-
- // Find record
- $record = $this->hrFileUploadModel->find($file_id);
-
- if (!$record) {
- return $this->failNotFound("File record not found");
- }
-
- $uploadPath = WRITEPATH . 'uploads/hr_files/';
- $filePath = $uploadPath . $record['file_name'];
-
- if (!file_exists($filePath)) {
- return $this->failNotFound("File not found on server");
- }
-
- // Force file download
- return $this->response->download($filePath, null)
- ->setFileName($record['file_name']);
- } catch (\Exception $e) {
- return $this->failServerError($e->getMessage());
+
+ // Upload folder path
+ $uploadPath = WRITEPATH . 'uploads/hr_files/';
+
+ // If directory not exists, create it
+ if (!is_dir($uploadPath)) {
+ mkdir($uploadPath, 0777, true);
}
+
+ // New file name with timestamp
+ $newFileName = time() . '_' . $file->getRandomName();
+
+ // Move file
+ $file->move($uploadPath, $newFileName);
+
+ // Prepare data
+ $data = [
+ 'client_id' => $this->request->getPost('client_id'),
+ 'client_branch_id' => $this->request->getPost('client_branch_id'),
+ 'policy_no' => $this->request->getPost('policy_no'),
+ 'file_name' => $newFileName,
+ 'file_action' => $this->request->getPost('file_action'),
+ 'status' => $this->request->getPost('status'),
+ 'created_by' => $this->request->getPost('created_by'),
+ 'updated_by' => $this->request->getPost('created_by'),
+ ];
+
+ // Save into DB
+ $this->hrFileUploadModel->insert($data);
+
+ return $this->respondCreated([
+ 'status' => true,
+ 'message' => 'File uploaded successfully',
+ 'data' => $data
+ ]);
+
+ } catch (\Exception $e) {
+ return $this->failServerError($e->getMessage());
}
-
- public function hrFileList()
- {
- try {
- $request = service('request');
- $builder = $this->hrFileUploadModel;
-
- // Allowed filter keys
- $filters = [
- 'client_id',
- 'client_branch_id',
- 'policy_no',
- 'file_action',
- 'status',
- 'created_by'
- ];
-
- // Apply filters dynamically
- foreach ($filters as $key) {
- $value = $request->getGetPost($key); // supports both GET and POST
- if (!empty($value)) {
- $builder->where($key, $value);
+
+ }
+
+ public function hrFileDownload($id = null)
+ {
+ try {
+
+ $file_id = $this->request->getGet('id') ?? $id;
+
+ // Find record
+ $record = $this->hrFileUploadModel->find($file_id);
+
+ if (!$record) {
+ return $this->failNotFound("File record not found");
+ }
+
+ $uploadPath = WRITEPATH . 'uploads/hr_files/';
+ $filePath = $uploadPath . $record['file_name'];
+
+ if (!file_exists($filePath)) {
+ return $this->failNotFound("File not found on server");
+ }
+
+ // Force file download
+ return $this->response->download($filePath, null)
+ ->setFileName($record['file_name']);
+ } catch (\Exception $e) {
+ return $this->failServerError($e->getMessage());
+ }
+ }
+
+ public function hrFileList()
+ {
+ try {
+ $request = service('request');
+ $builder = $this->hrFileUploadModel;
+
+ // Allowed filter keys
+ $filters = [
+ 'client_id',
+ 'client_branch_id',
+ 'policy_no',
+ 'file_action',
+ 'status',
+ 'created_by'
+ ];
+
+ // Apply filters dynamically
+ foreach ($filters as $key) {
+ $value = $request->getGetPost($key); // supports both GET and POST
+ if (!empty($value)) {
+ $builder->where($key, $value);
+ }
+ }
+
+ // Fetch results
+ $data = $builder->findAll();
+
+ return $this->respond([
+ 'status' => true,
+ 'message' => 'File list fetched successfully',
+ 'data' => $data
+ ]);
+ } catch (\Exception $e) {
+ return $this->failServerError($e->getMessage());
+ }
+ }
+
+ public function hrFileUploadMasters()
+ {
+ try {
+ //for inception upload
+ $data['actions'] = ['inception' => 'Inception (Employee + Dependents)', 'missed_inception' => 'Missed Inception (Employee + Dependents)', 'addition' => 'Addition (Employee + Dependents)', 'dependent_addition' => 'Dependent Addition (Only Dependents)', 'deletion' => 'Deletion', 'correction' => 'Correction', 'si_enhancement' => 'SI Enhancement'];
+
+ return $this->respond([
+ 'status' => true,
+ 'message' => 'File inception upload masters',
+ 'data' => $data
+ ]);
+ } catch (\Exception $e) {
+ return $this->failServerError($e->getMessage());
+ }
+ }
+
+ public function downloadSampleExcel()
+ {
+ $employeeController = new EmployeeController();
+ $file_path = $employeeController->downloadSampleExcelFile('enrollment', 1);
+ if(empty($file_path)){
+ return $this->respond(['status' => "success", 'code' => 404, 'data' => "", "message" => "Sample file not avilable"], 200);
+ }else{
+ return $this->respond(['status' => "success", 'code' => 200, 'data' => $file_path], 200);
+ }
+
+ }
+
+
+ // copy the active enrolled employee data
+ public function copyActiveEmployeeAndDependentDetails()
+ {
+ $received_payload = $this->request->getGet();
+ $client_id = $received_payload['client_id'] ?? null;
+ $emp_code = $received_payload['emp_code'] ?? null;
+ $new_client_policy_id = $received_payload['new_client_policy_id'] ?? null;
+
+ if (empty($client_id)) {
+ return $this->respond(['status' => "failed", 'code' => 404, 'message' => "client_id is required"], 200);
+ }
+
+ if (empty($new_client_policy_id)) {
+ return $this->respond(['status' => "failed", 'code' => 404, 'message' => "client_policy_id is required"], 200);
+ }
+
+ if (empty($emp_code)) {
+ return $this->respond(['status' => "failed", 'code' => 404, 'message' => "emp_code is required"], 200);
+ }
+
+ $client_policy_data = $this->clientPolicyModel
+ ->where('is_active', 1)
+ ->where('client_id', $client_id)
+ ->where('id', $new_client_policy_id)
+ ->whereIn('policy_type_id', [2, 3, 4, 5])
+ ->first();
+
+ if (empty($client_policy_data)) {
+ return $this->respond(['status' => "failed", 'code' => 404, 'message' => "Policy data not found", 'data' => []], 200);
+ }
+
+ $policy_terms = $client_policy_data['policy_terms'] ?? null;
+
+ if (empty($policy_terms)) {
+ return $this->respond(['status' => "failed", 'code' => 404, 'message' => "Policy terms not found", 'data' => []], 200);
+ }
+
+ $policy_terms = json_decode($policy_terms, true);
+
+ $family_floaters = $policy_terms['family_floaters'];
+
+ $empData = $this->employeeModel
+ ->where('emp_code', $emp_code)
+ ->where('client_id', $client_id)
+ // ->where('emp_status', 'enrolled')
+ ->where('is_active', 1)
+ ->findAll();
+
+ if (empty($empData)) {
+ return $this->respond(['status' => "failed", 'code' => 404, 'message' => "employee data not found", 'data' => []], 200);
+ }
+
+ $selfData = array_column(
+ array_filter($empData, function($row) {
+ return isset($row['relationship']) && strtolower($row['relationship']) == 'self';
+ }),
+ 'id'
+ );
+
+ $selfId = !empty($selfData) ? reset($selfData) : null;
+ $floters = $this->FloterConvertion($family_floaters);
+
+ $data = [];
+ foreach ($floters as $familyFloatesValue) {
+
+ $dependent = preg_replace('/\d/', '', $familyFloatesValue);
+
+ if (count($empData)) {
+ foreach ($empData as $key => $value) {
+ if ($value['family_floater_key'] === $dependent) {
+
+ $employee_policy = $this->employeePolicyModel->where('employee_id', $selfId)->where('client_policy_id',$new_client_policy_id)->where('is_active', 1 )->get()->getRow();
+
+ $temp['is_value_exist'] = true;
+ $temp['data']['family_floater_key'] = $familyFloatesValue;
+ $temp['data']['employee_id'] = $value['id'];
+ $temp['data']['relationship'] = $value['relationship'];
+ $temp['data']['name'] = $value['name'];
+ $temp['data']['dob'] = $this->convertDateFormatDMY($value['dob']);
+ $temp['data']['client_policy_id'] = $new_client_policy_id;
+ $temp['data']['form_type'] = $dependent;
+ $temp['data']['basic_cover_si'] = isset($employee_policy->basic_cover_si) ? $employee_policy->basic_cover_si : 0;
+
+
+ $temp['data']['age_validation'] = $this->getAgeRange($policy_terms, $familyFloatesValue);
+
+
+ array_push($data, $temp);
+ unset($empData[$key]);
+ $floters = array_diff($floters, [$familyFloatesValue]);
+ break;
}
}
-
- // Fetch results
- $data = $builder->findAll();
-
- return $this->respond([
- 'status' => true,
- 'message' => 'File list fetched successfully',
- 'data' => $data
- ]);
- } catch (\Exception $e) {
- return $this->failServerError($e->getMessage());
}
}
-
- public function hrFileUploadMasters()
- {
- try {
- //for inception upload
- $data['actions'] = ['inception' => 'Inception (Employee + Dependents)', 'missed_inception' => 'Missed Inception (Employee + Dependents)', 'addition' => 'Addition (Employee + Dependents)', 'dependent_addition' => 'Dependent Addition (Only Dependents)', 'deletion' => 'Deletion', 'correction' => 'Correction', 'si_enhancement' => 'SI Enhancement'];
-
- return $this->respond([
- 'status' => true,
- 'message' => 'File inception upload masters',
- 'data' => $data
- ]);
- } catch (\Exception $e) {
- return $this->failServerError($e->getMessage());
- }
- }
-
- public function downloadSampleExcel()
- {
- $employeeController = new EmployeeController();
- $file_path = $employeeController->downloadSampleExcelFile('enrollment', 1);
- if(empty($file_path)){
- return $this->respond(['status' => "success", 'code' => 404, 'data' => "", "message" => "Sample file not avilable"], 200);
- }else{
- return $this->respond(['status' => "success", 'code' => 200, 'data' => $file_path], 200);
- }
-
- }
+ if(!empty($data)){
+ return $this->respond(['status' => "success", 'code' => 200, 'data' => $data], 200);
+ }else{
+ return $this->respond(['status' => "failed", 'code' => 404, 'message' => "No data found", 'data' => []], 200);
+ }
+ }
}
\ No newline at end of file
diff --git a/app/Controllers/RestAuthenticationController.php b/app/Controllers/RestAuthenticationController.php
index 69d9e5e..22e834e 100755
--- a/app/Controllers/RestAuthenticationController.php
+++ b/app/Controllers/RestAuthenticationController.php
@@ -69,7 +69,10 @@ class RestAuthenticationController extends AdminController
{
$client = \Config\Services::curlrequest();
$url = env('POST_ENROLLMENT_BASEURL').$endPoint;
- $response = $client->post( $url, ['json' => $postData, 'http_errors' => false ] );
+ $headers = [
+ 'App-Signature' => getenv('APP_SIGNATURE'),
+ ];
+ $response = $client->post( $url, ['json' => $postData, 'headers' => $headers , 'http_errors' => false ] );
// return json_decode($response->getBody(), true);
return $response->getBody();
}
@@ -84,15 +87,17 @@ class RestAuthenticationController extends AdminController
$options = [
'query' => $queryParams,
'http_errors' => false,
+ 'headers' => [
+ 'App-Signature' => getenv('APP_SIGNATURE'),
+ 'Accept' => 'application/json'
+ ]
];
- if (isset($params['token']) && !empty($params['token'])) {
- $options['headers'] = [
- 'Authorization' => 'Bearer ' . $params['token'],
- 'Accept' => 'application/json'
- ];
+ if (!empty($params['token'])) {
+ $options['headers']['Authorization'] = 'Bearer ' . $params['token'];
}
+
$response = $client->get($url, $options);
return $response->getBody();
@@ -261,26 +266,63 @@ class RestAuthenticationController extends AdminController
$empdata = RestAuthHelper::getPreAndPostDataByEmailOrMobile(['email_id' => $email]);
// print_r($empdata); die;
+ $otp = random_int(100000, 999999);
+
if(empty($empdata)){
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyEmployeeWithEmailId: No employee data found both PRE & POST");
log_message('error', ' ');
log_message('error', '************************ PRE END ********************************');
+
+ $retailUserdata = RestAuthHelper::getRetailUserData(['email_id' => $email]);
+ // print_r($retailUserdata); die;
+
+ if (!empty($retailUserdata)) {
+
+ $retailApiParams['client_id'] = $retailUserdata['id'];
+ $retailApiParams['email_id'] = $email;
+ $retailApiParams['otp'] = $otp;
+
+ // update the otp in retail user
+ $api_response = $this->callThirdPartyAPI($retailApiParams, 'updateRetailUserAuthDetails');
+ $api_response = json_decode($api_response ?? '{}', true) ?? $api_response;
+ // print_r($api_response); die;
+ if (isset($api_response['status']) && $api_response['status'] == true) {
+
+ //send Email
+ $retail_common = [
+ 'client_id' => $retailUserdata['id'],
+ 'client_branch_id' => null,
+ 'client_policy_id' => null,
+ 'employee_policy_id' => null,
+ 'employee_id' => null,
+ 'mail_type' => 'retail_user_otp_mail',
+ ];
+
+ $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyEmployeeWithEmailId: Sending Retail user OTP email to " . $email);
+ $res = $this->sendEmailOtp($email, $otp, $retail_common);
+
+ if (json_decode($res)->status == 'success') {
+ $result = ['user_verification' => true, 'message' => "Verified Successfully"];
+ return $this->respond(['status' => 'success', 'code' => 200, 'data' => $result], 200);
+ } else {
+ $result = ['user_verification' => false, 'message' => "Mail sending failed , try again"];
+ return $this->respond(['status' => 'failed', 'code' => 404, 'data' => $result], 200);
+ }
+ }
+ }
+
$result = ['user_verification' => false , 'message' => "User not found"];
return $this->respond(['status' => 'failed','code' => 404,'data' => $result],200);
}
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyEmployeeWithEmailId: employee data both PRE & POST = " . json_encode($empdata));
-
-
$employeeData = [];
if (isset($empdata['pre']) && !empty($empdata['pre'])) {
$employeeData = $empdata['pre'];
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyEmployeeWithEmailId: Using PRE data");
}
- $otp = random_int(100000, 999999);
-
if (isset($employeeData['employee_id']))
{
@@ -318,7 +360,6 @@ class RestAuthenticationController extends AdminController
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyEmployeeWithEmailId: Calling callThirdPartyAPI for updateEmpOTP");
}
-
//send Email
$common = [
'client_id' => $employeeData['client_id'],
@@ -329,11 +370,8 @@ class RestAuthenticationController extends AdminController
'mail_type' => 'otp_mail',
];
- $subject = 'Nhance user verification - OTP';
- $mail_content = $otp . ' is your verification code for Nhance.';
-
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyEmployeeWithEmailId: Sending OTP email to " . $employeeData['email_corporate']);
- $res = MailHelper::send_email(['mail' => $employeeData['email_corporate'], 'subject' => $subject, 'common' => $common, 'message' => $mail_content]);
+ $res = $this->sendEmailOtp($employeeData['email_corporate'], $otp, $common);
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyEmployeeWithEmailId: Mail response = " . $res);
if (json_decode($res)->status == 'success') {
@@ -347,6 +385,7 @@ class RestAuthenticationController extends AdminController
$result = ['user_verification' => false, 'message' => "Mail sending failed , try again"];
return $this->respond(['status' => 'failed', 'code' => 404, 'data' => $result], 200);
}
+
} else {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyEmployeeWithEmailId: OTP update failed in PRE DATABASE");
log_message('error', ' ');
@@ -390,14 +429,37 @@ class RestAuthenticationController extends AdminController
$email_id = isset($this->request->getJSON()->email_id) ? $this->request->getJSON()->email_id : null;
$otp = isset($this->request->getJSON()->otp) ? $this->request->getJSON()->otp : null;
+ if(empty($otp)){
+ return $this->respond(['status' => 'OTP is required','code' => 400,'message' => 'OTP is required'], 200);
+ }
+
+ if (empty($mobile_number) && empty($email_id)) {
+ return $this->respond(['status' => 'failed','code' => 400,'message' => 'Mobile number or Email ID is required'], 200);
+ }
+
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - getVerifiedUserData: Fetching empdata via RestAuthHelper");
$empdata = RestAuthHelper::getPreAndPostDataByEmailOrMobile(['email_id' => $email_id, 'otp' => $otp, 'mobile_number' => $mobile_number ]);
if(empty($empdata)){
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - getVerifiedUserData: empdata is empty");
- log_message('error', ' ');
- log_message('error', '************************ PRE END ********************************');
+
+ $retailUserdata = RestAuthHelper::getRetailUserData(['email_id' => $email_id, 'mobile_number' => $mobile_number, 'otp' => $otp]);
+ // print_r($retailUserdata); die;
+
+ if (!empty($retailUserdata)) {
+
+ $retailApiParams['client_id'] = $retailUserdata['id'];
+ $retailApiParams['email_id'] = $email_id;
+ $retailApiParams['mobile_number'] = $mobile_number;
+ $retailApiParams['otp'] = $otp;
+
+ // Call the third-party API function
+ $apiResponse = $this->callThirdPartyAPI($retailApiParams, 'getVerifiedRetailUserData');
+ // print_r($apiResponse); die;
+ return $this->respond(['status' => 'failed', 'code' => 200, 'data' => [], 'post_enrollment' => json_decode($apiResponse, true)], 200);
+ }
+
return $this->respond(['status' => 'Invalid OTP','code' => 404,'data' => "", 'message' => "Invalid OTP"],200);
}
@@ -473,6 +535,15 @@ class RestAuthenticationController extends AdminController
// employee auth api's end
+ public function sendEmailOtp($email, $otp, $common)
+ {
+ $subject = 'Nhance user verification - OTP';
+ $mail_content = $otp . ' is your verification code for Nhance.';
+ $response = MailHelper::send_email(['mail' => $email, 'subject' => $subject, 'common' => $common, 'message' => $mail_content]);
+
+ return $response;
+ }
+
diff --git a/app/Filters/AuthJWT.php b/app/Filters/AuthJWT.php
index 484372a..262a5e5 100755
--- a/app/Filters/AuthJWT.php
+++ b/app/Filters/AuthJWT.php
@@ -20,7 +20,7 @@ class AuthJWT implements FilterInterface
{
public function before(RequestInterface $request, $arguments = null)
{
- $jwt = $request->getHeader('Authorization');
+ $jwt = $request->getHeaderLine('Authorization');
if ($jwt) {
if (JWTToken::validateJWT($jwt)) {
diff --git a/app/Filters/Cors.php b/app/Filters/Cors.php
new file mode 100644
index 0000000..c47f276
--- /dev/null
+++ b/app/Filters/Cors.php
@@ -0,0 +1,422 @@
+
+ */
+ protected array $allowedOrigins = [];
+
+ /**
+ * Whether to allow credentials (cookies, authorization headers) in CORS requests
+ * WARNING: Cannot be true if using wildcard (*) origin
+ *
+ * @var bool
+ */
+ protected bool $allowCredentials = false;
+
+ /**
+ * HTTP methods allowed for CORS requests
+ *
+ * @var string
+ */
+ protected string $allowedMethods = 'GET,POST,PUT,PATCH,DELETE,OPTIONS';
+
+ /**
+ * HTTP headers allowed in CORS requests
+ *
+ * @var string
+ */
+ protected string $allowedHeaders = 'Content-Type,Authorization,X-Requested-With,Accept,Origin';
+
+ /**
+ * Headers exposed to the client (accessible via JavaScript)
+ *
+ * @var string
+ */
+ protected string $exposeHeaders = '';
+
+ /**
+ * How long (in seconds) the preflight response can be cached
+ * Default: 24 hours (86400 seconds)
+ *
+ * @var int
+ */
+ protected int $maxAge = 86400;
+
+ /**
+ * Whether to enable debug logging for CORS requests
+ *
+ * @var bool
+ */
+ protected bool $debug = false;
+
+ /**
+ * Initialize CORS configuration from environment variables
+ *
+ * @throws \RuntimeException If configuration is invalid
+ */
+
+ protected $myLogger;
+ public function __construct()
+ {
+
+ $this->myLogger = \Config\Services::mylogger();
+ // Parse allowed origins from environment variable
+ // Format: comma or semicolon separated list
+ // Examples: "https://example.com,https://app.example.com" or "*.example.com"
+ $raw = env('CORS_ALLOWED_ORIGINS', '*');
+ $parts = preg_split('/\s*[,;]\s*/', trim($raw));
+ $this->allowedOrigins = array_filter(array_map('trim', $parts));
+
+ // Load other configuration from environment
+ $this->allowCredentials = filter_var(
+ env('CORS_ALLOW_CREDENTIALS', false),
+ FILTER_VALIDATE_BOOLEAN
+ );
+ $this->allowedMethods = env('CORS_ALLOWED_METHODS', $this->allowedMethods);
+ $this->allowedHeaders = env('CORS_ALLOWED_HEADERS', $this->allowedHeaders);
+ $this->exposeHeaders = env('CORS_EXPOSE_HEADERS', $this->exposeHeaders);
+ $this->maxAge = (int) env('CORS_MAX_AGE', $this->maxAge);
+ $this->debug = filter_var(env('CORS_DEBUG', false), FILTER_VALIDATE_BOOLEAN);
+
+ // Security validation: wildcard origin cannot be used with credentials
+ // This is a browser security requirement, not just a best practice
+ if ($this->allowCredentials && in_array('*', $this->allowedOrigins, true)) {
+ throw new \RuntimeException(
+ 'CORS configuration error: Cannot use wildcard (*) origin with credentials enabled. ' .
+ 'This violates browser security policies. Either disable credentials or specify explicit origins.'
+ );
+ }
+
+ $this->log('CORS filter initialized', [
+ 'allowed_origins' => $this->allowedOrigins,
+ 'allow_credentials' => $this->allowCredentials,
+ 'allowed_methods' => $this->allowedMethods,
+ ]);
+ }
+
+ /**
+ * Check if a given origin is allowed to access this API
+ *
+ * Supports:
+ * - Exact matches: https://example.com
+ * - Wildcard origins: *.example.com
+ * - Scheme-less matching: example.com (matches http and https)
+ * - Universal wildcard: *
+ *
+ * @param string|null $origin The Origin header from the request
+ * @return bool True if origin is allowed, false otherwise
+ */
+ protected function isOriginAllowed(?string $origin): bool
+ {
+ // Reject empty origins
+ if (empty($origin)) {
+ $this->log('Origin rejected: empty origin header');
+ return false;
+ }
+
+ // Validate origin format - must include scheme (http:// or https://)
+ // This prevents malformed origins from being accepted
+ if (!preg_match('#^https?://#i', $origin)) {
+ $this->log('Origin rejected: invalid format (missing scheme)', ['origin' => $origin]);
+ return false;
+ }
+
+ // If wildcard present in configuration, allow any origin
+ if (in_array('*', $this->allowedOrigins, true)) {
+ $this->log('Origin allowed: wildcard match', ['origin' => $origin]);
+ return true;
+ }
+
+ // Parse the host from the origin for wildcard matching
+ // Example: https://app.example.com:8080 → app.example.com
+ $originHost = parse_url($origin, PHP_URL_HOST) ?: $origin;
+
+ foreach ($this->allowedOrigins as $allowed) {
+ if ($allowed === '') {
+ continue;
+ }
+
+ // 1. Exact match (including scheme and port)
+ // Example: https://example.com matches https://example.com
+ if (strcasecmp($allowed, $origin) === 0) {
+ $this->log('Origin allowed: exact match', [
+ 'origin' => $origin,
+ 'matched_rule' => $allowed
+ ]);
+ return true;
+ }
+
+ // 2. Handle scheme-less and wildcard patterns
+ // If the allowed entry doesn't contain ://, it's either a host-only or wildcard pattern
+ if (strpos($allowed, '://') === false) {
+
+ // 2a. Wildcard subdomain pattern: *.example.com
+ // Matches: app.example.com, api.example.com, dev.app.example.com
+ // Does NOT match: example.com (use explicit entry for root domain)
+ if (strpos($allowed, '*.') === 0) {
+ $allowedRoot = substr($allowed, 2); // Remove *. prefix
+
+ // Check if origin host ends with the allowed root domain
+ if ($originHost === $allowedRoot || str_ends_with($originHost, '.' . $allowedRoot)) {
+ $this->log('Origin allowed: wildcard subdomain match', [
+ 'origin' => $origin,
+ 'matched_rule' => $allowed,
+ 'origin_host' => $originHost
+ ]);
+ return true;
+ }
+ }
+ // 2b. Direct host match (scheme-less)
+ // Allows both http and https for the same host
+ // Example: example.com matches both http://example.com and https://example.com
+ else {
+ if (strcasecmp($allowed, $originHost) === 0) {
+ $this->log('Origin allowed: host match (scheme-less)', [
+ 'origin' => $origin,
+ 'matched_rule' => $allowed,
+ 'origin_host' => $originHost
+ ]);
+ return true;
+ }
+ }
+ }
+ }
+
+ // No match found - reject this origin
+ $this->log('Origin rejected: no matching rule', [
+ 'origin' => $origin,
+ 'checked_rules' => $this->allowedOrigins
+ ]);
+ return false;
+ }
+
+ /**
+ * Build the Access-Control-Allow-Origin header value
+ *
+ * Returns either:
+ * - '*' if wildcard is configured and credentials are disabled
+ * - The actual origin value if credentials are enabled or specific origins configured
+ *
+ * Note: When credentials are enabled, you MUST echo back the specific origin,
+ * browsers reject wildcard with credentials.
+ *
+ * @param string $origin The validated origin
+ * @return string The value for Access-Control-Allow-Origin header
+ */
+ protected function buildAllowOriginHeader(string $origin): string
+ {
+ // If wildcard configured and credentials NOT required, can safely return '*'
+ // This allows any origin to access the resource
+ if (in_array('*', $this->allowedOrigins, true) && !$this->allowCredentials) {
+ return '*';
+ }
+
+ // Otherwise, must return the specific origin
+ // This is required when allow-credentials is true
+ return $origin;
+ }
+
+ /**
+ * Add all CORS headers to the response
+ *
+ * This method is called for both preflight and actual requests
+ * to ensure consistent CORS headers across all responses.
+ *
+ * @param ResponseInterface $response The response object to add headers to
+ * @param RequestInterface $request The original request
+ * @param string $origin The validated origin
+ * @param bool $isPreflight Whether this is a preflight OPTIONS request
+ * @return void
+ */
+ protected function addCorsHeaders(
+ ResponseInterface $response,
+ RequestInterface $request,
+ string $origin,
+ bool $isPreflight = false
+ ): void {
+ // CRITICAL: Vary header prevents caching issues
+ // Without this, a cached response for origin A might be served to origin B,
+ // causing CORS errors because the Access-Control-Allow-Origin won't match
+ $response->setHeader('Vary', 'Origin');
+
+ // Set the allowed origin
+ $allowOrigin = $this->buildAllowOriginHeader($origin);
+ $response->setHeader('Access-Control-Allow-Origin', $allowOrigin);
+
+ // If credentials are allowed, set the header
+ // This allows cookies, authorization headers, and TLS client certificates
+ if ($this->allowCredentials) {
+ $response->setHeader('Access-Control-Allow-Credentials', 'true');
+ }
+
+ // Allowed HTTP methods
+ $response->setHeader('Access-Control-Allow-Methods', $this->allowedMethods);
+
+ // Handle allowed headers
+ if ($isPreflight) {
+ // For preflight: respect what the browser is asking for
+ // The browser sends Access-Control-Request-Headers to ask permission
+ $requestedHeaders = $request->getHeaderLine('Access-Control-Request-Headers');
+ $response->setHeader(
+ 'Access-Control-Allow-Headers',
+ $requestedHeaders ?: $this->allowedHeaders
+ );
+ } else {
+ // For actual requests: use configured headers
+ // Access-Control-Request-Headers is only for preflight
+ $response->setHeader('Access-Control-Allow-Headers', $this->allowedHeaders);
+ }
+
+ // Expose additional headers to the client (accessible via JavaScript)
+ // Without this, only simple headers are accessible: Cache-Control, Content-Language,
+ // Content-Type, Expires, Last-Modified, Pragma
+ if (!empty($this->exposeHeaders)) {
+ $response->setHeader('Access-Control-Expose-Headers', $this->exposeHeaders);
+ }
+
+ // Cache duration for preflight responses
+ // Reduces preflight requests by allowing browser to cache the permissions
+ if ($this->maxAge > 0) {
+ $response->setHeader('Access-Control-Max-Age', (string) $this->maxAge);
+ }
+ }
+
+ /**
+ * Execute before the controller
+ *
+ * Handles preflight OPTIONS requests by returning early with appropriate headers.
+ * For other requests, allows them to proceed to the controller.
+ *
+ * @param RequestInterface $request The request object
+ * @param mixed $arguments Optional arguments
+ * @return ResponseInterface|null Response for preflight, null for other requests
+ */
+ public function before(RequestInterface $request, $arguments = null)
+ {
+ $origin = $request->getHeaderLine('Origin') ?: '';
+ $method = strtoupper($request->getMethod());
+
+ // Handle preflight OPTIONS requests
+ // Preflight is sent by browsers before actual cross-origin requests
+ // to check if the actual request is safe to send
+ if ($method === 'OPTIONS') {
+ $this->log('Preflight request received', [
+ 'origin' => $origin,
+ 'method' => $method,
+ 'uri' => (string) $request->getUri()
+ ]);
+
+ // Validate origin - reject if not allowed
+ if (empty($origin) || !$this->isOriginAllowed($origin)) {
+ $this->log('Preflight rejected: origin not allowed', ['origin' => $origin]);
+
+ // Return 403 Forbidden for rejected origins
+ // Some prefer 200 with no CORS headers, but 403 is more explicit
+ return Services::response()
+ ->setStatusCode(403)
+ ->setJSON(['error' => 'Origin not allowed']);
+ }
+
+ // Origin is valid - build preflight response
+ $response = Services::response();
+ $this->addCorsHeaders($response, $request, $origin, true);
+
+ // 204 No Content is the standard response for successful preflight
+ // It indicates "permission granted, but no data to return"
+ $response->setStatusCode(204);
+ $response->setBody('');
+
+ $this->log('Preflight approved', [
+ 'origin' => $origin,
+ 'allowed_methods' => $this->allowedMethods
+ ]);
+
+ return $response;
+ }
+
+ // For non-OPTIONS requests, don't return a response
+ // Let the request proceed to the controller
+ // CORS headers will be added in after() method
+ return null;
+ }
+
+ /**
+ * Execute after the controller
+ *
+ * Adds CORS headers to the response for actual (non-preflight) requests.
+ * This ensures all API responses include proper CORS headers.
+ *
+ * @param RequestInterface $request The request object
+ * @param ResponseInterface $response The response object
+ * @param mixed $arguments Optional arguments
+ * @return void
+ */
+ public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
+ {
+ $origin = $request->getHeaderLine('Origin') ?: '';
+
+ // Only add CORS headers if origin is present and allowed
+ // No origin header means it's a same-origin request (no CORS needed)
+ if (empty($origin)) {
+ return;
+ }
+
+ if (!$this->isOriginAllowed($origin)) {
+ $this->log('Response blocked: origin not allowed', [
+ 'origin' => $origin,
+ 'uri' => (string) $request->getUri()
+ ]);
+ return;
+ }
+
+ // Add CORS headers to the response
+ $this->addCorsHeaders($response, $request, $origin, false);
+
+ $this->log('CORS headers added to response', [
+ 'origin' => $origin,
+ 'status' => $response->getStatusCode()
+ ]);
+ }
+
+ /**
+ * Log debug information if debug mode is enabled
+ *
+ * Logs to CodeIgniter's log system at 'info' level.
+ * Enable with CORS_DEBUG=true in .env file.
+ *
+ * @param string $message The log message
+ * @param array $context Additional context data
+ * @return void
+ */
+ protected function log(string $message, array $context = []): void
+ {
+ if (!$this->debug) {
+ return;
+ }
+
+ // $logger = Services::logger();
+ $contextString = !empty($context) ? json_encode($context, JSON_UNESCAPED_SLASHES) : '';
+ $this->myLogger->logme('error','[CORS] ' . $message . ($contextString ? ' | ' . $contextString : ''));
+ // $logger->info('[CORS] ' . $message . ($contextString ? ' | ' . $contextString : ''));
+ }
+}
\ No newline at end of file
diff --git a/app/Filters/VerifyAppSignature.php b/app/Filters/VerifyAppSignature.php
new file mode 100644
index 0000000..a5257b2
--- /dev/null
+++ b/app/Filters/VerifyAppSignature.php
@@ -0,0 +1,36 @@
+getHeaderLine('App-Signature');
+
+ // Load the server's expected signature from the .env
+ $validSignature = getenv('APP_SIGNATURE');
+
+ // Check if signature is valid
+ if ($clientSignature !== $validSignature) {
+ return service('response')
+ ->setStatusCode(403)
+ ->setJSON([
+ 'status' => false,
+ 'message' => 'Forbidden: Invalid App Signature',
+ ]);
+ }
+
+ // allow request to proceed
+ }
+
+ public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
+ {
+ // nothing to do after response
+ }
+}
diff --git a/app/Helpers/RestAuthHelper.php b/app/Helpers/RestAuthHelper.php
index 1308676..121c9cb 100644
--- a/app/Helpers/RestAuthHelper.php
+++ b/app/Helpers/RestAuthHelper.php
@@ -346,6 +346,9 @@ class RestAuthHelper
$client = \Config\Services::curlrequest();
$endPoint = 'getPostEmployeeDataForAuth';
$url = env('POST_ENROLLMENT_BASEURL') . $endPoint;
+ $headers = [
+ 'App-Signature' => getenv('APP_SIGNATURE'),
+ ];
$postData = [];
@@ -368,7 +371,7 @@ class RestAuthHelper
log_message('error', 'Sending POST to external API: ' . $url);
log_message('error', 'POST payload: ' . json_encode($postData));
- $response = $client->post($url, ['json' => $postData, 'http_errors' => false]);
+ $response = $client->post($url, ['json' => $postData, 'headers' => $headers , 'http_errors' => false]);
$post_json = $response->getBody();
// log_message('error', 'Response from API: ' . $post_json);
@@ -380,7 +383,7 @@ class RestAuthHelper
return $data;
}
- log_message('warning', 'No mobile or email present in params for post fetch.');
+ log_message('error', 'No mobile or email present in params for post fetch.');
}
public static function updatePreMpin(array $params)
@@ -437,4 +440,60 @@ class RestAuthHelper
log_message('warning', '[updatePostMpin] Missing required parameters: employee_id or mpin');
return false;
}
+
+ // ----------------------------------------------------------------------------------------------
+
+ public static function getRetailUserData(array $params)
+ {
+ log_message('error', 'Function getRetailUserData called with: ' . json_encode($params));
+
+ $mobile_number = $params['mobile_number'] ?? null;
+ $email_id = $params['email_id'] ?? null;
+ $otp = $params['otp'] ?? null;
+ $old_mpin = $params['old_mpin'] ?? null;
+
+ if (!empty($mobile_number) || !empty($email_id)) {
+
+ $client = \Config\Services::curlrequest();
+ $endPoint = 'getRetailUserData';
+ $url = env('POST_ENROLLMENT_BASEURL') . $endPoint;
+ $headers = [
+ 'App-Signature' => getenv('APP_SIGNATURE'),
+ ];
+
+ $postData = [];
+
+ if (!empty($mobile_number)) {
+ $postData['mobile_number'] = $mobile_number;
+ }
+
+ if (!empty($email_id)) {
+ $postData['email_id'] = $email_id;
+ }
+
+ if (!empty($otp)) {
+ $postData['otp'] = $otp;
+ }
+
+ if (!empty($old_mpin)) {
+ $postData['old_mpin'] = $old_mpin;
+ }
+
+ log_message('error', 'Sending POST to external API: ' . $url);
+ log_message('error', 'POST payload: ' . json_encode($postData));
+
+ $response = $client->post($url, ['json' => $postData, 'headers' => $headers, 'http_errors' => false]);
+
+ $post_json = $response->getBody();
+ // print_r($post_json);
+
+ $post_data = json_decode($post_json, true);
+
+ $data = $post_data['data'] ?? [];
+ log_message('error', 'Parsed post_data: ' . json_encode($data));
+ return $data;
+ }
+
+ return [];
+ }
}
diff --git a/app/Helpers/utility_helper.php b/app/Helpers/utility_helper.php
index 3372200..765b8af 100755
--- a/app/Helpers/utility_helper.php
+++ b/app/Helpers/utility_helper.php
@@ -666,3 +666,35 @@ if (!function_exists('check_pay_by_employee_or_company')) {
}
+if (!function_exists('getLatestGMCPolicy')) {
+
+ function getLatestGMCPolicy(array $empPolicy)
+ {
+ try{
+ $filtered = array_filter($empPolicy, function ($row) {
+ $type = is_object($row) ? $row->policy_type_id : $row['policy_type_id'];
+ return isset($type) && (int)$type === 2;
+ });
+
+ if (count($filtered) > 1) {
+
+ usort($filtered, function ($a, $b) {
+ $dateA = is_object($a) ? $a->policy_end_date : $a['policy_end_date'];
+ $dateB = is_object($b) ? $b->policy_end_date : $b['policy_end_date'];
+ return strtotime($dateB) <=> strtotime($dateA);
+ });
+
+ $row = reset($filtered);
+ return is_object($row) ? ($row->ClientPolicyId ?? null) : ($row['ClientPolicyId'] ?? null);
+ }
+
+ return null;
+
+ }catch(\Exception $e){
+ log_message('error', 'Exception getLatestGMCPolicy :' . $e->getMessage());
+ return null;
+ }
+ }
+
+}
+
diff --git a/app/Models/EmployeeModel.php b/app/Models/EmployeeModel.php
index 2cfc852..c556bdb 100755
--- a/app/Models/EmployeeModel.php
+++ b/app/Models/EmployeeModel.php
@@ -166,7 +166,8 @@ class EmployeeModel extends Model
client_policy.disclaimer,
client_policy.policy_type_id ,
employee_polices.tpa_id as tpa_id ,
- employee_polices.rand_string as rand_string
+ employee_polices.rand_string as rand_string,
+ client_policy.policy_end_date
', FALSE) // Select all columns from both tables
->join('client_policy', 'client_policy.id = employee_polices.client_policy_id')
->join('policy_type', 'policy_type.id = client_policy.policy_type_id')
diff --git a/app/Views/client_policy.php b/app/Views/client_policy.php
index fe028ca..b2f4917 100755
--- a/app/Views/client_policy.php
+++ b/app/Views/client_policy.php
@@ -60,8 +60,71 @@
#table-client-policy_filter{
text-align: left;
}
-
+
+
+
+
@@ -227,7 +290,7 @@
required>
-
+
+
+
@@ -261,15 +333,26 @@
-
-
+
+
+
+
+
+
+
+
+ Policy Visibilty in Enrollment App
+
+
+
+
-
+
+
+
+
+
+
+
+
+ Is LGBTQ Enable
+
+
+
+
+
+
+
+ Is Premium Summary Display Enabled
+
diff --git a/ca.pem b/ca.pem
new file mode 100644
index 0000000..a303fe9
--- /dev/null
+++ b/ca.pem
@@ -0,0 +1,76 @@
+-----BEGIN CERTIFICATE-----
+MIIEADCCAuigAwIBAgIQB/57HSuaqUkLaasdjxUdPjANBgkqhkiG9w0BAQsFADCB
+mDELMAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIElu
+Yy4xEzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTEwLwYDVQQDDChB
+bWF6b24gUkRTIGFwLXNvdXRoLTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQH
+DAdTZWF0dGxlMCAXDTIxMDUxOTE3NDAzNFoYDzIwNjEwNTE5MTg0MDM0WjCBmDEL
+MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x
+EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTEwLwYDVQQDDChBbWF6
+b24gUkRTIGFwLXNvdXRoLTEgUm9vdCBDQSBSU0EyMDQ4IEcxMRAwDgYDVQQHDAdT
+ZWF0dGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtbkaoVsUS76o
+TgLFmcnaB8cswBk1M3Bf4IVRcwWT3a1HeJSnaJUqWHCJ+u3ip/zGVOYl0gN1MgBb
+MuQRIJiB95zGVcIa6HZtx00VezDTr3jgGWRHmRjNVCCHGmxOZWvJjsIE1xavT/1j
+QYV/ph4EZEIZ/qPq7e3rHohJaHDe23Z7QM9kbyqp2hANG2JtU/iUhCxqgqUHNozV
+Zd0l5K6KnltZQoBhhekKgyiHqdTrH8fWajYl5seD71bs0Axowb+Oh0rwmrws3Db2
+Dh+oc2PwREnjHeca9/1C6J2vhY+V0LGaJmnnIuOANrslx2+bgMlyhf9j0Bv8AwSi
+dSWsobOhNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQb7vJT
+VciLN72yJGhaRKLn6Krn2TAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD
+ggEBAAxEj8N9GslReAQnNOBpGl8SLgCMTejQ6AW/bapQvzxrZrfVOZOYwp/5oV0f
+9S1jcGysDM+DrmfUJNzWxq2Y586R94WtpH4UpJDGqZp+FuOVJL313te4609kopzO
+lDdmd+8z61+0Au93wB1rMiEfnIMkOEyt7D2eTFJfJRKNmnPrd8RjimRDlFgcLWJA
+3E8wca67Lz/G0eAeLhRHIXv429y8RRXDtKNNz0wA2RwURWIxyPjn1fHjA9SPDkeW
+E1Bq7gZj+tBnrqz+ra3yjZ2blss6Ds3/uRY6NYqseFTZWmQWT7FolZEnT9vMUitW
+I0VynUbShVpGf6946e0vgaaKw20=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICrjCCAjWgAwIBAgIQGKVv+5VuzEZEBzJ+bVfx2zAKBggqhkjOPQQDAzCBlzEL
+MAkGA1UEBhMCVVMxIjAgBgNVBAoMGUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4x
+EzARBgNVBAsMCkFtYXpvbiBSRFMxCzAJBgNVBAgMAldBMTAwLgYDVQQDDCdBbWF6
+b24gUkRTIGFwLXNvdXRoLTEgUm9vdCBDQSBFQ0MzODQgRzExEDAOBgNVBAcMB1Nl
+YXR0bGUwIBcNMjEwNTE5MTc1MDU5WhgPMjEyMTA1MTkxODUwNTlaMIGXMQswCQYD
+VQQGEwJVUzEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNlcywgSW5jLjETMBEG
+A1UECwwKQW1hem9uIFJEUzELMAkGA1UECAwCV0ExMDAuBgNVBAMMJ0FtYXpvbiBS
+RFMgYXAtc291dGgtMSBSb290IENBIEVDQzM4NCBHMTEQMA4GA1UEBwwHU2VhdHRs
+ZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMqdLJ0tZF/DGFZTKZDrGRJZID8ivC2I
+JRCYTWweZKCKSCAzoiuGGHzJhr5RlLHQf/QgmFcgXsdmO2n3CggzhA4tOD9Ip7Lk
+P05eHd2UPInyPCHRgmGjGb0Z+RdQ6zkitKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAd
+BgNVHQ4EFgQUC1yhRgVqU5bR8cGzOUCIxRpl4EYwDgYDVR0PAQH/BAQDAgGGMAoG
+CCqGSM49BAMDA2cAMGQCMG0c/zLGECRPzGKJvYCkpFTCUvdP4J74YP0v/dPvKojL
+t/BrR1Tg4xlfhaib7hPc7wIwFvgqHes20CubQnZmswbTKLUrgSUW4/lcKFpouFd2
+t2/ewfi/0VhkeUW+IiHhOMdU
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGATCCA+mgAwIBAgIRAKlQ+3JX9yHXyjP/Ja6kZhkwDQYJKoZIhvcNAQEMBQAw
+gZgxCzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJ
+bmMuMRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTExMC8GA1UEAwwo
+QW1hem9uIFJEUyBhcC1zb3V0aC0xIFJvb3QgQ0EgUlNBNDA5NiBHMTEQMA4GA1UE
+BwwHU2VhdHRsZTAgFw0yMTA1MTkxNzQ1MjBaGA8yMTIxMDUxOTE4NDUyMFowgZgx
+CzAJBgNVBAYTAlVTMSIwIAYDVQQKDBlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMu
+MRMwEQYDVQQLDApBbWF6b24gUkRTMQswCQYDVQQIDAJXQTExMC8GA1UEAwwoQW1h
+em9uIFJEUyBhcC1zb3V0aC0xIFJvb3QgQ0EgUlNBNDA5NiBHMTEQMA4GA1UEBwwH
+U2VhdHRsZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKtahBrpUjQ6
+H2mni05BAKU6Z5USPZeSKmBBJN3YgD17rJ93ikJxSgzJ+CupGy5rvYQ0xznJyiV0
+91QeQN4P+G2MjGQR0RGeUuZcfcZitJro7iAg3UBvw8WIGkcDUg+MGVpRv/B7ry88
+7E4OxKb8CPNoa+a9j6ABjOaaxaI22Bb7j3OJ+JyMICs6CU2bgkJaj3VUV9FCNUOc
+h9PxD4jzT9yyGYm/sK9BAT1WOTPG8XQUkpcFqy/IerZDfiQkf1koiSd4s5VhBkUn
+aQHOdri/stldT7a+HJFVyz2AXDGPDj+UBMOuLq0K6GAT6ThpkXCb2RIf4mdTy7ox
+N5BaJ+ih+Ro3ZwPkok60egnt/RN98jgbm+WstgjJWuLqSNInnMUgkuqjyBWwePqX
+Kib+wdpyx/LOzhKPEFpeMIvHQ3A0sjlulIjnh+j+itezD+dp0UNxMERlW4Bn/IlS
+sYQVNfYutWkRPRLErXOZXtlxxkI98JWQtLjvGzQr+jywxTiw644FSLWdhKa6DtfU
+2JWBHqQPJicMElfZpmfaHZjtXuCZNdZQXWg7onZYohe281ZrdFPOqC4rUq7gYamL
+T+ZB+2P+YCPOLJ60bj/XSvcB7mesAdg8P0DNddPhHUFWx2dFqOs1HxIVB4FZVA9U
+Ppbv4a484yxjTgG7zFZNqXHKTqze6rBBAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB
+Af8wHQYDVR0OBBYEFCEAqjighncv/UnWzBjqu1Ka2Yb4MA4GA1UdDwEB/wQEAwIB
+hjANBgkqhkiG9w0BAQwFAAOCAgEAYyvumblckIXlohzi3QiShkZhqFzZultbFIu9
+GhA5CDar1IFMhJ9vJpO9nUK/camKs1VQRs8ZsBbXa0GFUM2p8y2cgUfLwFULAiC/
+sWETyW5lcX/xc4Pyf6dONhqFJt/ovVBxNZtcmMEWv/1D6Tf0nLeEb0P2i/pnSRR4
+Oq99LVFjossXtyvtaq06OSiUUZ1zLPvV6AQINg8dWeBOWRcQYhYcEcC2wQ06KShZ
+0ahuu7ar5Gym3vuLK6nH+eQrkUievVomN/LpASrYhK32joQ5ypIJej3sICIgJUEP
+UoeswJ+Z16f3ECoL1OSnq4A0riiLj1ZGmVHNhM6m/gotKaHNMxsK9zsbqmuU6IT/
+P6cR0S+vdigQG8ZNFf5vEyVNXhl8KcaJn6lMD/gMB2rY0qpaeTg4gPfU5wcg8S4Y
+C9V//tw3hv0f2n+8kGNmqZrylOQDQWSSo8j8M2SRSXiwOHDoTASd1fyBEIqBAwzn
+LvXVg8wQd1WlmM3b0Vrsbzltyh6y4SuKSkmgufYYvC07NknQO5vqvZcNoYbLNea3
+76NkFaMHUekSbwVejZgG5HGwbaYBgNdJEdpbWlA3X4yGRVxknQSUyt4dZRnw/HrX
+k8x6/wvtw7wht0/DOqz1li7baSsMazqxx+jDdSr1h9xML416Q4loFCLgqQhil8Jq
+Em4Hy3A=
+-----END CERTIFICATE-----