Merge branch 'dev' of bitbucket.org:jubilian/nhance-enrollment into dev

This commit is contained in:
Gowtham M 2025-11-25 11:36:26 +05:30
commit 125af14d1c
27 changed files with 2030 additions and 260 deletions

View File

@ -1,6 +1,7 @@
# README # # README #
This README would normally document whatever steps are necessary to get your application up and running. This README would normally document whatever steps are necessary to get your application up and running.
This is test cmd for checking auto deploy
### What is this repository for? ### ### What is this repository for? ###

View File

@ -14,6 +14,7 @@ use App\Filters\HttpRequestLog;
use App\Filters\CloseDbConnection; use App\Filters\CloseDbConnection;
use App\Filters\AuthJWT; use App\Filters\AuthJWT;
use App\Filters\Cors;
class Filters extends BaseConfig class Filters extends BaseConfig
{ {
@ -35,6 +36,7 @@ class Filters extends BaseConfig
'HttpRequestLog' => HttpRequestLog::class, 'HttpRequestLog' => HttpRequestLog::class,
'authJWT' => AuthJWT::class, 'authJWT' => AuthJWT::class,
'CloseDbConnection' => CloseDbConnection::class 'CloseDbConnection' => CloseDbConnection::class
'Cors' => Cors::class
]; ];
/** /**
@ -47,11 +49,13 @@ class Filters extends BaseConfig
public array $globals = [ public array $globals = [
'before' => [ 'before' => [
'HttpRequestLog' => ['except' => 'cli/*'], 'HttpRequestLog' => ['except' => 'cli/*'],
'Cors',
// 'csrf', // 'csrf',
// 'invalidchars', // 'invalidchars',
], ],
'after' => [ 'after' => [
'CloseDbConnection' 'CloseDbConnection'
'Cors',
// 'secureheaders', // 'secureheaders',
], ],
]; ];

View File

@ -434,8 +434,6 @@ $routes->cli('cli/new_gdrive_token', 'GoogleDriveController::generateNewGoogleDr
//Employee login api's //Employee login api's
$routes->post("/employeeRest/verifyEmployeeNumber", "RestAuthenticationController::verifyEmployeeWithMobileNumber"); $routes->post("/employeeRest/verifyEmployeeNumber", "RestAuthenticationController::verifyEmployeeWithMobileNumber");
$routes->post("/employeeRest/getVerifiedUserData", "RestAuthenticationController::getVerifiedUserData"); $routes->post("/employeeRest/getVerifiedUserData", "RestAuthenticationController::getVerifiedUserData");
$routes->post("/employeeRest/verifyMpin", "RestAuthenticationController::verifyMpin");
$routes->post("/employeeRest/checkMpin", "RestAuthenticationController::checkMpin");
$routes->post("/employeeRest/verifyEmployeeEmailId", "RestAuthenticationController::verifyEmployeeWithEmailId"); $routes->post("/employeeRest/verifyEmployeeEmailId", "RestAuthenticationController::verifyEmployeeWithEmailId");
// $routes->post("/employeeRest/saveMpin", "RestAuthenticationController::saveMpin"); // $routes->post("/employeeRest/saveMpin", "RestAuthenticationController::saveMpin");
@ -450,10 +448,23 @@ $routes->group("/api", ["filter" => "authJWT"], function ($routes) {
$routes->post("getId", "RestAuthenticationController::getUserIdFromToken"); $routes->post("getId", "RestAuthenticationController::getUserIdFromToken");
}); });
// MPIN api's
$routes->post("employeeRest/saveMpin", "RestAuthenticationController::saveMpin"); $routes->post("employeeRest/saveMpin", "RestAuthenticationController::saveMpin");
$routes->post("employeeRest/updateMpin", "RestAuthenticationController::updateMpin"); $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/forgotMPIN", "RestAuthenticationController::forgotMPIN");
$routes->post("calculatePremium", "EmployeeRestController::calculatePremium"); $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/createOrUpdateEmployeePolicySiAmount", "EmployeeRestController::createOrUpdateEmployeePolicySiAmount");
// $routes->post("employeeRest/calculatePremium", "EmployeeRestController::calculatePremium"); // $routes->post("employeeRest/calculatePremium", "EmployeeRestController::calculatePremium");
@ -505,11 +516,12 @@ $routes->group("employeeRest", ["filter" => "authJWT"], function ($routes) {
$routes->post("hrFileUpload", "EmployeeRestController::hrFileUpload"); $routes->post("hrFileUpload", "EmployeeRestController::hrFileUpload");
}); });
$routes->get("getEmployeeActiveOrInactivePolicy", "EmployeeRestController::getEmployeeActiveOrInactivePolicy"); $routes->get("getEmployeeActiveOrInactivePolicy", "EmployeeRestController::getEmployeeActiveOrInactivePolicy");
$routes->get("sendPushNotification", "EmployeeRestController::sendPushNotification"); $routes->get("sendPushNotification", "EmployeeRestController::sendPushNotification");
$routes->post("sendEmail", "EmployeeRestController::send_email"); $routes->post("sendEmail", "EmployeeRestController::send_email");
$routes->get("getPolicyLevelEmployeeSummaryData", "EmployeeRestController::getPolicyLevelEmployeeSummaryData"); $routes->get("getPolicyLevelEmployeeSummaryData", "EmployeeRestController::getPolicyLevelEmployeeSummaryData");
$routes->post("calculatePremium", "EmployeeRestController::calculatePremium");
$routes->get("getBackToEnrolledDetails", "EmployeeRestController::getBackToEnrolledDetails"); $routes->get("getBackToEnrolledDetails", "EmployeeRestController::getBackToEnrolledDetails");
//crone job //crone job
@ -530,5 +542,7 @@ $routes->get('notification_mail_header',"NotificationController::notification_ma
$routes->get('notification_mail_footer',"NotificationController::notification_mail_footer"); $routes->get('notification_mail_footer',"NotificationController::notification_mail_footer");
$routes->group('test',function($routes){
$routes->get('logo_renaming','TestingController::logo_renaming');
});

View File

@ -684,6 +684,12 @@ class ClientController extends AdminController
$insert = $this->clientModel->insert($data); $insert = $this->clientModel->insert($data);
if ($insert) { if ($insert) {
$client_data = $this->clientModel->where(['id' => $insert, 'is_active' => 1])->first(); $client_data = $this->clientModel->where(['id' => $insert, 'is_active' => 1])->first();
$client_id = $insert;
$default_template_creation = $this->createDefaultMailTemplate($client_id , $client_data);
if($default_template_creation == false){
$this->myLogger->logme('error', 'Default Mail Template Creation Failed for Client ID: {data}', ['data' => $client_id]);
}
return $this->respond(['status' => true, 'code' => 200, 'data' => $client_data], 200); return $this->respond(['status' => true, 'code' => 200, 'data' => $client_data], 200);
} else { } else {
return $this->respond(['status' => false, 'code' => 404, 'message' => 'no data found'], 200); return $this->respond(['status' => false, 'code' => 404, 'message' => 'no data found'], 200);
@ -5334,6 +5340,76 @@ class ClientController extends AdminController
} }
public function createDefaultMailTemplate($client_id , $client_data){
$member_welcome_mail_template = $this->notificationModel->where('client_id',NULL)->where('template_name','member_welcome_mail')->get()->getResultArray()[0]??[];
$member_remainder_mail_template = $this->notificationModel->where('client_id',NULL)->where('template_name','member_reminder_mail')->get()->getResultArray()[0]??[];
$member_review_and_summary_mail_template = $this->notificationModel->where('client_id',NULL)->where('template_name','member_review_and_summary_mail')->get()->getResultArray()[0]??[];
$default_member_welcome_mail_template = [
'client_id' => $client_id,
'template_name' => 'member_welcome_mail',
'subject' => $member_welcome_mail_template['subject']??'',
'mail_content' => $member_welcome_mail_template['mail_content']??'',
'mail_content_json'=> $member_welcome_mail_template['mail_content_json']??'',
'created_by' => get_session_userid(),
'created_at' => date('Y-m-d H:i:s'),
'updated_by' => null,
'updated_at' => date('Y-m-d H:i:s'),
'mail_content_copy'=> null
];
$default_member_remainder_mail_template = [
'client_id' => $client_id,
'template_name' => 'member_reminder_mail',
'subject' => $member_remainder_mail_template['subject']??'',
'mail_content' => $member_remainder_mail_template['mail_content']??'',
'mail_content_json'=> $member_remainder_mail_template['mail_content_json']??'',
'created_by' => get_session_userid(),
'created_at' => date('Y-m-d H:i:s'),
'updated_by' => null,
'updated_at' => date('Y-m-d H:i:s'),
'mail_content_copy'=> null
];
$default_member_review_and_summary_mail_template = [
'client_id' => $client_id,
'template_name' => 'member_review_and_summary_mail',
'subject' => $member_review_and_summary_mail_template['subject']??'',
'mail_content' => $member_review_and_summary_mail_template['mail_content']??'',
'mail_content_json'=> $member_review_and_summary_mail_template['mail_content_json']??'',
'created_by' => get_session_userid(),
'created_at' => date('Y-m-d H:i:s'),
'updated_by' => null,
'updated_at' => date('Y-m-d H:i:s'),
'mail_content_copy'=> null
];
$this->myLogger->logme('error', 'Default Mail Template Data ' . json_encode([
$default_member_welcome_mail_template,
$default_member_remainder_mail_template,
$default_member_review_and_summary_mail_template
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
$default_templates_inserted = $this->notificationModel->insertBatch([
$default_member_welcome_mail_template,
$default_member_remainder_mail_template,
$default_member_review_and_summary_mail_template
]);
return $default_templates_inserted ? true : false;
}

View File

@ -412,27 +412,48 @@ class EmployeeController extends AdminController
* @return redirect back with an error message if the file is not found, otherwise sends the file to the user for download. * @return redirect back with an error message if the file is not found, otherwise sends the file to the user for download.
*/ */
public function downloadSampleExcelFile($actionType = null) public function downloadSampleExcelFile($actionType = null, $return_type = 0)
{ {
// $actionType = $this->request->getGet(); // $actionType = $this->request->getGet();
$filePath = ''; $filePath = '';
// Path to your file // Path to your file
if ($actionType == 'inception') { if ($actionType == 'inception') {
$filePath = ROOTPATH . 'public/sample_excel/sample_inception.xls'; $filePath = ($return_type == 1)
? base_url('public/sample_excel/sample_inception.xls')
: ROOTPATH . 'public/sample_excel/sample_inception.xls';
} else if ($actionType == 'correction') { } else if ($actionType == 'correction') {
$filePath = ROOTPATH . 'public/sample_excel/sample_correction .xls'; $filePath = ($return_type == 1)
? base_url('public/sample_excel/sample_correction.xls')
: ROOTPATH . 'public/sample_excel/sample_correction.xls';
} else if ($actionType == 'si_enhancement') { } else if ($actionType == 'si_enhancement') {
$filePath = ROOTPATH . 'public/sample_excel/sample_si_enhancement.xls'; $filePath = ($return_type == 1)
? base_url('public/sample_excel/sample_si_enhancement.xls')
: ROOTPATH . 'public/sample_excel/sample_si_enhancement.xls';
} else if ($actionType == 'dependent_addtion') { } else if ($actionType == 'dependent_addtion') {
$filePath = ROOTPATH . 'public/sample_excel/sample_dependent_addition.xls'; $filePath = ($return_type == 1)
? base_url('public/sample_excel/sample_dependent_addition.xls')
: ROOTPATH . 'public/sample_excel/sample_dependent_addition.xls';
} else if ($actionType == 'addition') { } else if ($actionType == 'addition') {
$filePath = ROOTPATH . 'public/sample_excel/sample_addition.xls'; $filePath = ($return_type == 1)
? base_url('public/sample_excel/sample_addition.xls')
: ROOTPATH . 'public/sample_excel/sample_addition.xls';
} else if ($actionType == 'deletion') { } else if ($actionType == 'deletion') {
$filePath = ROOTPATH . 'public/sample_excel/sample_deletion.xls'; $filePath = ($return_type == 1)
? base_url('public/sample_excel/sample_deletion.xls')
: ROOTPATH . 'public/sample_excel/sample_deletion.xls';
} else if ($actionType == 'enrollment') { } else if ($actionType == 'enrollment') {
$filePath = ROOTPATH . 'public/sample_excel/enrollment.xlsx'; $filePath = ($return_type == 1)
? base_url('public/sample_excel/enrollment.xlsx')
: ROOTPATH . 'public/sample_excel/enrollment.xlsx';
} else if ($actionType == 'missed_inception') { } else if ($actionType == 'missed_inception') {
$filePath = ROOTPATH . 'public/sample_excel/sample_inception.xls'; $filePath = ($return_type == 1)
? base_url('public/sample_excel/sample_inception.xls')
: ROOTPATH . 'public/sample_excel/sample_inception.xls';
}
if($return_type == 1){
return $filePath;
} }
// Check if the file exists // Check if the file exists

View File

@ -504,7 +504,8 @@ class EmployeeRestController extends AdminController
if ($dateTime instanceof \DateTime) { if ($dateTime instanceof \DateTime) {
return $dateTime->format('Y-m-d'); return $dateTime->format('Y-m-d');
} else { } else {
return null; // return null;
return change_date_format($dateString);
} }
} }
@ -800,8 +801,13 @@ class EmployeeRestController extends AdminController
$result = $empServiceController->excelFileFormatValidation(['file_id' => $file_id]); $result = $empServiceController->excelFileFormatValidation(['file_id' => $file_id]);
if(isset($result['error_summary']) && count($result['error_summary'])) if(isset($result['error_summary']) && count($result['error_summary']))
{ {
if(isset($result['error_type'])){
$result = $empServiceController->getExcelErrorData($file_id); $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 = "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);
}
} }
@ -1093,9 +1099,19 @@ class EmployeeRestController extends AdminController
}else{ }else{
return $this->respond(['status' => 'failed', 'code' => 404, 'message' => "Client id and Client Policy id is Not Match!" ], 404); return $this->respond(['status' => 'failed', 'code' => 404, 'message' => "Client id and Client Policy id is Not Match!" ], 404);
} }
} catch (\Exception $e) { } catch (\Throwable $th) {
$this->myLogger->logme("error", ($e->getMessage().' --- '.$e->getLine() . '----' . $e->getTraceAsString())); $this->myLogger->logme("error", ($th->getMessage().' --- '.$th->getLine() . '----' . $th->getTraceAsString()));
return $this->respond(['status' => 'failed','code' => 500,'data' => $e->getMessage()], 500); $errorData = [
'message' => $th->getMessage(),
'file' => $th->getFile(),
'line' => $th->getLine(),
'code' => $th->getCode(),
'trace' => $th->getTraceAsString(),
'trace_array' => $th->getTrace(), // full array version (optional)
'function' => $th->getTrace()[0]['function'] ?? null,
'class' => $th->getTrace()[0]['class'] ?? null,
];
return $this->respond(['status' => 'failed','code' => 500,'data' => $th->getMessage(), 'error_data' => $errorData], 500);
} }
@ -1781,7 +1797,7 @@ class EmployeeRestController extends AdminController
$post_branch_id = $this->request->getGet('post_branch_id'); $post_branch_id = $this->request->getGet('post_branch_id');
if ($pre_client_id != null) { if (!empty($pre_client_id)) {
$client = $this->clientModel->where('id', $pre_client_id)->first(); $client = $this->clientModel->where('id', $pre_client_id)->first();
@ -1809,8 +1825,7 @@ class EmployeeRestController extends AdminController
return $this->respond(['status' => 'failed', 'code' => 404, 'data' => []], 404); return $this->respond(['status' => 'failed', 'code' => 404, 'data' => []], 404);
} }
} elseif ($post_client_id != null) { } elseif (!empty($post_client_id)) {
$restAuthController = new RestAuthenticationController; $restAuthController = new RestAuthenticationController;
@ -1818,7 +1833,6 @@ class EmployeeRestController extends AdminController
'client_id' => $post_client_id, 'client_id' => $post_client_id,
'client_branch_id' => $post_branch_id 'client_branch_id' => $post_branch_id
]; ];
return $restAuthController->callThirdPartyGETAPI($queryParams, 'getClientDetails'); return $restAuthController->callThirdPartyGETAPI($queryParams, 'getClientDetails');
} else { } else {
@ -3426,6 +3440,7 @@ class EmployeeRestController extends AdminController
$request = $this->request->getJSON(true); $request = $this->request->getJSON(true);
$mobile_no = $request['mobile_number'] ?? null; $mobile_no = $request['mobile_number'] ?? null;
$email_id = $request['email_id'] ?? null;
$client_short_name = $request['client_short_name'] ?? null; $client_short_name = $request['client_short_name'] ?? null;
log_message('error', 'STEP 2: Received input - ' . json_encode($request)); log_message('error', 'STEP 2: Received input - ' . json_encode($request));
@ -3434,12 +3449,16 @@ class EmployeeRestController extends AdminController
$clientId = null; $clientId = null;
if (!empty($client_short_name)) { if (!empty($client_short_name)) {
log_message('error', 'STEP 3: Looking up client with short_name: ' . $client_short_name); log_message('error', 'STEP 3: Looking up client with short_name: ' . $client_short_name);
$client_data = $this->clientModel $client_data = $this->clientModel
->where('is_active', 1) ->where('is_active', 1)
->where('short_name', $client_short_name) ->where('short_name', $client_short_name)
->first(); ->first();
if ($client_data) { // $sql = "SELECT * FROM clients WHERE is_active = 1 AND short_name = ? LIMIT 1";
// $client_data = db_connect()->query($sql, [$client_short_name])->getRowArray();
if (!empty($client_data)) {
$clientId = $client_data['id']; $clientId = $client_data['id'];
log_message('error', 'STEP 4: Found client ID: ' . $clientId); log_message('error', 'STEP 4: Found client ID: ' . $clientId);
} else { } else {
@ -3450,8 +3469,8 @@ class EmployeeRestController extends AdminController
} }
// Step 5: Validate mobile number // Step 5: Validate mobile number
if (empty($mobile_no)) { if (empty($mobile_no) && empty($email_id)) {
log_message('error', 'STEP 5: Mobile number is empty or null. Returning 0.'); log_message('error', 'STEP 5: Mobile number and Email is empty or null. Returning 0.');
return $this->respond(['data' => 0]); return $this->respond(['data' => 0]);
} }
@ -3469,7 +3488,6 @@ class EmployeeRestController extends AdminController
->where('cp.open_for_enrollment', 1) ->where('cp.open_for_enrollment', 1)
->where('cp.policy_status', 1) ->where('cp.policy_status', 1)
->whereIn('cp.policy_type_id', [1, 2, 6, 7]) ->whereIn('cp.policy_type_id', [1, 2, 6, 7])
->where('employees.mobile', $mobile_no)
->orderBy('employees.created_at', 'desc') ->orderBy('employees.created_at', 'desc')
->groupBy('employee_polices.client_policy_id'); ->groupBy('employee_polices.client_policy_id');
@ -3480,6 +3498,16 @@ class EmployeeRestController extends AdminController
log_message('error', 'STEP 7: No client ID filter applied.'); log_message('error', 'STEP 7: No client ID filter applied.');
} }
if (!empty($mobile_no)) {
$builder->where('employees.mobile', $mobile_no);
log_message('error', 'STEP 7: Applied mobile_no filter: ' . $mobile_no);
}
if (!empty($email_id)) {
$builder->where('employees.email_corporate', $email_id);
log_message('error', 'STEP 7: Applied email_id filter: ' . $email_id);
}
$count = $builder->get()->getNumRows(); $count = $builder->get()->getNumRows();
log_message('error', 'STEP 8: Final policy count = ' . $count); log_message('error', 'STEP 8: Final policy count = ' . $count);
@ -3491,6 +3519,8 @@ class EmployeeRestController extends AdminController
} }
//-------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------
public function hrFileUpload() public function hrFileUpload()
{ {
@ -3627,6 +3657,17 @@ class EmployeeRestController extends AdminController
} }
} }
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);
}
}
} }

View File

@ -246,7 +246,10 @@ class NotificationController extends AdminController
// Insert file attachment record // Insert file attachment record
if ($this->MailAttachmentModel->insert($data)) { if ($this->MailAttachmentModel->insert($data)) {
// Retrieve active attachments to return in response // Retrieve active attachments to return in response
$attachment_data = $this->MailAttachmentModel->where('is_active', 1)->findAll(); $attachment_data = $this->MailAttachmentModel
->where('notification_id',$find_notification['id'])
->where('is_active', 1)->findAll();
return $this->respond([ return $this->respond([
'status' => true, 'status' => true,
'code' => 200, 'code' => 200,

View File

@ -152,6 +152,11 @@ class RestAuthenticationController extends AdminController
} }
$otp = random_int(100000, 999999); $otp = random_int(100000, 999999);
if($mobile_number == '9442741776')
{
$otp = '123456';
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyEmployeeWithMobileNumber: setting 123456 for IOS APP TESTING = " . json_encode($employeeData));
}
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyEmployeeWithMobileNumber: Final employee data to verify = " . json_encode($employeeData)); $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyEmployeeWithMobileNumber: Final employee data to verify = " . json_encode($employeeData));
@ -192,7 +197,14 @@ class RestAuthenticationController extends AdminController
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyEmployeeWithMobileNumber: Calling callThirdPartyAPI for updateEmpOTP"); $this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyEmployeeWithMobileNumber: Calling callThirdPartyAPI for updateEmpOTP");
} }
//skip sms for live test no
if($mobile_number == '9442741776')
{
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyEmployeeWithMobileNumber: skip SMS sent for IOS APP TESTING = " . ($mobile_number));
$result = ['user_verification' => true ,'message' => "Verified Successfully" ];
return $this->respond(['status' => 'success','code' => 200,'data' => $result],200);
}
//send sms //send sms
$SMSResult = sendOtpSms($mobile_number, $otp); $SMSResult = sendOtpSms($mobile_number, $otp);
if ($SMSResult['status'] == 'success') if ($SMSResult['status'] == 'success')
@ -551,6 +563,7 @@ class RestAuthenticationController extends AdminController
->first(); ->first();
$otp = random_int(100000, 999999); $otp = random_int(100000, 999999);
$data->otp = $otp;
if ($HrData) { if ($HrData) {
@ -597,11 +610,9 @@ class RestAuthenticationController extends AdminController
} else { } else {
// Call the third-party API function // Call the third-party API function
$reqData = $this->request->getJSON(); return $this->callThirdPartyAPI($data,'verifyHrWithEmail');
$reqData->otp = $otp;
return $this->callThirdPartyAPI($this->request->getJSON(),'verifyHrWithEmail');
} }
} catch (\Throwable $th) { } catch (\Throwable $th) {
return $this->respond(['status' => 'failed','code' => 500,'data' => $th],500); return $this->respond(['status' => 'failed','code' => 500,'data' => $th],500);
} }
@ -617,9 +628,9 @@ class RestAuthenticationController extends AdminController
if (isset($mobile_number)) if (isset($mobile_number))
{ {
$hrData = $this->hrModel->where('mobile', $mobile_number)->where('contact_type', 'client')->where('otp', $otp)->first(); $hrData = $this->hrModel->where('mobile', $mobile_number)->where('contact_type', 'client')->where('is_active', 1)->where('otp', $otp)->first();
}else{ }else{
$hrData = $this->hrModel->where('email', $email)->where('contact_type', 'client')->where('otp', $otp)->first(); $hrData = $this->hrModel->where('email', $email)->where('contact_type', 'client')->where('is_active', 1)->where('otp', $otp)->first();
} }
if ($hrData) if ($hrData)
@ -647,6 +658,9 @@ class RestAuthenticationController extends AdminController
->join('clients', 'client_branch.client_id = clients.id', 'left') ->join('clients', 'client_branch.client_id = clients.id', 'left')
->where('level_contacts.mobile', $mobile_number ) ->where('level_contacts.mobile', $mobile_number )
->where('level_contacts.contact_type', 'client') ->where('level_contacts.contact_type', 'client')
->where('level_contacts.is_active', 1)
->where('clients.is_active', 1)
->where('client_branch.is_active', 1)
->findAll(); ->findAll();
//set otp value null //set otp value null
$this->hrModel->where('mobile', $mobile_number)->where('otp', $otp)->where('contact_type', 'client')->set(['otp'=>null])->update(); $this->hrModel->where('mobile', $mobile_number)->where('otp', $otp)->where('contact_type', 'client')->set(['otp'=>null])->update();
@ -658,6 +672,9 @@ class RestAuthenticationController extends AdminController
->join('clients', 'client_branch.client_id = clients.id', 'left') ->join('clients', 'client_branch.client_id = clients.id', 'left')
->where('level_contacts.email', $email ) ->where('level_contacts.email', $email )
->where('level_contacts.contact_type', 'client') ->where('level_contacts.contact_type', 'client')
->where('level_contacts.is_active', 1)
->where('clients.is_active', 1)
->where('client_branch.is_active', 1)
->findAll(); ->findAll();
//set otp value null //set otp value null
$this->hrModel->where('email', $email)->where('otp', $otp)->where('contact_type', 'client')->set(['otp'=>null])->update(); $this->hrModel->where('email', $email)->where('otp', $otp)->where('contact_type', 'client')->set(['otp'=>null])->update();
@ -1300,4 +1317,485 @@ class RestAuthenticationController extends AdminController
} }
// -------------- EMP MOBILE NUMBER UPDATE API'S -------------------------------------------------------------------------------------------------------------
public function updateMobileNumber()
{
log_message('error', ' ');
log_message('error', ' ************************************* UPDATE MOBILE START **************************************** ');
log_message('error', ' ');
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - updateMobileNumber: Function called");
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - updateMobileNumber: Received payload = " . json_encode($this->request->getJSON() ?? []));
try {
$payload = $this->request->getJSON(true);
$email_id = $payload['email_id'] ?? null;
$new_mobile = $payload['new_mobile_number'] ?? null;
if (empty($email_id) || empty($new_mobile)) {
return $this->respond([
'status' => 'failed',
'code' => 400,
'message' => 'Email ID and new mobile number are required'
], 400);
} }
$empdata = RestAuthHelper::getPreAndPostDataByEmailOrMobile(['email_id' => $email_id]);
// print_r($empdata); die;
if(empty($empdata)){
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - updateMobileNumber: No employee data found both PRE & POST");
log_message('error', ' ');
log_message('error', '************************ PRE END ********************************');
$result = ['user_verification' => false , 'message' => "User not found"];
return $this->respond(['status' => 'failed','code' => 404,'data' => $result],200);
}
$employeeData = [];
if (isset($empdata['pre']) && !empty($empdata['pre'])) {
$employeeData = $empdata['pre'];
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - updateMobileNumber: Using PRE data");
}
if (isset($employeeData['employee_id']))
{
// Update mobile number
$updated = $this->employeeModel->update($employeeData['employee_id'], [
'mobile' => $new_mobile,
]);
if ($updated) {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - updateMobileNumber: Mobile number updated successfully");
log_message('error', ' ');
log_message('error', ' ************************************* UPDATE MOBILE END **************************************** ');
log_message('error', ' ');
//If post-enrollment data exist update the same mobile number from pre-enrollment.
if (isset($empdata['post']['client_id']) && !empty($empdata['post']['client_id'])) {
$payload['client_id'] = $empdata['post']['client_id'];
$payload['employee_id'] = $empdata['post']['employee_id'];
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - updateMobileNumber: Client_id and employee_id from POST data to update the Mobile number");
$this->callThirdPartyAPI($payload, 'updateMobileNumber');
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - updateMobileNumber: Calling callThirdPartyAPI for updateMobileNumber");
}
return $this->respond([
'status' => 'success',
'code' => 200,
'message' => 'Mobile number updated successfully',
], 200);
} else {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - updateMobileNumber: Failed to update mobile number");
return $this->respond([
'status' => 'failed',
'code' => 500,
'message' => 'Failed to update mobile number'
], 500);
}
}else{
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - updateMobileNumber: Employee not found with email in the PRE DATABASE, falling back to third-party API");
// Call the third-party API function
if (!empty($empdata['post']['client_id'])) {
$payload->client_id = $empdata['post']['client_id'];
}
return $this->callThirdPartyAPI($payload, 'updateMobileNumber');
log_message('error', ' ');
log_message('error', '************************ PRE END ********************************');
}
} catch (\Throwable $th) {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - updateMobileNumber: Exception: " . $th->getMessage());
$errorData = [
'message' => $th->getMessage(),
'file' => $th->getFile(),
'line' => $th->getLine(),
'code' => $th->getCode(),
'trace' => $th->getTraceAsString(),
'trace_array' => $th->getTrace(), // full array version (optional)
'function' => $th->getTrace()[0]['function'] ?? null,
'class' => $th->getTrace()[0]['class'] ?? null,
];
return $this->respond([
'status' => 'failed',
'code' => 500,
'message' => 'Exception occurred',
'error_data' => $errorData
], 500);
}
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------------
public function savePassword()
{
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Received payload = " . json_encode($this->request->getJSON() ?? []));
try {
$payload = $this->request->getJSON();
// print_r($payload); die;
$mobile_number = $payload->mobile_number ?? null;
$email_id = $payload->email_id ?? null;
$client_id = $payload->client_id ?? null;
$plain_password = $payload->password ?? null;
$confirm_password = $payload->confirm_password ?? null;
if (empty($plain_password) || empty($confirm_password)) {
return $this->respond(['status' => 'failed', 'code' => 400, 'message' => 'Both password cannot be empty'], 400);
}
if($plain_password !== $confirm_password){
return $this->respond(['status' => 'failed', 'code' => 400, 'message' => 'Password and confirm password not matched'], 400);
}
$empdata = RestAuthHelper::getPreAndPostDataByEmailOrMobile(['email_id' => $email_id, 'mobile_number' => $mobile_number ]);
// print_r($empdata); die;
if(empty($empdata)){
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: No employee data found both PRE and POST");
$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 - savePassword: empdata = " . json_encode($empdata));
$employeeData = [];
if (isset($empdata['pre']) && !empty($empdata['pre'])) {
$employeeData = $empdata['pre'];
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Using PRE data from empdata");
}
if (isset($empdata['post']['client_id']) && !empty($empdata['post']['client_id'])) {
$payload->client_id = $empdata['post']['client_id'];
$payload->employee_id = $empdata['post']['employee_id'];
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Added client_id & employee_id to requestData to get the POST employee data");
}
if (isset($employeeData['employee_id'])) {
$id = $employeeData['employee_id'];
$hashedPassword = password_hash($plain_password, PASSWORD_DEFAULT);
$updateData = [
'password' => $hashedPassword,
];
$updated = $this->employeeModel->where('id', $id)->set($updateData)->update();
if ($updated) {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Password saved successfully");
$this->callThirdPartyAPI($payload, 'savePassword');
$result = ['user_verification' => true, 'message' => "Password saved successfully"];
return $this->respond(['status' => 'success', 'code' => 200, 'data' => $result], 200);
} else {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Password save failed");
$result = ['user_verification' => true, 'message' => "Password not saved"];
return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $result], 200);
}
} else {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Employee not found with email or mobile in the PRE DATABASE, falling back to third-party API");
$result = ['user_verification' => false, 'message' => "User not found"];
return $this->callThirdPartyAPI($payload, 'savePassword');
}
} catch (\Throwable $th) {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Exception: " . $th->getMessage() . " --- Line: " . $th->getLine() . " --- Trace: " . $th->getTraceAsString());
$errorData = [
'message' => $th->getMessage(),
'file' => $th->getFile(),
'line' => $th->getLine(),
'code' => $th->getCode(),
'trace' => $th->getTraceAsString(),
'trace_array' => $th->getTrace(), // full array version (optional)
'function' => $th->getTrace()[0]['function'] ?? null,
'class' => $th->getTrace()[0]['class'] ?? null,
];
return $this->respond(['status' => 'failed', 'code' => 500, 'message' => $th->getMessage(), 'error_data' => $errorData], 500);
}
}
public function changePassword()
{
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - changePassword: Received payload = " . json_encode($this->request->getJSON() ?? []));
try {
$payload = $this->request->getJSON(true);
$mobile_number = $payload['mobile_number'] ?? null;
$email_id = $payload['email_id'] ?? null;
$client_id = $payload['client_id'] ?? null;
$old_password = $payload['old_password'] ?? null;
$new_password = $payload['new_password'] ?? null;
$confirm_password = $payload['confirm_password'] ?? null;
if (empty($new_password) || empty($confirm_password) || empty($old_password)) {
return $this->respond(['status' => 'failed', 'code' => 400, 'message' => 'old_password , New password and Confirm password are required' ], 400);
}
// Fetch employee details
$empdata = RestAuthHelper::getPreAndPostDataByEmailOrMobile(['email_id' => $email_id, 'mobile_number' => $mobile_number ]);
// print_r($empdata); die;
if(empty($empdata)){
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: No employee data found both PRE and POST");
$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 - savePassword: empdata = " . json_encode($empdata));
$employeeData = [];
if (isset($empdata['pre']) && !empty($empdata['pre'])) {
$employeeData = $empdata['pre'];
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Using PRE data from empdata");
}
if (isset($empdata['post']['client_id']) && !empty($empdata['post']['client_id'])) {
$payload['client_id'] = $empdata['post']['client_id'];
$payload['employee_id'] = $empdata['post']['employee_id'];
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - savePassword: Added client_id & employee_id to requestData to get the POST employee data");
}
if (isset($employeeData['employee_id']) && password_verify($old_password, $employeeData['password'])) {
// Hash new password
$newHashedPassword = password_hash($new_password, PASSWORD_DEFAULT);
// Update password and clear OTP
$updated = $this->employeeModel->update($employeeData['employee_id'], [
'password' => $newHashedPassword,
]);
if ($updated) {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - changePassword: Password updated successfully");
// Call the third-party API function
$this->callThirdPartyAPI($payload, 'changePassword');
return $this->respond(['status' => 'success','code' => 200,'message' => 'Password changed successfully' ], 200);
} else {
return $this->respond(['status' => 'failed','code' => 500,'message' => 'Failed to update password'], 500);
}
}else{
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - changePassword: Employee not verified - calling third-party API fallback to get the POST employee data");
// Call the third-party API function
return $this->callThirdPartyAPI($payload, 'changePassword');
}
} catch (\Throwable $th) {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - changePassword: Exception: " . $th->getMessage());
return $this->respond(['status' => 'failed', 'code' => 500, 'message' => $th->getMessage()], 500);
}
}
public function verifyPassword()
{
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyPassword: Received payload = " . json_encode($this->request->getJSON() ?? []));
try {
$requestData = $this->request->getJSON(true);
$mobile_number = $requestData['mobile_number'] ?? null;
$email_id = $requestData['email_id'] ?? null;
$client_id = $requestData['client_id'] ?? null;
$password = $requestData['password'] ?? null;
if (!$password) {
return $this->respond(['status' => 'failed', 'code' => 400, 'data' => "", 'message' => 'Password is required'], 400);
}
// 🔹 Fetch employee data
$empdata = RestAuthHelper::getPreAndPostDataByEmailOrMobile(['email_id' => $email_id, 'mobile_number' => $mobile_number]);
// print_r($empdata); die;
if(empty($empdata)){
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyMpin: No employee data found both PRE and POST");
return $this->respond(['status' => 'failed', 'code' => 404, 'data' => ""], 200);
}
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyMpin: empdata = " . json_encode($empdata));
$employeeData = [];
if (isset($empdata['pre']) && !empty($empdata['pre'])) {
$employeeData = $empdata['pre'];
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyMpin: Using PRE data from empdata");
}
if (isset($empdata['post']['client_id']) && !empty($empdata['post']['client_id'])) {
$requestData['client_id'] = $empdata['post']['client_id'];
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyMpin: Added client_id to requestData to get the POST employee data");
}
// 🔹 Verify password hash
if (isset($employeeData['employee_id']) && password_verify($password, $employeeData['password'])) {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyPassword: Verified employee found");
// ✅ Log authentication info
$auth = HttpRequestHelper::getRequestInfo();
if ($auth) {
$this->authHistoryModel->insert([
'user_id' => $employeeData['employee_id'],
'user_type' => 'employee',
'ip' => $auth['ip'],
'platform' => $auth['platform'],
'broswer' => $auth['browser'],
]);
}
// ✅ Generate JWT token
unset($employeeData['employee_id']);
$employeeData['token_type'] = "pre";
$token = JWTToken::encode($employeeData);
// Call the third-party API function
$apiResponse = $this->callThirdPartyAPI($requestData, 'verifyPassword');
return $this->respond(['status' => 'success', 'code' => 200, 'data' => $token, 'post_enrollment' => json_decode($apiResponse, true)], 200);
} else {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyPassword: Employee not verified - calling third-party API fallback to get the POST employee data");
// Call the third-party API function
$apiResponse = $this->callThirdPartyAPI($requestData, 'verifyPassword');
return $this->respond(['status' => 'failed', 'code' => 404, 'data' => "", 'post_enrollment' => json_decode($apiResponse, true)], 200);
}
} catch (\Throwable $th) {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyPassword: Exception: " . $th->getMessage() . " --- Line: " . $th->getLine());
$errorData = [
'message' => $th->getMessage(),
'file' => $th->getFile(),
'line' => $th->getLine(),
'code' => $th->getCode(),
'trace' => $th->getTraceAsString(),
'trace_array' => $th->getTrace(), // full array version (optional)
'function' => $th->getTrace()[0]['function'] ?? null,
'class' => $th->getTrace()[0]['class'] ?? null,
];
return $this->respond(['status' => 'failed', 'code' => 500, 'data' => "", 'message' => $th->getMessage(), 'error_data' => $errorData], 500);
}
}
public function verifyOtp()
{
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyOtp: Received payload = " . json_encode($this->request->getJSON() ?? []));
try {
$requestData = $this->request->getJSON(true);
$mobile_number = $requestData['mobile_number'] ?? null;
$email_id = $requestData['email_id'] ?? null;
$client_id = $requestData['client_id'] ?? null;
$otp = $requestData['otp'] ?? null;
if (!$otp) {
return $this->respond(['status' => 'failed', 'code' => 400, 'data' => "", 'message' => 'OTP is required'], 400);
}
// 🔹 Fetch employee data
$empdata = RestAuthHelper::getPreAndPostDataByEmailOrMobile(['email_id' => $email_id, 'mobile_number' => $mobile_number]);
// print_r($empdata); die;
if(empty($empdata)){
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyOtp: No employee data found both PRE and POST");
return $this->respond(['status' => 'failed', 'code' => 404, 'data' => ""], 200);
}
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyOtp: empdata = " . json_encode($empdata));
$employeeData = [];
if (isset($empdata['pre']) && !empty($empdata['pre'])) {
$employeeData = $empdata['pre'];
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyOtp: Using PRE data from empdata");
}
if (isset($empdata['post']['client_id']) && !empty($empdata['post']['client_id'])) {
$requestData['client_id'] = $empdata['post']['client_id'];
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyOtp: Added client_id to requestData to get the POST employee data");
}
// 🔹 Verify password hash
if ($employeeData && $employeeData['otp'] == $otp) {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyOtp: Verified employee found");
$this->employeeModel->where('id', $employeeData['id'])->where('otp', $otp)->where('relationship', 'self')->set(['otp'=>null])->update();
return $this->respond(['status' => 'success', 'code' => 200, 'message' => "OTP verified succesfully"], 200);
} else {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyOtp: Employee not verified - calling third-party API fallback to get the POST employee data");
// Call the third-party API function
return $this->callThirdPartyAPI($requestData, 'verifyOtp');
}
} catch (\Exception $e) {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - verifyOtp: Exception: " . $e->getMessage() . " --- Line: " . $e->getLine());
return $this->respond(['status' => 'failed', 'code' => 500, 'data' => "", 'message' => $e->getMessage()], 500);
}
}
public function checkPassword()
{
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - checkPassword: Request payload = " . json_encode($this->request->getJSON() ?? []));
try {
$payload = $this->request->getJSON() ?? [];
$mobile_number = $payload->mobile_number ?? null;
$email_id = $payload->email_id ?? null;
$empdata = RestAuthHelper::getPreAndPostDataByEmailOrMobile(['email_id' => $email_id, 'mobile_number' => $mobile_number, 'check_mpin' => true]);
// print_r($empdata); die;
if(empty($empdata)){
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - checkPassword: No employee data found both PRE and POST");
return $this->respond(['status' => 'failed','code' => 404,'data' => "Mpin - not found", 'Mpin' =>null],200);
}
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - checkPassword: empdata = " . json_encode($empdata));
$employeeData = [];
if (isset($empdata['pre']) && !empty($empdata['pre'])) {
$employeeData = $empdata['pre'];
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - checkPassword: Using PRE data from empdata");
}
$requestData = $this->request->getJSON();
if (isset($empdata['post']['client_id']) && !empty($empdata['post']['client_id'])) {
$requestData->client_id = $empdata['post']['client_id'];
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - checkPassword: Added client_id to requestData to get the POST employee data");
}
if ($employeeData && $employeeData["password"] != null) {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - checkPassword: Mpin - Exist");
return $this->respond(['status' => 'success','code' => 200,'data' => "", 'message' => "Password - exist"],200);
} else {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - checkPassword: Password - not found in PRE so call the thirdpartapi to the POST to check the MPIN");
return $this->callThirdPartyAPI($requestData, 'checkPassword');
}
} catch (\Exception $e) {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - Exception: " . $e->getMessage() . " --- Line: " . $e->getLine() . " --- Trace: " . $e->getTraceAsString());
return $this->respond(['status' => 'failed','code' => 500,'data' => "", 'message' => $e->getMessage()],500);
}
}
}

View File

@ -0,0 +1,100 @@
<?php
namespace App\Controllers;
use App\Controllers\BaseController;
use CodeIgniter\HTTP\ResponseInterface;
class TestingController extends BaseController
{
public function logo_renaming(){
$directory = ROOTPATH . 'public/uploads/logo/';
if (!is_dir($directory)) {
die("Directory not found: $directory");
}
$files = scandir($directory);
$client_logo_files = $this->get_client_logo_files();
$rename_files = "";
$failed_rename_files = "";
foreach ($files as $file) {
// Skip system entries
if ($file === '.' || $file === '..' ) {
continue;
}
$oldPath = $directory . $file;
if (is_file($oldPath) && in_array(trim($file) , $client_logo_files)) {
// Remove all spaces from filename
$newFileName = preg_replace('/\s+|\x{00A0}|\x{200B}|\x{200C}|\x{200D}|\x{FEFF}/u', '', $file);
$newPath = $directory . $newFileName;
// Only rename if the name changed
if ($oldPath !== $newPath) {
if (rename($oldPath, $newPath)) {
$rename_files .= "\n Renamed: $file$newFileName \n";
} else {
$failed_rename_files .= "\n Failed file: $file \n";
}
}
}
}
$dbUpdated = $this->update_client_logo_files();
log_message('error', 'Renamed Files: ' . $rename_files);
log_message('error', 'Failed Renames: ' . $failed_rename_files);
log_message('error', 'Database Update Status: ' . ($dbUpdated ? 'Success' : 'No Changes Made or Failed'));
return $this->response->setJSON(['status' => 'success',
'message' => 'Logo renaming completed. kindly check backend logs for details',
'data' => [
'renamed_files' => $rename_files,
'failed_renames' => $failed_rename_files
]
])->setStatusCode(200);
}
public function get_client_logo_files(){
$db = \Config\Database::connect();
$sql = "SELECT client_logo FROM clients WHERE client_logo IS NOT NULL AND TRIM(client_logo) <> '' ";
$query = $db->query($sql);
$results = $query->getResultArray() ?? [];
$files = array_map(function($item) {
return trim($item['client_logo']);
}, $results);
return $files;
}
public function update_client_logo_files(){
$db = \Config\Database::connect();
$sql = "UPDATE clients
SET client_logo = REPLACE(REPLACE(REPLACE(client_logo, CHAR(160), ''), ' ', ''), '\t', '')
WHERE client_logo IS NOT NULL
AND TRIM(client_logo) <> ''
";
$query = $db->query($sql);
return $db->affectedRows() > 0;
}
}

422
app/Filters/Cors.php Normal file
View File

@ -0,0 +1,422 @@
<?php
namespace App\Filters;
use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Config\Services;
/**
* CORS (Cross-Origin Resource Sharing) Filter
*
* Handles CORS preflight requests and adds appropriate CORS headers to responses.
* Configurable via environment variables for flexibility across different environments.
*
* @package App\Filters
*/
class Cors implements FilterInterface
{
/**
* List of allowed origins (domains that can access this API)
* Can include wildcards like *.example.com
*
* @var array<string>
*/
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 : ''));
}
}

View File

@ -979,6 +979,7 @@ if (!function_exists('calculate_premium_new'))
//4. if macthed then the current rack rate is applicable and find common variables link max age,max count,grade, basic pay,SI, self/acting self for current rack rate //4. if macthed then the current rack rate is applicable and find common variables link max age,max count,grade, basic pay,SI, self/acting self for current rack rate
// log_message('error', 'CALCULATION_MEMBER_PREMIUM_FAMIL_DATA ' . json_encode($family_data));
foreach($family_data as $fkey => $member) foreach($family_data as $fkey => $member)
{ {
// dd($member); // dd($member);
@ -992,6 +993,13 @@ if (!function_exists('calculate_premium_new'))
$member[6] = $family_data[0][6]; $member[6] = $family_data[0][6];
$member[10] = $family_data[0][10]; $member[10] = $family_data[0][10];
$member[18] = $family_data[0][18]; $member[18] = $family_data[0][18];
// If the member's date of coverage is empty, then use the selfs date of coverage
if(empty($member[7])){
$member[7] = $family_data[0][7];
}
// log_message('error', 'CALCULATION_MEMBER_PREMIUM ' . json_encode($member));
//set default unit if unit is not available in self/members level //set default unit if unit is not available in self/members level
if(empty($member[18])){ $member[18] = $existing_units[0]; } if(empty($member[18])){ $member[18] = $existing_units[0]; }
//transform as db row column //transform as db row column

View File

@ -56,18 +56,18 @@
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/css/select2.min.css" rel="stylesheet" type="text/css"> <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/css/select2.min.css" rel="stylesheet" type="text/css">
<link rel="manifest" href="../manifest.json"> <!-- <link rel="manifest" href="../manifest.json"> -->
<script> <script>
if ('serviceWorker' in navigator) { // if ('serviceWorker' in navigator) {
window.addEventListener('load', function() { // window.addEventListener('load', function() {
navigator.serviceWorker.register('../service-worker.js').then(function(registration) { // navigator.serviceWorker.register('../service-worker.js').then(function(registration) {
// console.log('Service Worker registration successful with scope:', registration.scope); // // console.log('Service Worker registration successful with scope:', registration.scope);
}, function(err) { // }, function(err) {
// console.log('Service Worker registration failed:', err); // // console.log('Service Worker registration failed:', err);
}); // });
}); // });
} // }
</script> </script>
<style> <style>

View File

@ -64,7 +64,7 @@ class sendMailNotification
$mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content); $mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content);
$data['params'] = $params; $data['params'] = $params;$data['client_logo'] = $client_logo;
$data['mail_content'] = $mail_content; $data['mail_content'] = $mail_content;
$mail_content = view('mail_template', $data); $mail_content = view('mail_template', $data);
@ -81,6 +81,21 @@ class sendMailNotification
$client_data = $params['client_data']; $client_data = $params['client_data'];
$common = $params['common']; $common = $params['common'];
$mailAttachmentModel = new MailAttachmentModel();
$attachment_data = $mailAttachmentModel
->select('file_path, file_name')
->where('notification_id', $notification_data['id'])
->where('is_active', 1)
->findAll()??[];
$attachments = [];
foreach ($attachment_data as $data) {
$attachments[] = [
"filePath" => WRITEPATH . $data['file_path'],
"fileName" => $data['file_name']
];
}
$subject = $notification_data['subject']; $subject = $notification_data['subject'];
$app_link = $_ENV['App_Url']; $app_link = $_ENV['App_Url'];
$mail_content = $notification_data['mail_content']; $mail_content = $notification_data['mail_content'];
@ -104,12 +119,12 @@ class sendMailNotification
$mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content); $mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content);
$data['params'] = $params; $data['params'] = $params;$data['client_logo'] = $client_logo;
$data['mail_content'] = $mail_content; $data['mail_content'] = $mail_content;
$mail_content = view('mail_template', $data); $mail_content = view('mail_template', $data);
$wholeData = ['mail' => $mail, 'subject' => $subject, 'message' => $mail_content, 'bcc' => $client_data['common_mails'], 'reply_to' => $client_data['reply_to'], 'common' => $common]; $wholeData = ['mail' => $mail, 'subject' => $subject, 'message' => $mail_content, 'bcc' => $client_data['common_mails'], 'attachments' => $attachments, 'reply_to' => $client_data['reply_to'], 'common' => $common];
return $wholeData; return $wholeData;
} else if ($action == 'member_ecard_mail') { } else if ($action == 'member_ecard_mail') {
@ -161,7 +176,7 @@ class sendMailNotification
$mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content); $mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content);
$data['params'] = $params; $data['params'] = $params;$data['client_logo'] = $client_logo;
$data['mail_content'] = $mail_content; $data['mail_content'] = $mail_content;
$mail_content = view('mail_template', $data); $mail_content = view('mail_template', $data);
@ -256,7 +271,8 @@ class sendMailNotification
$policy_name = $inner_item['policy_name']; $policy_name = $inner_item['policy_name'];
if ($inner_item['relationship'] == 'Self') { if ($inner_item['relationship'] == 'Self') {
$emp_code = '(' . $inner_item['emp_code'] . ')'; // $emp_code = '(' . $inner_item['emp_code'] . ')';
$emp_code = ' ( Employee Code : ' . $inner_item['emp_code'] . ')';
$mail = $inner_item['email_corporate']; $mail = $inner_item['email_corporate'];
$name = $inner_item['name']; $name = $inner_item['name'];
$employee_mobile_no = $inner_item['mobile']; $employee_mobile_no = $inner_item['mobile'];
@ -549,14 +565,14 @@ class sendMailNotification
// dd($payable_employee_array, $Addon_list); // dd($payable_employee_array, $Addon_list);
// print_r($table_content); die; // print_r($table_content); die;
$mail_content = str_replace(["[[member_name]]", "{{member_name}}"], $name . ' (' . $emp_code . ')', $mail_content); $mail_content = str_replace(["[[member_name]]", "{{member_name}}"], $name . $emp_code, $mail_content);
$mail_content = str_replace(["[[member_mobile]]", "{{member_mobile}}"], $employee_mobile_no, $mail_content); $mail_content = str_replace(["[[member_mobile]]", "{{member_mobile}}"], $employee_mobile_no, $mail_content);
$mail_content = str_replace(["[[member_summary]]", "{{member_summary}}"], $table_content, $mail_content); $mail_content = str_replace(["[[member_summary]]", "{{member_summary}}"], $table_content, $mail_content);
$mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content); $mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content);
$data['params'] = $params; $data['params'] = $params;$data['client_logo'] = $client_logo;
$data['mail_content'] = $mail_content; $data['mail_content'] = $mail_content;
$mail_content = view('mail_template', $data); $mail_content = view('mail_template', $data);
@ -647,7 +663,8 @@ class sendMailNotification
$policy_name = $inner_item['policy_name']; $policy_name = $inner_item['policy_name'];
if ($inner_item['relationship'] == 'Self') { if ($inner_item['relationship'] == 'Self') {
$emp_code = ' (' . $inner_item['emp_code'] . ')'; // $emp_code = ' (' . $inner_item['emp_code'] . ')';
$emp_code = ' ( Employee Code : ' . $inner_item['emp_code'] . ')';
} else { } else {
$emp_code = ''; $emp_code = '';
} }
@ -859,7 +876,7 @@ class sendMailNotification
$mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content); $mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content);
$data['params'] = $params; $data['params'] = $params;$data['client_logo'] = $client_logo;
$data['mail_content'] = $mail_content; $data['mail_content'] = $mail_content;
$mail_content = view('mail_template', $data); $mail_content = view('mail_template', $data);
@ -1167,7 +1184,7 @@ class sendMailNotification
// //
// $mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content); // $mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content);
// $data['params'] = $params; // $data['params'] = $params;$data['client_logo'] = $client_logo;
// $data['mail_content'] = $mail_content; // $data['mail_content'] = $mail_content;
// $mail_content = view('mail_template',$data); // $mail_content = view('mail_template',$data);
// $mail_content = $header_of_mail . // $mail_content = $header_of_mail .
@ -1248,7 +1265,7 @@ class sendMailNotification
$mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content); $mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content);
$data['params'] = $params; $data['params'] = $params;$data['client_logo'] = $client_logo;
$data['mail_content'] = $mail_content; $data['mail_content'] = $mail_content;
$mail_content = view('mail_template', $data); $mail_content = view('mail_template', $data);
@ -1262,6 +1279,23 @@ class sendMailNotification
$client_data = $params['client_data']; $client_data = $params['client_data'];
$mail = $params['test_mail']; $mail = $params['test_mail'];
$mailAttachmentModel = new MailAttachmentModel();
$attachment_data = $mailAttachmentModel
->select('file_path, file_name')
->where('notification_id', $notification_data['id'])
->where('is_active', 1)
->findAll()??[];
$attachments = [];
foreach ($attachment_data as $data) {
$attachments[] = [
"filePath" => WRITEPATH . $data['file_path'],
"fileName" => $data['file_name']
];
}
$mail_content = $notification_data['mail_content']; $mail_content = $notification_data['mail_content'];
$subject = $notification_data['subject']; $subject = $notification_data['subject'];
@ -1287,11 +1321,11 @@ class sendMailNotification
$mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content); $mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content);
$data['params'] = $params; $data['params'] = $params;$data['client_logo'] = $client_logo;
$data['mail_content'] = $mail_content; $data['mail_content'] = $mail_content;
$mail_content = view('mail_template', $data); $mail_content = view('mail_template', $data);
$wholeData = ['mail' => $mail, 'subject' => $subject, 'message' => $mail_content, 'bcc' => $client_data['common_mails'], 'reply_to' => $client_data['reply_to']]; $wholeData = ['mail' => $mail, 'subject' => $subject, 'message' => $mail_content, 'bcc' => $client_data['common_mails'], 'attachments' => $attachments , 'reply_to' => $client_data['reply_to']];
} }
} }
@ -1345,7 +1379,7 @@ class sendMailNotification
$mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content); $mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content);
$data['params'] = $params; $data['params'] = $params;$data['client_logo'] = $client_logo;
$data['mail_content'] = $mail_content; $data['mail_content'] = $mail_content;
$mail_content = view('mail_template', $data); $mail_content = view('mail_template', $data);
@ -1406,7 +1440,8 @@ class sendMailNotification
$policy_name = $array_list['policy_name']; $policy_name = $array_list['policy_name'];
if ($array_list['relationship'] == 'Self') { if ($array_list['relationship'] == 'Self') {
$emp_code = ' (' . $array_list['emp_code'] . ')'; // $emp_code = ' (' . $array_list['emp_code'] . ')';
$emp_code = ' ( Employee Code : ' . $array_list['emp_code'] . ')';
} else { } else {
$emp_code = ''; $emp_code = '';
} }
@ -1496,7 +1531,7 @@ class sendMailNotification
} }
} }
$mail_content = str_replace(["[[member_name]]", "{{member_name}}"], $name . ' (' . $emp_code . ')', $mail_content); $mail_content = str_replace(["[[member_name]]", "{{member_name}}"], $name . $emp_code, $mail_content);
$mail_content = str_replace(["[[member_mobile]]", "{{member_mobile}}"], $mobile, $mail_content); $mail_content = str_replace(["[[member_mobile]]", "{{member_mobile}}"], $mobile, $mail_content);
$mail_content = str_replace(["[[member_summary]]", "{{member_summary}}"], $table_content, $mail_content); $mail_content = str_replace(["[[member_summary]]", "{{member_summary}}"], $table_content, $mail_content);
@ -1504,7 +1539,7 @@ class sendMailNotification
$mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content); $mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content);
$data['params'] = $params; $data['params'] = $params;$data['client_logo'] = $client_logo;
$data['mail_content'] = $mail_content; $data['mail_content'] = $mail_content;
$mail_content = view('mail_template', $data); $mail_content = view('mail_template', $data);
@ -1562,7 +1597,8 @@ class sendMailNotification
$policy_name = $array_list['policy_name']; $policy_name = $array_list['policy_name'];
if ($array_list['relationship'] == 'Self') { if ($array_list['relationship'] == 'Self') {
$emp_code = ' (' . $array_list['emp_code'] . ')'; // $emp_code = ' (' . $array_list['emp_code'] . ')';
$emp_code = ' ( Employee Code : ' . $array_list['emp_code'] . ')';
} else { } else {
$emp_code = ''; $emp_code = '';
} }
@ -1652,14 +1688,14 @@ class sendMailNotification
} }
} }
$mail_content = str_replace(["[[member_name]]", "{{member_name}}"], $name . ' (' . $emp_code . ')', $mail_content); $mail_content = str_replace(["[[member_name]]", "{{member_name}}"], $name . $emp_code, $mail_content);
$mail_content = str_replace(["[[member_summary]]", "{{member_summary}}"], $table_content, $mail_content); $mail_content = str_replace(["[[member_summary]]", "{{member_summary}}"], $table_content, $mail_content);
$mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content); $mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content);
$data['params'] = $params; $data['params'] = $params;$data['client_logo'] = $client_logo;
$data['mail_content'] = $mail_content; $data['mail_content'] = $mail_content;
$mail_content = view('mail_template', $data); $mail_content = view('mail_template', $data);
@ -1809,14 +1845,14 @@ class sendMailNotification
} }
} }
$mail_content = str_replace(["[[member_name]]", "{{member_name}}"], $name . ' (' . $emp_code . ')', $mail_content); $mail_content = str_replace(["[[member_name]]", "{{member_name}}"], $name . $emp_code, $mail_content);
$mail_content = str_replace(["[[member_summary]]", "{{member_summary}}"], $table_content, $mail_content); $mail_content = str_replace(["[[member_summary]]", "{{member_summary}}"], $table_content, $mail_content);
$mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content); $mail_content = preg_replace('/<p[^>]*>(&nbsp;|\s)*<\/p>/i', '', $mail_content);
$data['params'] = $params; $data['params'] = $params;$data['client_logo'] = $client_logo;
$data['mail_content'] = $mail_content; $data['mail_content'] = $mail_content;
$mail_content = view('mail_template', $data); $mail_content = view('mail_template', $data);

View File

@ -56,6 +56,7 @@ if (!function_exists('file_Upload')) {
{ {
if ($fileToUpload !== null && $fileToUpload->isValid() && !$fileToUpload->hasMoved()) { if ($fileToUpload !== null && $fileToUpload->isValid() && !$fileToUpload->hasMoved()) {
$fileName = $fileToUpload->getName(); $fileName = $fileToUpload->getName();
$fileName = preg_replace('/[\s\x{00A0}\x{200B}-\x{200D}\x{FEFF}]/u', '', $fileName);
$fileToUpload->move($filepath, $fileName); $fileToUpload->move($filepath, $fileName);
return $fileName; return $fileName;
} else { } else {

View File

@ -45,6 +45,7 @@ class EmployeeModel extends Model
"mpin", "mpin",
"is_mpin_skipped", "is_mpin_skipped",
"is_biometric_enabled", "is_biometric_enabled",
"password",
]; ];
// Callbacks // Callbacks
@ -170,6 +171,7 @@ class EmployeeModel extends Model
->join('client_policy', 'client_policy.id = employee_polices.client_policy_id') ->join('client_policy', 'client_policy.id = employee_polices.client_policy_id')
->join('policy_type', 'policy_type.id = client_policy.policy_type_id') ->join('policy_type', 'policy_type.id = client_policy.policy_type_id')
->where('client_policy.policy_status', 1) ->where('client_policy.policy_status', 1)
->where('client_policy.enrolment_visibility', 1)
->where('employee_polices.status !=', 'truncated') ->where('employee_polices.status !=', 'truncated')
->where('employee_polices.is_active', 1) ->where('employee_polices.is_active', 1)
->where('employee_polices.employee_id', $id) ->where('employee_polices.employee_id', $id)

View File

@ -73,7 +73,7 @@
<div class="row float-left" style="position: relative; bottom: 20px; left: 13px;"> <div class="row float-left" style="position: relative; bottom: 20px; left: 13px;">
<button type="button" id="btnAutoBranchFetch" <button type="button" id="btnAutoBranchFetch"
class="btn btn-primary waves-effect waves-light btn-sm "> Auto Fetch branch Details</button> class="btn btn-primary waves-effect waves-light btn-sm "> Fetch Client Branch (Post-Enrolment)</button>
</div> </div>
<div class="row float-right" style="position: relative; bottom: 20px; right: 13px;"> <div class="row float-right" style="position: relative; bottom: 20px; right: 13px;">
@ -315,6 +315,7 @@ $('#btnBranchAdd').click(function() {
$('#branch_form').parsley().reset(); $('#branch_form').parsley().reset();
$('.ac').css('display', 'block'); $('.ac').css('display', 'block');
$('#post_branch_id').val(''); $('#post_branch_id').val('');
$('#branch_id_primarykey').val('');
contactCount = 1 contactCount = 1
var addButton = document.getElementById('add'); var addButton = document.getElementById('add');
@ -378,6 +379,8 @@ $("#branch_form").submit(function(event) {
var selectedValues = $("#selected").val(); var selectedValues = $("#selected").val();
console.log(selectedValues, selectedValues); console.log(selectedValues, selectedValues);
console.log("branch_id_primarykey", $('#branch_id_primarykey').val());
let level_contect_data = getContactsData(); let level_contect_data = getContactsData();
console.log('level_contect_data', level_contect_data); console.log('level_contect_data', level_contect_data);
@ -958,25 +961,30 @@ function validateDuplicateByClientBranch(input, field, submitButId) {
// 1 Local duplication check (User entered) // 1 Local duplication check (User entered)
let isLocalDuplicate = false; let isLocalDuplicate = false;
$('input[name="' + field + '[]"]').each(function(index) { $('input[name="' + field + '[]"]').each(function(index) {
let compareVal = $(this).val().trim();
console.log(`Entered value: ${value} | Contact ${index+1} value: ${$(this).val()}`); console.log(`Entered value: ${value} | Contact ${index+1} value: ${$(this).val()}`);
if (this !== input && $(this).val().trim() === value) { if (this !== input && compareVal !== '' && compareVal === value) {
isLocalDuplicate = true; isLocalDuplicate = true;
return false; // break loop return false;
} }
}); });
if (isLocalDuplicate) { if (isLocalDuplicate) {
console.log(`r u n Local`); console.log(`r u n Local`);
console.log(`btn Dis - true`); console.log(`duplicate found for ${field}`);
toastr.warning(message, 'WARNING'); toastr.warning(message, 'WARNING');
$('#' + submitButId).prop('disabled', true); $('#' + submitButId).prop('disabled', true);
return; // dont call server if duplicate in UI return;
}
// important Skip empty values
if (value === '') {
checkAllFieldsValid(submitButId);
return;
} }
// Don't forgot be careful // Don't forgot be careful
// 2 Server-side duplicate check (DB) // 2 Server-side duplicate check (DB)
if (!isLocalDuplicate && value !== '') {
$.ajax({ $.ajax({
url: '<?= base_url("client/others/check-duplicate") ?>', url: '<?= base_url("client/others/check-duplicate") ?>',
type: 'POST', type: 'POST',
@ -990,12 +998,12 @@ function validateDuplicateByClientBranch(input, field, submitButId) {
success: function(response) { success: function(response) {
if (response.isDuplicate) { if (response.isDuplicate) {
console.log(`r u n Server`); console.log(`r u n Server`);
console.log(`btn Dis - true`); console.log(`duplicate found for ${field}`);
toastr.warning(message, 'WARNING'); toastr.warning(message, 'WARNING');
$('#' + submitButId).prop('disabled', true); $('#' + submitButId).prop('disabled', true);
} else { } else {
console.log(`btn Dis - false`); console.log(`No duplicate for ${field}`);
$('#' + submitButId).prop('disabled', false); checkAllFieldsValid(submitButId);
} }
}, },
error: function(xhr, status, error) { error: function(xhr, status, error) {
@ -1003,6 +1011,54 @@ function validateDuplicateByClientBranch(input, field, submitButId) {
} }
}); });
} }
// recheck all contacts before enabling submit
function checkAllFieldsValid(submitButId) {
let emailDuplicates = false;
let mobileDuplicates = false;
// cross check all EMAIL duplicates
let emailSeen = [];
$('input[name="email[]"]').each(function() {
let val = $(this).val().trim();
if (val && emailSeen.includes(val)) {
emailDuplicates = true;
} else if (val) {
emailSeen.push(val);
}
});
// cross check all MOBILE duplicates
let mobileSeen = [];
$('input[name="mobile[]"]').each(function() {
let val = $(this).val().trim();
if (val && mobileSeen.includes(val)) {
mobileDuplicates = true;
} else if (val) {
mobileSeen.push(val);
}
});
if (emailDuplicates || mobileDuplicates) {
$('#' + submitButId).prop('disabled', true);
// show correct message based on whats duplicated
if (emailDuplicates && mobileDuplicates) {
toastr.warning("Email and Mobile values are duplicate!", "WARNING");
console.log('Both Email and Mobile duplicates');
} else if (emailDuplicates) {
toastr.warning("Email duplicate!", "WARNING");
console.log('Cross Check Email duplicates');
} else if (mobileDuplicates) {
toastr.warning("Mobile duplicate!", "WARNING");
console.log('Cross Check Mobile duplicates');
}
console.log(`btn Dis - true`);
} else {
console.log('unique — enable');
console.log(`btn Dis - false`);
$('#' + submitButId).prop('disabled', false);
}
} }
function getContactsData() { function getContactsData() {

View File

@ -115,7 +115,7 @@ body {
<div class="modal-dialog modal-dialog-centered" style="margin-left: 400px !important;"> <div class="modal-dialog modal-dialog-centered" style="margin-left: 400px !important;">
<div class="modal-content modal-lg"> <div class="modal-content modal-lg">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title" id="autoFetchBranchModalLabel">Auto Fetch Branch Details</h5> <h5 class="modal-title" id="autoFetchBranchModalLabel">Fetch Client Branch (Post-Enrolment)</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> <button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>

View File

@ -1,3 +1,69 @@
<style>
#notification_slider .switch-label {
position: relative;
display: inline-flex;
align-items: center;
gap: 10px;
cursor: pointer;
font-weight: 500;
color: #333;
justify-content: flex-end;
margin-right: 40px;
}
#notification_slider .switch-label input {
opacity: 0;
width: 0;
height: 0;
}
#notification_slider .slider {
position: relative;
width: 50px;
height: 25px;
background-color: #fff;
border-radius: 25px;
box-shadow: 0 0 5px rgba(0,0,0,0.2);
transition: 0.3s;
}
#notification_slider .slider::before {
content: "";
position: absolute;
height: 19px;
width: 19px;
left: 3px;
top: 3px;
background-color: #ccc;
border-radius: 50%;
transition: 0.3s;
}
#notification_slider input:checked + .slider {
background-color: #ff4d4d; /* red when ON */
}
#notification_slider input:checked + .slider::before {
transform: translateX(25px);
background-color: #fff;
}
#notification_slider .switch-text {
user-select: none;
}
#table-client-policy_wrapper .row>.col-sm-12.col-md-6:first-child{
display: none;
}
#table-client-policy_filter{
text-align: left;
}
</style>
<div class="tab-pane fade" id="police-tab"> <div class="tab-pane fade" id="police-tab">
<div class="row float-right" style="padding-bottom: 10px; position: relative;right: 13px;"> <div class="row float-right" style="padding-bottom: 10px; position: relative;right: 13px;">
@ -5,6 +71,18 @@
<!-- <button type="button" id="BtnAddSuccess" class="btn btn-success waves-effect waves-light BtnAddSuccess btn-sm" onclick="showModal()"><span class="fa fa-plus-square" aria-hidden="true" style="padding: 5px 10px;"></span>Add Policy From Lead</button> --> <!-- <button type="button" id="BtnAddSuccess" class="btn btn-success waves-effect waves-light BtnAddSuccess btn-sm" onclick="showModal()"><span class="fa fa-plus-square" aria-hidden="true" style="padding: 5px 10px;"></span>Add Policy From Lead</button> -->
</div> </div>
<br>
<div class="" style="padding: 10px; position: absolute;
right: 0;" id="notification_slider">
<label class="switch-label">
<input type="checkbox" id="chk-show-expired">
<span class="slider"></span>
<span class="switch-text">Expired Policies</span>
</label>
</div>
<div class="table-responsive" id="table_list"> <div class="table-responsive" id="table_list">
<table class="table table-borderless table mb-0" id="table-client-policy"> <table class="table table-borderless table mb-0" id="table-client-policy">
@ -322,6 +400,9 @@ $(document).ready(function() {
// Get today's date // Get today's date
var today = new Date(); var today = new Date();
const showExpired = $('#chk-show-expired').is(':checked');
var startDatePicker = flatpickr("#start_date", { var startDatePicker = flatpickr("#start_date", {
dateFormat: "d-m-Y", dateFormat: "d-m-Y",
defaultDate: today, defaultDate: today,
@ -436,6 +517,7 @@ $(document).ready(function() {
si_mapping = `<a href="#" data-id="${item.id}" data-typeid="${item.policy_type_id}" class="dropdown-item" onclick="showModal('si_mapping'); loadModal('${item.id}','${item.base_policy}');"><i class="mdi mdi-swap-horizontal"></i> SI Mapping</a>`; si_mapping = `<a href="#" data-id="${item.id}" data-typeid="${item.policy_type_id}" class="dropdown-item" onclick="showModal('si_mapping'); loadModal('${item.id}','${item.base_policy}');"><i class="mdi mdi-swap-horizontal"></i> SI Mapping</a>`;
} }
if(showExpired == false && checkDateStatus(item.policy_end_date) != 'Expired'){
policyTable += policyTable +=
` `
@ -457,7 +539,7 @@ $(document).ready(function() {
${auto_si_menu} ${auto_si_menu}
${si_mapping}`; ${si_mapping}`;
// Conditionally render the delete option based on the role // Conditionally render the delete option based on the role
if (role !== 3 && role !== 4) { if (role != 3 && role != 4) {
policyTable += policyTable +=
` `
<a href="#" data-id="${item.id}" id="${search_term}" data-typeid="${item.policy_type_id}" class="dropdown-item" onclick="removepolicy(this)"><i class="fa fa-trash mr-2 text-muted font-18 vertical-middle"></i>Delete</a>`; <a href="#" data-id="${item.id}" id="${search_term}" data-typeid="${item.policy_type_id}" class="dropdown-item" onclick="removepolicy(this)"><i class="fa fa-trash mr-2 text-muted font-18 vertical-middle"></i>Delete</a>`;
@ -470,6 +552,7 @@ $(document).ready(function() {
</tr> </tr>
`; `;
}
}); });
$('#policy_table').append(policyTable); $('#policy_table').append(policyTable);
@ -479,8 +562,10 @@ $(document).ready(function() {
$('#table-client-policy').DataTable({ $('#table-client-policy').DataTable({
paging: true, paging: true,
searching: false, searching: true,
// ordering: false autoWidth: false,
responsive: true,
}); });
@ -491,6 +576,8 @@ $('.btnAdd').click(function() {
fetchClientBranch() fetchClientBranch()
$('#notification_slider').hide();
$('#policy_form')[0].reset(); $('#policy_form')[0].reset();
$('#add_form').show(); $('#add_form').show();
$('#table_list').hide(); $('#table_list').hide();
@ -524,6 +611,7 @@ $('.btnAdd').click(function() {
$('.btnBack').click(function() { $('.btnBack').click(function() {
$('#notification_slider').show();
$('#policy_form')[0].reset(); $('#policy_form')[0].reset();
$('#add_form').hide(); $('#add_form').hide();
$('#table_list').show(); $('#table_list').show();
@ -548,6 +636,8 @@ $("#policy_form").submit(function(event) {
event.preventDefault(); event.preventDefault();
$('#notification_slider').show();
policy_PrimaryKey = $('#client_id_policy').val(); policy_PrimaryKey = $('#client_id_policy').val();
policy_client = $('#policy_PrimaryKey').val(); policy_client = $('#policy_PrimaryKey').val();
@ -689,6 +779,8 @@ $("#policy_form").submit(function(event) {
auto_si_menu = `<a href="#" data-id="${item.id}" data-typeid="${item.policy_type_id}" class="dropdown-item" onclick="showModal('rack_rate_auto_si_modal'); getRackRateSIAmountAndAutoSiDataForAutoSI('${item.id}')"><i class="mdi mdi-autorenew mr-2 text-muted font-18 vertical-middle"></i>Auto SI</a>`; auto_si_menu = `<a href="#" data-id="${item.id}" data-typeid="${item.policy_type_id}" class="dropdown-item" onclick="showModal('rack_rate_auto_si_modal'); getRackRateSIAmountAndAutoSiDataForAutoSI('${item.id}')"><i class="mdi mdi-autorenew mr-2 text-muted font-18 vertical-middle"></i>Auto SI</a>`;
} }
if(checkDateStatus(item.policy_end_date) != 'Expired'){
policyTable += policyTable +=
` `
<tr> <tr>
@ -710,7 +802,7 @@ $("#policy_form").submit(function(event) {
${auto_si_menu}`; ${auto_si_menu}`;
// Conditionally render the delete option based on the role // Conditionally render the delete option based on the role
if (role !== 3 && role !== 4) { if (role != 3 && role != 4) {
policyTable += policyTable +=
` `
<a href="#" data-id="${item.id}" id="${search_term}" data-typeid="${item.policy_type_id}" class="dropdown-item" onclick="removepolicy(this)"><i class="fa fa-trash mr-2 text-muted font-18 vertical-middle"></i>Delete</a>`; <a href="#" data-id="${item.id}" id="${search_term}" data-typeid="${item.policy_type_id}" class="dropdown-item" onclick="removepolicy(this)"><i class="fa fa-trash mr-2 text-muted font-18 vertical-middle"></i>Delete</a>`;
@ -722,6 +814,10 @@ $("#policy_form").submit(function(event) {
</td> </td>
</tr> </tr>
`; `;
}
}); });
$('#policy_table').append(policyTable); $('#policy_table').append(policyTable);
// console.log(policyTable); // console.log(policyTable);
@ -748,7 +844,11 @@ $("#policy_form").submit(function(event) {
//console.log('Unknown error occurred', 'Warning'); //console.log('Unknown error occurred', 'Warning');
} }
}, 1000); }, 1000);
},
complete:function(){
$('notification_slider').show();
} }
}); });
}); });
@ -812,6 +912,9 @@ $('body').on('click', '.btnPolicyEdit', function() {
var policy_form_action = ''; var policy_form_action = '';
var policy_id = $(this).attr('data-id'); var policy_id = $(this).attr('data-id');
$('#notification_slider').hide();
$('.loader').fadeIn(); $('.loader').fadeIn();
$('.loader-mask').fadeIn(); $('.loader-mask').fadeIn();
@ -1035,6 +1138,10 @@ $('body').on('click', '.btnPolicyEdit', function() {
$('.loader-mask').delay(350).fadeOut('slow'); $('.loader-mask').delay(350).fadeOut('slow');
//console.log('Something Wrong!', 'warning'); //console.log('Something Wrong!', 'warning');
}, 1000); }, 1000);
},
complete:function() {
$('#notification_slider').hide();
console.log('complete call');
} }
}); });
}); });
@ -2143,3 +2250,173 @@ function featchClient() {
</script> </script>
<script>
$(document).ready(function () {
$('#chk-show-expired').on('change', function () {
const showExpired = $(this).is(':checked');
let policyTable = '';
let data = <?= isset($client_policy) ? json_encode($client_policy) : '[]' ?>;
let role = data.role
delete data.role;
console.log("checkbox working");
$.each(data, function(index, item) {
// console.log('step 1');
var patternGMC = /gmc/i; // Case insensitive pattern for 'gmc'
var patternGPA = /gpa/i; // Case insensitive pattern for 'gpa'
var subject = item.policy_type_name;
//console.log('search terms subject', subject);
if (patternGMC.test(subject)) {
search_term = 'GMC';
} else if (patternGPA.test(subject)) {
search_term = 'GPA';
} else {
search_term = subject; // Set default value if neither 'GMC' nor 'GPA' exists
}
//console.log('search_term :', search_term)
var enrollmentStatus = '';
if (item.inception_type == 1) {
enrollmentStatus = 'N/A'
} else if (item.inception_type == 2) {
if (item.open_for_enrollment == 1) {
enrollmentStatus = '<a href="#" data-id="' + item.id + '" id="' + item.policy_id +
'" class="btnOpenEnroll" data-toggle="tooltip" data-placement="left" title="Click To Close Enrolment">Open</a>'
} else if (item.open_for_enrollment == 0) {
enrollmentStatus =
'<a href="#" data-toggle="tooltip" data-placement="top" title="Click To Open Enrolment" data-id="' +
item.id + '" id="' + item.policy_id + '" class="btnOpenEnroll">Closed</a>'
}
}
var tpaValue = 'TPA Unavailable';
if (item.tpa_short && item.tpa_branch_code) {
tpaValue = item.tpa_short + '-' + item.tpa_branch_code;
}
var policy_name_data = `${item.policy_type_name ?? ''}` + ' - ' + `${item.policy_no ?? ''}`;
// console.log("Inside of item "+ JSON.stringify(item,null,2));
let auto_si_menu = '';
let si_mapping = '';
if(item.policy_type_id == 2){
auto_si_menu = `<a href="#" data-id="${item.id}" data-typeid="${item.policy_type_id}" class="dropdown-item" onclick="showModal('rack_rate_auto_si_modal'); getRackRateSIAmountAndAutoSiDataForAutoSI('${item.id}')"><i class="mdi mdi-autorenew mr-2 text-muted font-18 vertical-middle"></i>Auto SI</a>`;
}
if (item.policy_type_id == 3 && item.base_policy != null && item.base_policy != ''){
console.log('base policy '+ item.base_policy);
si_mapping = `<a href="#" data-id="${item.id}" data-typeid="${item.policy_type_id}" class="dropdown-item" onclick="showModal('si_mapping'); loadModal('${item.id}','${item.base_policy}');"><i class="mdi mdi-swap-horizontal"></i> SI Mapping</a>`;
}
if(showExpired == true && checkDateStatus(item.policy_end_date) == 'Expired'){
policyTable +=
`
<tr>
<! -- <td>${item.insurer_short} - ${item.insurer_branch_name}</td> -->
<td>${policy_name_data}</td>
<td>${item.branch_name ? item.branch_name : ' - '}</td>
<! -- <td>${tpaValue}</td> -->
<td>${(item.policy_start_date)} / ${(item.policy_end_date)}</td>
<td style="text-align: center;">${(enrollmentStatus)}</td>
<td>${checkDateStatus(item.policy_end_date, 1)}</td>
<td>
<div class="btn-group dropdown">
<a href="javascript: void(0);" class="dropdown-toggle arrow-none btn btn-light btn-sm" data-toggle="dropdown"aria-expanded="false"><i class="mdi mdi-dots-horizontal"></i></a>
<div class="dropdown-menu dropdown-menu-right">
<a href="#" data-id="${item.id}" id="${item.policy_id}" class="dropdown-item btnPolicyEdit"><i class="mdi mdi-lead-pencil mr-2 text-muted font-18 vertical-middle"></i>Edit</a>
<a href="#" data-id="${item.id}" id="${search_term}" data-typeid="${item.policy_type_id}" class="dropdown-item btnPolicyMaster" data-toggle="modal"><i class="mdi mdi-wrench mr-2 text-muted font-18 vertical-middle"></i>Terms</a>
<a href="#" data-id="${item.id}" id="${search_term}" data-typeid="${item.policy_type_id}" class="dropdown-item btnPolicyModel" data-toggle="modal" data-target="#bs-example-modal-lg"><i class="mdi mdi-book-open mr-2 text-muted font-18 vertical-middle"></i>Rack Rate</a>
${auto_si_menu}
${si_mapping}`;
// Conditionally render the delete option based on the role
if (role != 3 && role != 4) {
policyTable +=
`
<a href="#" data-id="${item.id}" id="${search_term}" data-typeid="${item.policy_type_id}" class="dropdown-item" onclick="removepolicy(this)"><i class="fa fa-trash mr-2 text-muted font-18 vertical-middle"></i>Delete</a>`;
}
policyTable += `
</div>
</div>
</td>
</tr>
`;
}
if(showExpired == false && checkDateStatus(item.policy_end_date) != 'Expired'){
policyTable +=
`
<tr>
<! -- <td>${item.insurer_short} - ${item.insurer_branch_name}</td> -->
<td>${policy_name_data}</td>
<td>${item.branch_name ? item.branch_name : ' - '}</td>
<! -- <td>${tpaValue}</td> -->
<td>${(item.policy_start_date)} / ${(item.policy_end_date)}</td>
<td style="text-align: center;">${(enrollmentStatus)}</td>
<td>${checkDateStatus(item.policy_end_date, 1)}</td>
<td>
<div class="btn-group dropdown">
<a href="javascript: void(0);" class="dropdown-toggle arrow-none btn btn-light btn-sm" data-toggle="dropdown"aria-expanded="false"><i class="mdi mdi-dots-horizontal"></i></a>
<div class="dropdown-menu dropdown-menu-right">
<a href="#" data-id="${item.id}" id="${item.policy_id}" class="dropdown-item btnPolicyEdit"><i class="mdi mdi-lead-pencil mr-2 text-muted font-18 vertical-middle"></i>Edit</a>
<a href="#" data-id="${item.id}" id="${search_term}" data-typeid="${item.policy_type_id}" class="dropdown-item btnPolicyMaster" data-toggle="modal"><i class="mdi mdi-wrench mr-2 text-muted font-18 vertical-middle"></i>Terms</a>
<a href="#" data-id="${item.id}" id="${search_term}" data-typeid="${item.policy_type_id}" class="dropdown-item btnPolicyModel" data-toggle="modal" data-target="#bs-example-modal-lg"><i class="mdi mdi-book-open mr-2 text-muted font-18 vertical-middle"></i>Rack Rate</a>
${auto_si_menu}
${si_mapping}`;
// Conditionally render the delete option based on the role
if (role != 3 && role != 4) {
policyTable +=
`
<a href="#" data-id="${item.id}" id="${search_term}" data-typeid="${item.policy_type_id}" class="dropdown-item" onclick="removepolicy(this)"><i class="fa fa-trash mr-2 text-muted font-18 vertical-middle"></i>Delete</a>`;
}
policyTable += `
</div>
</div>
</td>
</tr>
`;
}
});
const table = $('#table-client-policy').DataTable();
table.clear().destroy();
$('#table-client-policy tbody').html(policyTable); // replace tbody content
$('#table-client-policy').DataTable({
paging: true,
searching: true,
autoWidth: false,
responsive: true,
});
});
});
</script>

View File

@ -99,10 +99,8 @@
</div> </div>
<div class="card-body status-option" id="statusContent" style="padding: 1.5rem !important;background-color: darkgrey;"> <div class="card-body status-option" id="statusContent" style="padding: 1.5rem !important;background-color: darkgrey;">
<div class="text-center"> <div class="text-center">
<div class="row" style="/* margin-left: 125px; */margin-bottom: -11px;">
<div class="row" style="margin-left: 125px; margin-bottom: -11px;">
<div class="col-xl-2 col-md-2"> <div class="col-xl-2 col-md-2">
<div class="card cardWidth"> <div class="card cardWidth">
<div class="card-body" id="emp_count_view_click"> <div class="card-body" id="emp_count_view_click">
@ -111,7 +109,6 @@
<h5 class="text-muted font-weight-normal mt-0 text-truncate" title="Emp Count">Emp Count</h5> <h5 class="text-muted font-weight-normal mt-0 text-truncate" title="Emp Count">Emp Count</h5>
<h3 class="my-2 py-1"><span data-plugin="counterup" id="emp_count_view">0</span></h3> <h3 class="my-2 py-1"><span data-plugin="counterup" id="emp_count_view">0</span></h3>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@ -168,10 +165,20 @@
</div> </div>
</div> </div>
</div><!-- end col --> </div><!-- end col -->
<div class="col-xl-2 col-md-2">
<div class="card">
<div class="card-body" id="emp_draft_view_click">
<div class="d-flex justify-content-between" style="justify-content: center !important;">
<div>
<h5 class="text-muted font-weight-normal mt-0 text-truncate" title="Not Logged-In">Draft</h5>
<h3 class="my-2 py-1"><span data-plugin="counterup" id="emp_draft_view">0</span></h3>
</div>
</div>
</div>
</div>
</div><!-- end col -->
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@ -297,16 +304,16 @@
}); });
} }
function filterTable(columnIndex, filterValue) // function filterTable(columnIndex, filterValue)
{ // {
var table = $('#tickets-table').DataTable(); // var table = $('#tickets-table').DataTable();
// Reset the search filter for all columns // // Reset the search filter for all columns
table.columns().search('').draw(); // table.columns().search('').draw();
// Apply the filter to the specified column // // Apply the filter to the specified column
table.column(columnIndex).search(filterValue).draw(); // table.column(columnIndex).search(filterValue).draw();
} // }
function fetchEmpolyeeList(event) function fetchEmpolyeeList(event)
{ {
@ -357,28 +364,45 @@
return; return;
} }
var enrolled_count = 0; var enrolled_count = 0;
var not_enrolled_count = 0;
var loggedIn_count = 0; var loggedIn_count = 0;
var not_loggedIn_count = 0;
var self_count = 0;
var draft_count = 0;
data.forEach(function(employee, index) { data.forEach(function(employee, index) {
if(employee.relationship.toLowerCase() === "self"){
self_count++
}
if(employee.emp_status === 'enrolled'){ if(employee.emp_status === 'enrolled'){
var enrolled = 'Yes'; var enrolled = 'Yes';
enrolled_count++; enrolled_count++;
}else{ }else{
var enrolled = 'No'; var enrolled = 'No';
if (employee.relationship.toLowerCase() === "self") {
not_enrolled_count++;
}
} }
if(employee.user_type === 'employee'){ if(employee.relationship.toLowerCase() === "self" && employee.user_type === 'employee'){
var loggedIn = 'Yes'; var loggedIn = 'Yes';
loggedIn_count++; loggedIn_count++;
}else{ }else{
if (employee.relationship && employee.relationship.toLowerCase() === "self") { if (employee.relationship && employee.relationship.toLowerCase() === "self") {
var loggedIn = 'No'; var loggedIn = 'No';
not_loggedIn_count ++;
}else{ }else{
var loggedIn = '-'; var loggedIn = '-';
} }
} }
if(employee.relationship.toLowerCase() === "self" && enrolled == "No" && loggedIn == "Yes"){
draft_count++;
}
table.row.add([ table.row.add([
index + 1, index + 1,
employee.employee_name, employee.employee_name,
@ -387,15 +411,15 @@
enrolled, enrolled,
loggedIn loggedIn
]); ]);
$('#emp_count_view').html(data.length);
$('#emp_enrolled_view').html(enrolled_count);
$('#emp_not_enrolled_view').html(data.length - enrolled_count);
$('#emp_logged_in_view').html(loggedIn_count);
$('#emp_not_logged_in_view').html(data.length - loggedIn_count);
}); });
$('#emp_count_view').html(self_count);
$('#emp_enrolled_view').html(enrolled_count);
$('#emp_not_enrolled_view').html(not_enrolled_count);
$('#emp_logged_in_view').html(loggedIn_count);
$('#emp_not_logged_in_view').html(not_loggedIn_count);
$('#emp_draft_view').html(draft_count);
table.draw(); table.draw();
function getUrlParameter(name) { function getUrlParameter(name) {
@ -490,91 +514,167 @@
}); });
$('#emp_enrolled_view_click').on('click', function() { // $('#emp_enrolled_view_click').on('click', function() {
console.log($(this).hasClass('click_hover')); // console.log($(this).hasClass('click_hover'));
if ($(this).hasClass('click_hover')) { // if ($(this).hasClass('click_hover')) {
// // $(this).removeClass('click_hover');
// $('.click_hover').each(function() {
// $(this).removeClass('click_hover'); // $(this).removeClass('click_hover');
$('.click_hover').each(function() { // });
$(this).removeClass('click_hover'); // table.columns().search('').draw(); // Clear all filters and show all data
}); // }else{
table.columns().search('').draw(); // Clear all filters and show all data // $('.click_hover').each(function() {
}else{ // $(this).removeClass('click_hover');
$('.click_hover').each(function() { // });
$(this).removeClass('click_hover'); // $('#emp_enrolled_view_click').addClass('click_hover');
}); // filterTable(4, 'Yes'); // Filter "Enrolled" column (4th column, index 3)
$('#emp_enrolled_view_click').addClass('click_hover'); // }
filterTable(4, 'Yes'); // Filter "Enrolled" column (4th column, index 3) // });
}
// $('#emp_not_enrolled_view_click').on('click', function() {
// if ($(this).hasClass('click_hover')) {
// // $(this).removeClass('click_hover');
// $('.click_hover').each(function() {
// $(this).removeClass('click_hover');
// });
// table.columns().search('').draw(); // Clear all filters and show all data
// }else{
// $('.click_hover').each(function() {
// $(this).removeClass('click_hover');
// });
// $('#emp_not_enrolled_view_click').addClass('click_hover');
// filterTable(4, 'No'); // Filter "Enrolled" column (4th column, index 3)
// }
// });
// $('#emp_logged_in_view_click').on('click', function() {
// if ($(this).hasClass('click_hover')) {
// // $(this).removeClass('click_hover');
// $('.click_hover').each(function() {
// $(this).removeClass('click_hover');
// });
// table.columns().search('').draw(); // Clear all filters and show all data
// }else{
// $('.click_hover').each(function() {
// $(this).removeClass('click_hover');
// });
// $('#emp_logged_in_view_click').addClass('click_hover');
// filterTable(5, 'Yes'); // Filter "Logged-In" column (5th column, index 4)
// }
// });
// $('#emp_not_logged_in_view_click').on('click', function() {
// if ($(this).hasClass('click_hover')) {
// // $(this).removeClass('click_hover');
// $('.click_hover').each(function() {
// $(this).removeClass('click_hover');
// });
// table.columns().search('').draw(); // Clear all filters and show all data
// }else{
// $('.click_hover').each(function() {
// $(this).removeClass('click_hover');
// });
// $('#emp_not_logged_in_view_click').addClass('click_hover');
// filterTable(5, 'No'); // Filter "Logged-In" column (5th column, index 4)
// }
// });
// $('#emp_draft_view_click').on('click', function() {
// var table = $('#tickets-table').DataTable();
// if ($(this).hasClass('click_hover')) {
// // Remove active class and reset filters
// $('.click_hover').removeClass('click_hover');
// table.columns().search('').draw(); // Clear all filters
// } else {
// // Remove existing active state and set new one
// $('.click_hover').removeClass('click_hover');
// $(this).addClass('click_hover');
// // Apply both filters simultaneously
// filterTableMultiple([
// { column: 5, value: 'Yes' },
// { column: 4, value: 'No' }
// ]);
// }
// });
// $('#emp_count_view_click').on('click', function() {
// if ($(this).hasClass('click_hover')) {
// // $(this).removeClass('click_hover');
// $('.click_hover').each(function() {
// $(this).removeClass('click_hover');
// });
// table.columns().search('').draw(); // Clear all filters and show all data
// }else{
// $('.click_hover').each(function() {
// $(this).removeClass('click_hover');
// });
// $('#emp_count_view_click').addClass('click_hover');
// table.columns().search('').draw(); // Clear all filters and show all data
// }
// });
// === Attach click handlers ===
$('#emp_enrolled_view_click').on('click', function() {
handleFilterClick('emp_enrolled_view_click', [{ column: 4, value: 'Yes' }]);
}); });
$('#emp_not_enrolled_view_click').on('click', function() { $('#emp_not_enrolled_view_click').on('click', function() {
if ($(this).hasClass('click_hover')) { handleFilterClick('emp_not_enrolled_view_click', [
// $(this).removeClass('click_hover'); { column: 3, value: 'Self' },
$('.click_hover').each(function() { { column: 4, value: 'No' }
$(this).removeClass('click_hover'); ]);
});
table.columns().search('').draw(); // Clear all filters and show all data
}else{
$('.click_hover').each(function() {
$(this).removeClass('click_hover');
});
$('#emp_not_enrolled_view_click').addClass('click_hover');
filterTable(4, 'No'); // Filter "Enrolled" column (4th column, index 3)
}
}); });
$('#emp_logged_in_view_click').on('click', function() { $('#emp_logged_in_view_click').on('click', function() {
if ($(this).hasClass('click_hover')) { handleFilterClick('emp_logged_in_view_click', [{ column: 5, value: 'Yes' }]);
// $(this).removeClass('click_hover');
$('.click_hover').each(function() {
$(this).removeClass('click_hover');
});
table.columns().search('').draw(); // Clear all filters and show all data
}else{
$('.click_hover').each(function() {
$(this).removeClass('click_hover');
});
$('#emp_logged_in_view_click').addClass('click_hover');
filterTable(5, 'Yes'); // Filter "Logged-In" column (5th column, index 4)
}
}); });
$('#emp_not_logged_in_view_click').on('click', function() { $('#emp_not_logged_in_view_click').on('click', function() {
if ($(this).hasClass('click_hover')) { handleFilterClick('emp_not_logged_in_view_click', [{ column: 5, value: 'No' }]);
// $(this).removeClass('click_hover');
$('.click_hover').each(function() {
$(this).removeClass('click_hover');
}); });
table.columns().search('').draw(); // Clear all filters and show all data
}else{ // 🔹 Attach click handlers
$('.click_hover').each(function() { $('#emp_draft_view_click').on('click', function() {
$(this).removeClass('click_hover'); handleFilterClick('emp_draft_view_click', [
}); { column: 5, value: 'Yes' }, // Logged-in = Yes
$('#emp_not_logged_in_view_click').addClass('click_hover'); { column: 4, value: 'No' } // Enrolled = No
filterTable(5, 'No'); // Filter "Logged-In" column (5th column, index 4) ]);
}
}); });
$('#emp_count_view_click').on('click', function() { $('#emp_count_view_click').on('click', function() {
if ($(this).hasClass('click_hover')) { // Just reset all filters — no column filter needed
// $(this).removeClass('click_hover'); handleFilterClick('emp_count_view_click', [{ column: 3, value: 'Self' }]);
$('.click_hover').each(function() {
$(this).removeClass('click_hover');
});
table.columns().search('').draw(); // Clear all filters and show all data
}else{
$('.click_hover').each(function() {
$(this).removeClass('click_hover');
});
$('#emp_count_view_click').addClass('click_hover');
table.columns().search('').draw(); // Clear all filters and show all data
}
}); });
toggleContent(); toggleContent();
}); });
// Common function to handle DataTable filter toggling
function handleFilterClick(buttonId, filters = null) {
var table = $('#tickets-table').DataTable();
var $button = $('#' + buttonId);
if ($button.hasClass('click_hover')) {
// Remove highlight and clear filters
$('.click_hover').removeClass('click_hover');
table.columns().search('').draw();
} else {
// Remove existing active state, set new one
$('.click_hover').removeClass('click_hover');
$button.addClass('click_hover');
// Apply multiple filters (array of {column, value})
table.columns().search(''); // clear existing filters
if(filters){
filters.forEach(f => table.column(f.column).search(f.value));
}
table.draw();
}
}
function toggleContent() function toggleContent()
{ {
var content = document.getElementById("statusContent"); var content = document.getElementById("statusContent");

View File

@ -85,8 +85,8 @@
<script src="<?= base_url() . "public"; ?>/assets/libs/datatables.net-buttons/js/buttons.print.min.js"></script> <script src="<?= base_url() . "public"; ?>/assets/libs/datatables.net-buttons/js/buttons.print.min.js"></script>
<script src="<?= base_url() . "public"; ?>/assets/libs/datatables.net-keytable/js/dataTables.keyTable.min.js"></script> <script src="<?= base_url() . "public"; ?>/assets/libs/datatables.net-keytable/js/dataTables.keyTable.min.js"></script>
<script src="<?= base_url() . "public"; ?>/assets/libs/datatables.net-select/js/dataTables.select.min.js"></script> <script src="<?= base_url() . "public"; ?>/assets/libs/datatables.net-select/js/dataTables.select.min.js"></script>
<script src="<?= base_url() . "public"; ?>/assets/libs/pdfmake/build/pdfmake.min.js"></script> <!-- <script src="<?= base_url() . "public"; ?>/assets/libs/pdfmake/build/pdfmake.min.js"></script> -->
<script src="<?= base_url() . "public"; ?>/assets/libs/pdfmake/build/vfs_fonts.js"></script> <!-- <script src="<?= base_url() . "public"; ?>/assets/libs/pdfmake/build/vfs_fonts.js"></script> -->
<!-- third party js ends --> <!-- third party js ends -->
<script src="<?= base_url() . "public"; ?>/assets/libs/bootstrap-datepicker/js/bootstrap-datepicker.min.js"></script> <script src="<?= base_url() . "public"; ?>/assets/libs/bootstrap-datepicker/js/bootstrap-datepicker.min.js"></script>

View File

@ -85,8 +85,8 @@
<script src="<?= base_url() . "public"; ?>/assets/libs/datatables.net-buttons/js/buttons.print.min.js"></script> <script src="<?= base_url() . "public"; ?>/assets/libs/datatables.net-buttons/js/buttons.print.min.js"></script>
<script src="<?= base_url() . "public"; ?>/assets/libs/datatables.net-keytable/js/dataTables.keyTable.min.js"></script> <script src="<?= base_url() . "public"; ?>/assets/libs/datatables.net-keytable/js/dataTables.keyTable.min.js"></script>
<script src="<?= base_url() . "public"; ?>/assets/libs/datatables.net-select/js/dataTables.select.min.js"></script> <script src="<?= base_url() . "public"; ?>/assets/libs/datatables.net-select/js/dataTables.select.min.js"></script>
<script src="<?= base_url() . "public"; ?>/assets/libs/pdfmake/build/pdfmake.min.js"></script> <!-- <script src="<?= base_url() . "public"; ?>/assets/libs/pdfmake/build/pdfmake.min.js"></script>
<script src="<?= base_url() . "public"; ?>/assets/libs/pdfmake/build/vfs_fonts.js"></script> <script src="<?= base_url() . "public"; ?>/assets/libs/pdfmake/build/vfs_fonts.js"></script> -->
<!-- third party js ends --> <!-- third party js ends -->
<script src="<?= base_url() . "public"; ?>/assets/libs/bootstrap-datepicker/js/bootstrap-datepicker.min.js"></script> <script src="<?= base_url() . "public"; ?>/assets/libs/bootstrap-datepicker/js/bootstrap-datepicker.min.js"></script>

View File

@ -62,9 +62,9 @@
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.3/dist/umd/popper.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.3/dist/umd/popper.min.js"></script>
<link rel="manifest" href="../manifest.json"> <!-- <link rel="manifest" href="../manifest.json"> -->
<script> <!-- <script>
if ('serviceWorker' in navigator) { if ('serviceWorker' in navigator) {
window.addEventListener('load', function() { window.addEventListener('load', function() {
navigator.serviceWorker.register('../service-worker.js').then(function(registration) { navigator.serviceWorker.register('../service-worker.js').then(function(registration) {
@ -74,7 +74,7 @@
}); });
}); });
} }
</script> </script> -->
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css" /> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css" /> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css" />
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

View File

@ -62,18 +62,18 @@
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.3/dist/umd/popper.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.3/dist/umd/popper.min.js"></script>
<link rel="manifest" href="../manifest.json"> <!-- <link rel="manifest" href="../manifest.json"> -->
<script> <script>
if ('serviceWorker' in navigator) { // if ('serviceWorker' in navigator) {
window.addEventListener('load', function() { // window.addEventListener('load', function() {
navigator.serviceWorker.register('../service-worker.js').then(function(registration) { // navigator.serviceWorker.register('../service-worker.js').then(function(registration) {
// console.log('Service Worker registration successful with scope:', registration.scope); // // console.log('Service Worker registration successful with scope:', registration.scope);
}, function(err) { // }, function(err) {
// console.log('Service Worker registration failed:', err); // // console.log('Service Worker registration failed:', err);
}); // });
}); // });
} // }
</script> </script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css" /> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css" /> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css" />

View File

@ -62,18 +62,18 @@
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.3/dist/umd/popper.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.3/dist/umd/popper.min.js"></script>
<link rel="manifest" href="../manifest.json"> <!-- <link rel="manifest" href="../manifest.json"> -->
<script> <script>
if ('serviceWorker' in navigator) { // if ('serviceWorker' in navigator) {
window.addEventListener('load', function() { // window.addEventListener('load', function() {
navigator.serviceWorker.register('../service-worker.js').then(function(registration) { // navigator.serviceWorker.register('../service-worker.js').then(function(registration) {
// console.log('Service Worker registration successful with scope:', registration.scope); // // console.log('Service Worker registration successful with scope:', registration.scope);
}, function(err) { // }, function(err) {
// console.log('Service Worker registration failed:', err); // // console.log('Service Worker registration failed:', err);
}); // });
}); // });
} // }
</script> </script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css" /> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css" /> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css" />

View File

@ -1,3 +1,20 @@
<?php
$value = "";
if(isset($params['notification_data'])){
$value = $params['notification_data'];
}
if(isset($params['notification'])){
$value = $params['notification'];
}
$value = json_decode($value['mail_content_json'] ?? '[]', true);
$contentWidth = (int) $value['body']['values']['contentWidth'] ?? 500;
?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
@ -10,8 +27,8 @@
<style> <style>
.mail-template-header { .mail-template-header {
max-width: 500px; max-width: <?=$contentWidth?>px;
background: #ffffff; background-color: #ffffff !important;
border-bottom: 1px solid #00999E; border-bottom: 1px solid #00999E;
width: 100%; /* default: allow full width */ width: 100%; /* default: allow full width */
} }
@ -19,27 +36,48 @@
/* On screens smaller than 600px → force 100% */ /* On screens smaller than 600px → force 100% */
@media screen and (max-width: 600px) { @media screen and (max-width: 600px) {
.mail-template-header { .mail-template-header {
background-color: #ffffff !important;
max-width: 100% !important; max-width: 100% !important;
width: 100% !important; width: 100% !important;
} }
} }
.mail-template-footer { .mail-template-footer {
max-width: 500px; max-width: <?=$contentWidth?>px;
background: #ffffff; background-color: #ffffff !important;
border-top: 1px solid #00999E; border-top: 1px solid #00999E;
width: 100%; /* default: allow full width */ width: 100%; /* default: allow full width */
} }
p{
margin:0 !important;
}
/* On screens smaller than 600px → force 100% */ /* On screens smaller than 600px → force 100% */
@media screen and (max-width: 600px) { @media screen and (max-width: 600px) {
.mail-template-footer { .mail-template-footer {
background-color: #ffffff !important;
max-width: 100% !important; max-width: 100% !important;
width: 100% !important; width: 100% !important;
} }
} }
@media screen and (max-width: 600px){
.header-div{
width: 100% !important;
}
.footer-div{
width : 100% !important ;
}
}
.client_logo,
.nhance_logo
{
vertical-align: middle !important;
}
</style> </style>
@ -47,15 +85,22 @@
<body> <body>
<!-- header --> <!-- header -->
<div align="center"> <div align="center" class="header-div">
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="mail-template-header"> <table width="100%" border="0" cellspacing="0" cellpadding="0" class="mail-template-header">
<tr style="height:90px; background-color: #ffffff;"> <tr style="height:90px; background-color: #ffffff !important;">
<td align="left" valign="middle" style="padding:20px;" width="50%"> <td align="left" class="client_logo" style="padding:5px;" width="50%">
<img src="<?= base_url('/public/uploads/logo/'); ?>" <div style="
alt="Client Logo" width:160px;
style="max-height:80px; max-width: 160px;"> height:80px;
background-image:url('<?= $client_logo ?>');
background-size:contain;
background-repeat:no-repeat;
background-position: center;
">
</div>
</td> </td>
<td align="right" valign="middle" style="padding:20px;" width="50%"> <td align="right" class="nhance_logo" style="padding:5px;" width="50%">
<img src="<?= base_url('/public/assets/images/Nhance-Logo-Final.png'); ?>" <img src="<?= base_url('/public/assets/images/Nhance-Logo-Final.png'); ?>"
alt="Default Logo" alt="Default Logo"
style="height:auto; max-width: 120px;"> style="height:auto; max-width: 120px;">
@ -74,9 +119,9 @@
<!-- footer --> <!-- footer -->
<div align="center"> <div align="center" class="footer-div">
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="mail-template-footer"> <table width="100%" border="0" cellspacing="0" cellpadding="0" class="mail-template-footer">
<tr style="background-color: #ffffff;"> <tr style="background-color: #ffffff !important;">
<td align="center" valign="middle" style="padding-top:5px;"> <td align="center" valign="middle" style="padding-top:5px;">
<img src="<?= base_url('/public/assets/images/Nhance-Logo-Final.png'); ?>" <img src="<?= base_url('/public/assets/images/Nhance-Logo-Final.png'); ?>"
alt="Default Logo" alt="Default Logo"
@ -93,3 +138,4 @@
</html> </html>

View File

@ -370,6 +370,18 @@
<input type="file" id="Question_title_fileInput" style="display: none;"> <input type="file" id="Question_title_fileInput" style="display: none;">
<table id="attachment_table" class="table table-sm mb-0" style="margin-top: 30px;">
<thead>
<tr>
<th>Attachments</th>
<th>Action</th>
</tr>
</thead>
<tbody id="attachment_tbody_reminder_mail_attachments">
</tbody>
</table>
</div> </div>
<div class="form-group text-right m-b-0"> <div class="form-group text-right m-b-0">
@ -1144,13 +1156,56 @@
var container = ''; var container = '';
if( template_name == 'member_welcome_mail' ) { if( template_name == 'member_welcome_mail' ) {
container = document.getElementById('attachment_tbody'); container = document.getElementById('attachment_tbody');
} //else { }
else if( template_name == "member_reminder_mail" ){
container = document.getElementById('attachment_tbody_reminder_mail_attachments');
}
//else {
// container = document.getElementById('attachment_tbody_ecard'); // container = document.getElementById('attachment_tbody_ecard');
// } // }
if (data) { if (data && template_name == "member_welcome_mail") {
$(container).empty(); $('#attachment_tbody').empty();
data.forEach(item => {
const newRow = document.createElement('tr');
newRow.className = 'dynamic-form-row';
newRow.innerHTML = `
<td> ${item.file_name} </td>
<td> <a class="fa fa-trash" data-id="${item.id}" onclick="removeAttachment('${item.id}')"></a></td>
`;
container.appendChild(newRow);
});
// Creating another row for the form with file input
const newFormRow = document.createElement('tr');
newFormRow.className = 'dynamic-form-row';
newFormRow.innerHTML = `
<td>
<form class="ajax" onsubmit="submitAttachmentForm(event, this)">
<div class="form-row">
<div class="form-group col-3">
<input type="file" class="file-input__input" name="file" required>
</div>
<div class="form-group col-2">
<button type="submit" class="btn btn-sm btn-primary">Submit</button>
</div>
</div>
</form>
</td>
`;
container.appendChild(newFormRow);
}
else if (data && template_name == "member_reminder_mail") {
$('#attachment_tbody_reminder_mail_attachments').empty();
data.forEach(item => { data.forEach(item => {
const newRow = document.createElement('tr'); const newRow = document.createElement('tr');
@ -1186,6 +1241,8 @@
container.appendChild(newFormRow); container.appendChild(newFormRow);
} else { } else {
// If no data is passed, create a new empty row // If no data is passed, create a new empty row
const newRow = document.createElement('tr'); const newRow = document.createElement('tr');
newRow.className = 'dynamic-form-row'; newRow.className = 'dynamic-form-row';
@ -1518,7 +1575,14 @@
initWithRetry(); initWithRetry();
if (res.data && template_name == 'member_welcome_mail') { if (res.data && (template_name == 'member_welcome_mail' )) {
console.log("file attachment for member_welcome_mail");
console.log(template_name);
addHTMLInput(res.data);
}
if (res.data && ( template_name == "member_reminder_mail" )) {
console.log("file attachment for member_reminder_mail");
console.log(template_name);
addHTMLInput(res.data); addHTMLInput(res.data);
} //else { } //else {
// addHTMLInput(); // addHTMLInput();