MERGE_TEST_HR_CHANGES&ISSUES

This commit is contained in:
Ubuntu 2026-02-06 11:45:29 +05:30
commit 370736acae
19 changed files with 774 additions and 265 deletions

View File

@ -560,6 +560,8 @@ $routes->group("/api", ["filter" => "authJWT"], function ($routes) {
$routes->get("getSSORedirectUrl", "ApiServiceController::getSSORedirectUrl");
$routes->get("getEmployeePolicy", "EmployeeRestController::getEmployeePolicy");
$routes->get("downloadCdSplitUpFile", "EmployeeRestController::downloadCdSplitUpFile");
$routes->get("downloadFileTableFile/(:any)", "EmployeeController::downloadFileList/$1");
$routes->group("employeeRest", ['filter' => ['appSignature'] ], function ($routes) {
@ -657,6 +659,7 @@ $routes->group("employeeRest", ["filter" => ['GlobalPostFileUploadGuard', 'appSi
$routes->get("hrFileDownload", "EmployeeRestController::hrFileDownload");
$routes->post("hrFileUpload", "EmployeeRestController::hrFileUpload");
$routes->post("updateHrFileUploadData", "EmployeeRestController::updateHrFileUploadData");
$routes->post("getHrDashboad", "EmployeeRestController::getHrDashboad");
//thz_master's

View File

@ -6328,7 +6328,21 @@ class ClientController extends AdminController
}
public function sendextraparam()
{
{
// $zipService = new \App\Libraries\ZipService();
// $source = WRITEPATH . 'uploads/hr_files';
// $destination = WRITEPATH . 'tmp/archive_' . date('Ymd') . '.zip';
// $result = $zipService->createLocalZip($source, $destination);
// if ($result['status']) {
// echo "File is ready at: " . $result['path'];
// } else {
// echo "Error creating zip: " . $result['message'];
// }
// die;
// $cd = $this->view_Deposit(2, 'rest', ['client_id' => 58, 'cd_ac_pk' => 94]);
// dd($cd);
// $return = db_connect()->table('jobs')->where('id', 1677)->get()->getRowArray();
@ -6343,7 +6357,10 @@ class ClientController extends AdminController
// $res = $medi_assist->MediAssistGetBenefDetails(['policy_no' => '97000034240400000030', 'file_id' => 389, 'return_type' => 'job', 'client_policy_id' => 6192 ]);
// dd($res);
// $employeeController = new EmployeeController();
$employeeController = new EmployeeController();
// $response = $employeeController->getEmployeeEcardFromTmpFolderAndZipToS3(json_decode('{"batch_no":2,"last_emp_policy_id":"13218","folder_name":"bulk_ecards_IOCL-77448855996699885555_2026-02-05_09-32-22","processed_in_this_batch_data_count":7,"pdf_count":0,"hr_id":"1"}', true));
// $response = $employeeController->bulkEcardDownloadAsZipFromS3(json_decode('{"client_policy_id":"6066","hr_id":"1"}', true));
// dd($response);
// $employeeController->truncateFileData('633');
// $res = $this->getHrAccessData(4075); dd($res);
@ -6363,6 +6380,8 @@ class ClientController extends AdminController
// $response = $ticketServiceController->tpaClaimDumpImporter(["file_id" => 54]); //mediassist
// $response = $ticketServiceController->tpaClaimDumpToTicketMasterImporters(["file_id" => 48]); //vidal
// $response = $ticketServiceController->tpaClaimDumpToTicketMasterImporters(["file_id" => 54]); //mediassist
// $response = $ticketServiceController->tpaClaimDumpToTicketMasterImporters(["file_id" => 4]); //abhi
// dd($response);
// ---------- TICKET CONTROLLER --------------------------------------------------------------------------------
@ -7743,180 +7762,6 @@ class ClientController extends AdminController
$combinedHrAccessData = $this->constructHrAccessData($hrAccessData, $client_id ,$pre_client_data['id']);
return $combinedHrAccessData;
}
// do not remove this commented items
// public function constructHrAccessData($data, $client_id , $pre_client_id)
// {
// // print_rr($data);die;
// $preHrs = $data['pre_hr_data'];
// $postHrs = $data['post_hr_data'];
// $hrAccessTableData = $data['hr_access_table_data'];
// $merged = [];
// // Merge based on mobile and email
// foreach ($postHrs as $post) {
// $found = false;
// foreach ($preHrs as $index => $pre) {
// if ( trim($post['hr_mobile']) == trim($pre['hr_mobile']) && trim($post['hr_mail']) == trim($pre['hr_mail']) ) {
// $merged[] = [
// 'pre_hr_id' => $pre['pre_hr_id'],
// 'post_hr_id' => $post['post_hr_id'],
// 'hr_name' => $post['hr_name'],
// 'hr_mobile' => $post['hr_mobile'],
// 'hr_mail' => $post['hr_mail'],
// 'pre_branch_id' => $pre['pre_branch_id'] ?? null,
// 'post_branch_id' => $post['post_branch_id'] ?? null,
// 'post_branch_name' => $post['post_branch_name'] ?? null
// ];
// unset($preHrs[$index]); // remove matched pre_hr
// $found = true;
// break;
// }
// }
// if (!$found) {
// $merged[] = [
// 'pre_hr_id' => null,
// 'post_hr_id' => $post['post_hr_id'],
// 'hr_name' => $post['hr_name'],
// 'hr_mobile' => $post['hr_mobile'],
// 'hr_mail' => $post['hr_mail'],
// 'pre_branch_id' => $pre['pre_branch_id'] ?? null,
// 'post_branch_id' => $post['post_branch_id'] ?? null ,
// 'post_branch_name' => $post['post_branch_name'] ?? null
// ];
// }
// }
// // Remaining preHrs (not matched)
// foreach ($preHrs as $pre) {
// foreach ($merged as $value) {
// if ( trim($pre['hr_mobile']) == trim($value['hr_mobile']) && trim($pre['hr_mail']) == trim($value['hr_mail']) ) {
// continue 2; // Skip adding this pre_hr as it's already matched
// }
// }
// $merged[] = [
// 'pre_hr_id' => $pre['pre_hr_id'],
// 'post_hr_id' => null,
// 'hr_name' => $pre['hr_name'],
// 'hr_mobile' => $pre['hr_mobile'],
// 'hr_mail' => $pre['hr_mail'],
// 'pre_branch_id' => $pre['pre_branch_id'] ?? null,
// 'post_branch_id' => $post['post_branch_id'] ?? null ,
// 'post_branch_name' => $post['post_branch_name'] ?? null
// ];
// }
// // dd($merged);
// $result = [];
// if (empty($hrAccessTableData)) {
// // No access data — fill result with hr data and other fields as null
// foreach ($merged as $hr) {
// $result[] = [
// 'hr_access_table_pk' => null,
// 'post_client_id' => $client_id ?? null,
// 'pre_hr_id' => $hr['pre_hr_id'] ?? null,
// 'post_hr_id' => $hr['post_hr_id'] ?? null,
// 'allowed_pre_modules' => [],
// 'allowed_post_modules' => [],
// 'allowed_pre_policies' => [],
// 'allowed_active_policies' => [],
// 'allowed_cd' => [],
// 'hr_name' => $hr['hr_name'] ?? null,
// 'hr_mobile' => $hr['hr_mobile'] ?? null,
// 'hr_mail' => $hr['hr_mail'] ?? null,
// 'pre_branch_id' => $hr['pre_branch_id'] ?? null,
// 'post_branch_id' => $hr['post_branch_id'] ?? null ,
// 'post_branch_name' => $hr['post_branch_name'] ?? null ,
// 'pre_client_id' => $pre_client_id ?? null
// ];
// }
// } else {
// // First create a map of HR data by post_hr_id for quick lookup
// $hrMap = [];
// foreach ($merged as $hr) {
// $hrMap[$hr['post_hr_id']] = $hr;
// }
// // Process access data first
// foreach ($hrAccessTableData as $access) {
// $post_hr_id = $access['post_hr_id'];
// // Check if this HR exists in our merged data
// if (isset($hrMap[$post_hr_id])) {
// $hr = $hrMap[$post_hr_id];
// $temp_arr_key = $hr['hr_mobile'] . $hr['hr_mail'];
// // Parse allowed modules
// $allowed_modules = json_decode($access['allowed_modules'], true) ?? null;
// $allowed_pre_modules = $allowed_modules['pre'] ?? [];
// $allowed_post_modules = $allowed_modules['post'] ?? [];
// $result[$temp_arr_key] = [
// 'hr_access_table_pk' => $access['id'] ?? null,
// 'post_client_id' => $access['post_client_id'] ?? null,
// 'pre_hr_id' => $hr['pre_hr_id'] ?? null,
// 'post_hr_id' => $hr['post_hr_id'] ?? null,
// 'allowed_pre_modules' => $allowed_pre_modules,
// 'allowed_post_modules' => $allowed_post_modules,
// 'allowed_pre_policies' => json_decode($access['allowed_pre_policies'], true) ?? [],
// 'allowed_active_policies' => json_decode($access['allowed_active_policies'], true) ?? [],
// 'allowed_cd' => json_decode($access['allowed_cd'], true) ?? [],
// 'hr_name' => $hr['hr_name'],
// 'hr_mobile' => $hr['hr_mobile'],
// 'hr_mail' => $hr['hr_mail'],
// 'pre_branch_id' => $hr['pre_branch_id'] ?? null,
// 'post_branch_id' => $hr['post_branch_id'] ?? null ,
// 'post_branch_name' => $hr['post_branch_name'] ?? null ,
// 'pre_client_id' => $pre_client_id ?? null
// ];
// // Remove from map so we know it's been processed
// unset($hrMap[$post_hr_id]);
// }
// }
// // Now process any remaining HRs that didn't have access records
// foreach ($hrMap as $hr) {
// $temp_arr_key = $hr['hr_mobile'] . $hr['hr_mail'];
// $result[$temp_arr_key] = [
// 'hr_access_table_pk' => null,
// 'post_client_id' => $client_id ?? null,
// 'pre_hr_id' => $hr['pre_hr_id'] ?? null,
// 'post_hr_id' => $hr['post_hr_id'] ?? null,
// 'allowed_pre_modules' => [],
// 'allowed_post_modules' => [],
// 'allowed_pre_policies' => [],
// 'allowed_active_policies' => [],
// 'allowed_cd' => [],
// 'hr_name' => $hr['hr_name'] ?? null,
// 'hr_mobile' => $hr['hr_mobile'] ?? null,
// 'hr_mail' => $hr['hr_mail'] ?? null,
// 'pre_branch_id' => $hr['pre_branch_id'] ?? null,
// 'post_branch_id' => $hr['post_branch_id'] ?? null ,
// 'post_branch_name' => $hr['post_branch_name'] ?? null ,
// 'pre_client_id' => $pre_client_id ?? null
// ];
// }
// }
// $resultData['hr_access_data'] = array_values($result);
// $resultData['pre_policy_data'] = $data['pre_policy_data'];
// $resultData['post_policy_data'] = $data['post_policy_data'];
// $resultData['post_cd_data'] = $data['post_cd_data'];
// return $resultData;
// }
public function constructHrAccessData($data, $client_id , $pre_client_id)
{
@ -8172,7 +8017,180 @@ class ClientController extends AdminController
];
return ['status' => 'failed', 'code' => 500, 'message' => $th->getMessage(), 'error_data' => $errorData];
}
}
}
public function constructHrAccessData_OLD($data, $client_id , $pre_client_id)
{
// print_rr($data);die;
$preHrs = $data['pre_hr_data'];
$postHrs = $data['post_hr_data'];
$hrAccessTableData = $data['hr_access_table_data'];
$merged = [];
// Merge based on mobile and email
foreach ($postHrs as $post) {
$found = false;
foreach ($preHrs as $index => $pre) {
if ( trim($post['hr_mobile']) == trim($pre['hr_mobile']) && trim($post['hr_mail']) == trim($pre['hr_mail']) ) {
$merged[] = [
'pre_hr_id' => $pre['pre_hr_id'],
'post_hr_id' => $post['post_hr_id'],
'hr_name' => $post['hr_name'],
'hr_mobile' => $post['hr_mobile'],
'hr_mail' => $post['hr_mail'],
'pre_branch_id' => $pre['pre_branch_id'] ?? null,
'post_branch_id' => $post['post_branch_id'] ?? null,
'post_branch_name' => $post['post_branch_name'] ?? null
];
unset($preHrs[$index]); // remove matched pre_hr
$found = true;
break;
}
}
if (!$found) {
$merged[] = [
'pre_hr_id' => null,
'post_hr_id' => $post['post_hr_id'],
'hr_name' => $post['hr_name'],
'hr_mobile' => $post['hr_mobile'],
'hr_mail' => $post['hr_mail'],
'pre_branch_id' => $pre['pre_branch_id'] ?? null,
'post_branch_id' => $post['post_branch_id'] ?? null ,
'post_branch_name' => $post['post_branch_name'] ?? null
];
}
}
// Remaining preHrs (not matched)
foreach ($preHrs as $pre) {
foreach ($merged as $value) {
if ( trim($pre['hr_mobile']) == trim($value['hr_mobile']) && trim($pre['hr_mail']) == trim($value['hr_mail']) ) {
continue 2; // Skip adding this pre_hr as it's already matched
}
}
$merged[] = [
'pre_hr_id' => $pre['pre_hr_id'],
'post_hr_id' => null,
'hr_name' => $pre['hr_name'],
'hr_mobile' => $pre['hr_mobile'],
'hr_mail' => $pre['hr_mail'],
'pre_branch_id' => $pre['pre_branch_id'] ?? null,
'post_branch_id' => $post['post_branch_id'] ?? null ,
'post_branch_name' => $post['post_branch_name'] ?? null
];
}
// dd($merged);
$result = [];
if (empty($hrAccessTableData)) {
// No access data — fill result with hr data and other fields as null
foreach ($merged as $hr) {
$result[] = [
'hr_access_table_pk' => null,
'post_client_id' => $client_id ?? null,
'pre_hr_id' => $hr['pre_hr_id'] ?? null,
'post_hr_id' => $hr['post_hr_id'] ?? null,
'allowed_pre_modules' => [],
'allowed_post_modules' => [],
'allowed_pre_policies' => [],
'allowed_active_policies' => [],
'allowed_cd' => [],
'hr_name' => $hr['hr_name'] ?? null,
'hr_mobile' => $hr['hr_mobile'] ?? null,
'hr_mail' => $hr['hr_mail'] ?? null,
'pre_branch_id' => $hr['pre_branch_id'] ?? null,
'post_branch_id' => $hr['post_branch_id'] ?? null ,
'post_branch_name' => $hr['post_branch_name'] ?? null ,
'pre_client_id' => $pre_client_id ?? null
];
}
} else {
// First create a map of HR data by post_hr_id for quick lookup
$hrMap = [];
foreach ($merged as $hr) {
$hrMap[$hr['post_hr_id']] = $hr;
}
// Process access data first
foreach ($hrAccessTableData as $access) {
$post_hr_id = $access['post_hr_id'];
// Check if this HR exists in our merged data
if (isset($hrMap[$post_hr_id])) {
$hr = $hrMap[$post_hr_id];
$temp_arr_key = $hr['hr_mobile'] . $hr['hr_mail'];
// Parse allowed modules
$allowed_modules = json_decode($access['allowed_modules'], true) ?? null;
$allowed_pre_modules = $allowed_modules['pre'] ?? [];
$allowed_post_modules = $allowed_modules['post'] ?? [];
$result[$temp_arr_key] = [
'hr_access_table_pk' => $access['id'] ?? null,
'post_client_id' => $access['post_client_id'] ?? null,
'pre_hr_id' => $hr['pre_hr_id'] ?? null,
'post_hr_id' => $hr['post_hr_id'] ?? null,
'allowed_pre_modules' => $allowed_pre_modules,
'allowed_post_modules' => $allowed_post_modules,
'allowed_pre_policies' => json_decode($access['allowed_pre_policies'], true) ?? [],
'allowed_active_policies' => json_decode($access['allowed_active_policies'], true) ?? [],
'allowed_cd' => json_decode($access['allowed_cd'], true) ?? [],
'hr_name' => $hr['hr_name'],
'hr_mobile' => $hr['hr_mobile'],
'hr_mail' => $hr['hr_mail'],
'pre_branch_id' => $hr['pre_branch_id'] ?? null,
'post_branch_id' => $hr['post_branch_id'] ?? null ,
'post_branch_name' => $hr['post_branch_name'] ?? null ,
'pre_client_id' => $pre_client_id ?? null
];
// Remove from map so we know it's been processed
unset($hrMap[$post_hr_id]);
}
}
// Now process any remaining HRs that didn't have access records
foreach ($hrMap as $hr) {
$temp_arr_key = $hr['hr_mobile'] . $hr['hr_mail'];
$result[$temp_arr_key] = [
'hr_access_table_pk' => null,
'post_client_id' => $client_id ?? null,
'pre_hr_id' => $hr['pre_hr_id'] ?? null,
'post_hr_id' => $hr['post_hr_id'] ?? null,
'allowed_pre_modules' => [],
'allowed_post_modules' => [],
'allowed_pre_policies' => [],
'allowed_active_policies' => [],
'allowed_cd' => [],
'hr_name' => $hr['hr_name'] ?? null,
'hr_mobile' => $hr['hr_mobile'] ?? null,
'hr_mail' => $hr['hr_mail'] ?? null,
'pre_branch_id' => $hr['pre_branch_id'] ?? null,
'post_branch_id' => $hr['post_branch_id'] ?? null ,
'post_branch_name' => $hr['post_branch_name'] ?? null ,
'pre_client_id' => $pre_client_id ?? null
];
}
}
$resultData['hr_access_data'] = array_values($result);
$resultData['pre_policy_data'] = $data['pre_policy_data'];
$resultData['post_policy_data'] = $data['post_policy_data'];
$resultData['post_cd_data'] = $data['post_cd_data'];
return $resultData;
}
public function saveHrAccessData()
{
@ -8837,17 +8855,6 @@ class ClientController extends AdminController
return $default_templates_inserted ? true : false;
}
// public function downloadClientKycDocs_2()
// {
// $file = WRITEPATH . 'uploads/client_kyc_documents/' . $file_name; // Example file path
// if (file_exists($file)) {
// return $this->response->download($file, null)->setFileName($file_name);
// } else {
// return "File not found.";
// }
// }
public function downloadClientKycDocs_2($file_name = null)
{
if (!$file_name) {

View File

@ -492,7 +492,25 @@ class EmployeeController extends AdminController
if(!empty($error) && $retun_type == 'api'){
$send = isset($error['error_summary'][5]) || isset($error['error_summary'][6]) ? true : false;
if($send){
return $this->respond(['status' => false, 'code' => 404, 'message' => $error['error_data'] ?? 'System error', 'data' => []], 200);
$string = $error['error_data'] ?? 'System error';
$errorMap = [
"Column order conflict" => "Invalid file format. Please use the sample file.",
];
$message = $string; // Default to the original error
foreach ($errorMap as $keyword => $friendlyMessage) {
if (strpos($string, $keyword) !== false) {
$message = $friendlyMessage;
break; // Stop looking once we find a match
}
}
return $this->respond(['status' => false, 'code' => 404, 'message' => $message, 'data' => []], 200);
}
}
@ -4446,7 +4464,7 @@ class EmployeeController extends AdminController
* 4. SEQUENTIAL RE-QUEUE (SAFE)
* --------------------------------------------------------- */
if ($execution_mode === 'sequential' && $rowCount === $batch_size) {
$this->myLogger->logme('info', "$log_search_context"."Re-queueing next batch - " . json_encode([
$this->myLogger->logme('error', "$log_search_context"."Re-queueing next batch - " . json_encode([
'next_batch' => $batch_no + 1,
'last_emp_id' => $new_last_emp_id
]));
@ -4619,5 +4637,202 @@ class EmployeeController extends AdminController
return $this->response->setJSON($data);
}
public function bulkEcardDownloadAsZipFromS3($params)
{
try {
$limit = $params['limit'] ?? 100;
$batch_no = $params['batch_no'] ?? 1;
$last_id = $params['last_emp_policy_id'] ?? 0;
// Fetch batch data
$employee_data = $this->employeePolicyModel->getEmployeeDataWithPolicyUsingClientPolicyIdOrEmployeePolicyIds($params, $limit, $last_id);
if (empty($employee_data)) {
if(!empty($last_id)){
$this->myLogger->logme('error', "bulkEcardDownloadAsZipFromS3 - No more records after last_emp_policy_id: {$last_id}");
$this->myLogger->logme('error', "getEmployeeEcardFromTmpFolderAndZipToS3 - Queuing ZIP creation for folder: " . ($params['folder_name'] ?? 'N/A'));
$r = Jobs::addJob(['job_name' => 'getEmployeeEcardFromTmpFolderAndZipToS3', 'payload' => $params]);
}
return ['status' => true, 'message' => 'Proceeding to Zip'];
}
// Use a consistent folder name across batches (passed in params)
$folderName = $params['folder_name'] ?? 'bulk_ecards_' . $employee_data[0]['policy_no'] . '_' . date('Y-m-d_H-i-s');
$tempPath = FCPATH . 'tmp/' . $folderName . '/';
if (!is_dir($tempPath)) {
mkdir($tempPath, 0777, true);
}
$s3 = \Config\Services::getS3Service();
$pdf_count = 0;
$current_last_id = end($employee_data)['emp_policy_id'];
foreach ($employee_data as $emp_value) {
// Track the last ID in this batch
$current_last_id = $emp_value['emp_policy_id'];
$s3_key = 'ecard_' . $emp_value['name'] . '(' . $emp_value['emp_code'] . ')' . '_' . $emp_value['tpa_id'] . '.pdf';
$s3_key = $this->sanitizeFilePart($s3_key);
if ($s3->exists($s3_key)) {
$s3_url = $s3->getPresignedUrl($s3_key);
$pdf_content = file_get_contents($s3_url['url']);
if ($pdf_content !== false) {
file_put_contents($tempPath . $s3_key, $pdf_content);
$pdf_count++;
}
}
}
$hasMore = count($employee_data) == $limit;
$payload = [
'batch_no' => $batch_no + 1,
'last_emp_policy_id' => $current_last_id,
'folder_name' => $folderName,
'processed_in_this_batch_data_count' => count($employee_data),
'pdf_count' => $pdf_count,
'hr_id' => $params['hr_id'] ?? null
];
if ($hasMore) {
$this->myLogger->logme('error', "bulkEcardDownloadAsZipFromS3 - Queuing next batch: " . json_encode($payload));
$r = Jobs::addJob(['job_name' => 'bulkEcardDownloadAsZipFromS3', 'payload' => $payload]);
$message = "Queuing next batch";
} else {
$this->myLogger->logme('error', "bulkEcardDownloadAsZipFromS3 - No more records after this batch. Next proceeding with getEmployeeEcardFromTmpFolderAndZipToS3");
$r = Jobs::addJob(['job_name' => 'getEmployeeEcardFromTmpFolderAndZipToS3', 'payload' => $payload]);
$message = "All batch completed. Next proceeding with getEmployeeEcardFromTmpFolderAndZipToS3";
}
return ['status' => true, 'message' => $message];
} catch (\Throwable $e) {
$mail_response = $this->sendMailToHrWithZipAttachments($params);
$context = [
'error_message' => $e->getMessage(),
'exception_class' => get_class($e),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTraceAsString(),
'mail_response' => $mail_response,
'params' => $params,
];
// Log detailed context for debugging
$this->myLogger->logme('error', 'bulkEcardDownloadAsZipFromS3 - Exception' . json_encode($context, JSON_PRETTY_PRINT));
// Return a detailed, structured error response
return [
'status' => false,
'message' => 'Exception occurred during bulk e-card download and ZIP creation.',
'error' => $context,
];
}
}
public function getEmployeeEcardFromTmpFolderAndZipToS3($params)
{
try {
$zipService = new \App\Libraries\ZipService();
$source = FCPATH . 'tmp/' . $params['folder_name'];
$destination = '/';
$zipName = $params['folder_name'] . '.zip' ?? '';
$result = $zipService->zipAndUploadS3($source, $destination, $zipName);
if($result['status'] === false){
$this->myLogger->logme('error', "getEmployeeEcardFromTmpFolderAndZipToS3 - ZIP creation/upload failed: " . json_encode($result));
$params['url'] = null; // Indicate failure
}else{
$params['url'] = $result['presigned_url']['url'] ?? null;
}
$mail_response = $this->sendMailToHrWithZipAttachments($params);
return ['zip_responce' => $result, 'mail_response' => $mail_response];
} catch (\Throwable $e) {
$mail_response = $this->sendMailToHrWithZipAttachments($params);
$context = [
'error_message' => $e->getMessage(),
'exception_class' => get_class($e),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTraceAsString(),
'mail_response' => $mail_response,
'params' => $params,
];
// Log detailed context for debugging
$this->myLogger->logme('error', 'getEmployeeEcardFromTmpFolderAndZipToS3 - Exception' . json_encode($context, JSON_PRETTY_PRINT));
// Return a detailed, structured error response
return [
'status' => false,
'message' => 'Exception occurred during bulk e-card download and ZIP creation.',
'error' => $context,
];
}
}
public function sendMailToHrWithZipAttachments($params)
{
$hr_id = $params['hr_id'] ?? null;
$url = $params['url'] ?? null;
if (empty($hr_id)) {
$this->myLogger->logme('error', "sendMailToHrWithZipAttachments - No HR ID provided.");
return ['status' => false, 'message' => 'No HR ID provided.'];
}
$hr_data = $this->LevelContactModel->where('id', $hr_id)->where('is_active', 1)->first();
if (empty($hr_data) || empty($hr_data['email'])) {
$this->myLogger->logme('error', "sendMailToHrWithZipAttachments - No valid HR data found for ID: {$hr_id}");
return ['status' => false, 'message' => 'No valid HR data found for ID: ' . $hr_id];
}
if(empty($url)){
$subject = "Employee Bulk E-Card Download Failed";
$message = "Dear {$hr_data['name']},<br><br>We were unable to generate the bulk e-card ZIP file. Please re-initialize the process or contact support to retry.";
}else{
$subject = "Employee Bulk E-Cards Download";
$message = "Dear {$hr_data['name']},<br><br>Please find the employee e-cards attached below.<br><br>Download Link: <a href='{$url}'>Download E-Cards</a><br><br>Note : This link valid for 2 days only.";
}
$bbc = 'venkateshraman786@gmail.com';
$mail_response = MailHelper::send_email([
'mail' => $hr_data['email'],
'subject' => $subject,
'message' => $message,
'bcc' => $bbc,
'common' => [
'mail_type' => 'employee_bulk_ecard_download_by_hr',
]
]);
$this->myLogger->logme('error', "sendMailToHrWithZipAttachments - Email sent to HR ID: {$hr_id}, Email Response: " . json_encode($mail_response));
return $mail_response;
}
public function downloadZip(){
}
}

View File

@ -69,6 +69,8 @@ use Kreait\Firebase\Messaging\CloudMessage;
use Kreait\Firebase\Messaging\Notification;
use Kreait\Firebase\Exception\MessagingException;
use Firebase\JWT\JWT;
class EmployeeRestController extends AdminController
{
@ -2375,6 +2377,7 @@ class EmployeeRestController extends AdminController
$value['membersCountOfActive'] = $activeCount;
$value['membersCountOfInactive'] = $inactiveCount;
$value['is_ecard_bulk_download'] = 0;
$value['is_ecard_bulk_download_for_employee'] = 0;
array_push($result, $value);
@ -2500,11 +2503,12 @@ class EmployeeRestController extends AdminController
$client_id = isset($search_data['client_id']) ? (int) $search_data['client_id'] : 0;
unset($search_data['client_id']);
unset($search_data['client_branch_id']);
$policy_number = isset($search_data['policy_no']) ? $search_data['policy_no'] : null;
$from_date = isset($search_data['from_date']) ? $search_data['from_date'] : null;
$to_date = isset($search_data['to_date']) ? $search_data['to_date'] : null;
$claim_status_id = isset($search_data['claim_status_id']) ? $search_data['claim_status_id'] : null;
unset($search_data['from_date'], $search_data['to_date'], $search_data['claim_status_id']);
unset($search_data['from_date'], $search_data['to_date'], $search_data['claim_status_id'], $search_data['policy_no']);
$where = [];
@ -2624,6 +2628,10 @@ class EmployeeRestController extends AdminController
$builder->whereIn('claim_status_id', $claim_status_ids);
}
if (!empty($policy_number)) {
$builder->where('cp.policy_no', $policy_number);
}
$builder->orderBy('tm.id', 'DESC');
$data = $builder->get()->getResultArray();
@ -4859,7 +4867,8 @@ class EmployeeRestController extends AdminController
THEN hr_file_upload.status
ELSE CONCAT(UCASE(LEFT(f.status, 1)), LCASE(SUBSTRING(f.status, 2)))
END AS status,
'0' as file_error_status
'0' as file_error_status,
'' as file_error_status
", false)
->join('clients c', 'c.id = hr_file_upload.client_id AND c.is_active = 1', 'left')
->join('client_branch cb', 'cb.id = hr_file_upload.client_branch_id AND cb.is_active = 1', 'left')
@ -4906,7 +4915,7 @@ class EmployeeRestController extends AdminController
public function getDataFromHrFilesTable($search_data)
{
$file_download_base = base_url('util/download-file-list/');
$file_download_base = base_url('downloadFileTableFile/');
$builder = $this->fileModel
->select("
files.id,
@ -5429,6 +5438,50 @@ class EmployeeRestController extends AdminController
}
}
public function getHrDashboad()
{
// $dashboard_id = $this->request->getGet('dashboard_id') ?? null;
$client_id = $this->request->getPost('client_id') ?? null;
$client_policy_id = $this->request->getPost('client_policy_id') ?? null;
$received_data = $this->request->getJSON(true) ?? null;
// 🔐 Move this to .env in real projects
$METABASE_SECRET_KEY = '6a9ec3d833576923ea04078188fe26cad17b5de351ab3ce349dd2c2d07b5d0cd';
$payload = [
'resource' => [
// 'dashboard' => 1
'dashboard' => 2
],
'params' => (object)['client_policy_id' => $received_data['client_policy_id']], // MUST be object for Metabase
'exp' => time() + (10 * 60) // 10 minutes
];
$token = JWT::encode($payload, $METABASE_SECRET_KEY, 'HS256');
// // You can either return token only
// return $this->response->setJSON([
// 'token' => $token,
// 'iframe_url' => "https://your-metabase-domain/embed/dashboard/{$token}#bordered=true&titled=true"
// ]);
// if($this->request->getGet('api') == 1)
// {
return $this->respond([
'status' => 'success',
'message' => 'Form data received successfully!',
'data' => [
'metabaseToken' => $token,
'metabaseUrl' => 'https://nsights.nhanceindia.in']
]);
// }
return view('meta_dashboard_demo_one', [
'metabaseToken' => $token,
'metabaseUrl' => 'https://nsights.nhanceindia.in',
]);
}
// get policy files
public function getPolicyAndEndorsementFiles()
{
@ -5455,8 +5508,17 @@ class EmployeeRestController extends AdminController
return $this->respond(['status' => false, 'code' => 404, 'message' => 'No file found', 'data' => []], 200);
}
$policyTransactionModel = new PolicyTransactionModel();
$policy_transaction_data = $policyTransactionModel->where('is_active', 1)->where('policy_no', $client_policy_data['policy_no'])->findAll();
$policyTransactionModel = new PolicyTransactionModel();
$builder = $policyTransactionModel
->where('is_active', 1)
->where('policy_no', $client_policy_data['policy_no'])
->where('action_type', $cd_data['event_name']);
if (!empty($cd_data['endorsement_no']) && $cd_data['event_name'] != 'inception') {
$builder->where('endorsement_no', $cd_data['endorsement_no']);
}
$policy_transaction_data = $builder->findAll();
if(empty($policy_transaction_data)){
$this->myLogger->logme('error', 'getPolicyAndEndorsementFiles: No Policy Transaction data found for policy_no=' . $client_policy_data['policy_no']);
@ -5525,10 +5587,16 @@ class EmployeeRestController extends AdminController
if(empty($employee_data)){
return $this->respond(['status' => false, 'code' => 404, 'message' => 'No employee data found for the policy'], 200);
}
$received_data['folder_name'] = 'bulk_ecards_' . $employee_data[0]['policy_no'] . '_' . date('Y-m-d_H-i-s');
// Dispatch background job to process the bulk e-card download
$r = Jobs::addJob(['job_name' => 'bulkEcardDownloadAsZipFromS3', 'payload' => $received_data]);
$this->myLogger->logme('error', 'bulkEcardDownloadAsZip: Job dispatched with result = ' . json_encode($r ?? []));
return $this->respond(['status' => true, 'code' => 200, 'message' => 'Bulk E-card download process started. Link share your mail'], 200);
}
}

View File

@ -213,6 +213,14 @@ class JobWorker extends AdminController
'bulkGenerateEcardAndStoreinS3' => [
'type' => 'CC', // Handler Category
'handler' => 'App\Controllers\EmployeeController',
],
'bulkEcardDownloadAsZipFromS3' => [
'type' => 'CC', // Handler Category
'handler' => 'App\Controllers\EmployeeController',
],
'getEmployeeEcardFromTmpFolderAndZipToS3' => [
'type' => 'CC', // Handler Category
'handler' => 'App\Controllers\EmployeeController',
]
];

View File

@ -2978,6 +2978,7 @@ class MasterController extends AdminController
'files' => WRITEPATH . 'uploads/commission/files',
'rules' => WRITEPATH . 'uploads/commission/rules',
'claim_sample_forms' => ROOTPATH . 'public/claim_sample_forms/',
'tmp' => ROOTPATH . 'public/tmp/',
'bds_dump_excel' => WRITEPATH . 'uploads/bds_dump_excel/',
'claims_mis' => WRITEPATH . 'uploads/claims_mis/',
];

View File

@ -776,7 +776,7 @@ class RestAuthenticationController extends AdminController
}else {
return $this->respond(['status' => 'failed','code' => 404,'data' => "" , 'message' => 'User not found' ],200);
return $this->respond(['status' => 'failed','code' => 404,'data' => "" , 'message' => 'Invalid OTP' ],200);
}
@ -786,7 +786,7 @@ class RestAuthenticationController extends AdminController
} else {
return $this->respond(['status' => 'failed','code' => 404,'data' => "" , 'message' => 'User not found' ],200);
return $this->respond(['status' => 'failed','code' => 404,'data' => "" , 'message' => 'Invalid OTP' ],200);
}
} catch (\Exception $e) {
return $this->respond(['status' => 'failed','code' => 500,'data' => $e->getMessage()],500);

View File

@ -993,12 +993,13 @@ class TestingController extends BaseController
$payload = [
'resource' => [
'dashboard' => 1
// 'dashboard' => 1
'dashboard' => 2
],
'params' => (object)[], // MUST be object for Metabase
'params' => (object)['client_policy' => 108], // MUST be object for Metabase
'exp' => time() + (10 * 60) // 10 minutes
];
// dd($payload);
$token = JWT::encode($payload, $METABASE_SECRET_KEY, 'HS256');
// // You can either return token only

View File

@ -68,7 +68,7 @@ class DepositHelper
'cd_ac_pk'=> isset($data['cd_ac_pk'])?$data['cd_ac_pk']:null,
'record_date' => $data['record_date'] ?? null,
'policy_transaction_id' => $data['pt_id'] ?? null,
'file_id' => $data['file_id'],
'file_id' => $data['file_id'] ?? null,
];
// Insert data and get the insert ID

View File

@ -86,10 +86,6 @@ class AbhiClaimImportService extends BaseTpaClaimImportService
// Employee / Member details
'member_code' => 'emp_code',
'relation' => 'relationship',
// Policy / Claim identifiers
'policy_number' => 'policy_no',
'abhi_claim_no' => 'claim_number',
// Dates
@ -428,41 +424,31 @@ class AbhiClaimImportService extends BaseTpaClaimImportService
return null;
}
$relation = strtolower($relation);
// trim removes whitespace, strtolower handles case sensitivity
$relation = strtolower(trim($relation));
if (str_contains($relation, 'self')) {
return 'self';
// Mapping specific keywords to standardized outputs
// ORDER MATTERS: Specific phrases (in-law) must come before general ones (father)
$map = [
'father-in-law' => ['father in law', 'father-in-law', 'fil'],
'mother-in-law' => ['mother in law', 'mother-in-law', 'mil'],
'father' => ['father', 'papa', 'dad'],
'mother' => ['mother', 'mom', 'mummy'],
'spouse' => ['spouse', 'wife', 'husband', 'hubby'],
'daughter' => ['daughter', 'daug'],
'son' => ['son'],
'self' => ['self', 'employee', 'main'],
];
foreach ($map as $standard => $keywords) {
foreach ($keywords as $keyword) {
if (str_contains($relation, $keyword)) {
return $standard;
}
}
}
if (str_contains($relation, 'spouse') || str_contains($relation, 'wife') || str_contains($relation, 'husband')) {
return 'spouse';
}
if (str_contains($relation, 'daughter')) {
return 'daughter';
}
if (str_contains($relation, 'son')) {
return 'son';
}
if (str_contains($relation, 'father in law') || str_contains($relation, 'father-in-law')) {
return 'father-in-law';
}
if (str_contains($relation, 'mother in law') || str_contains($relation, 'mother-in-law')) {
return 'mother-in-law';
}
if (str_contains($relation, 'father')) {
return 'father';
}
if (str_contains($relation, 'mother')) {
return 'mother';
}
return null; // unmatched case
return null;
}
}

View File

@ -274,20 +274,6 @@ abstract class BaseTpaClaimImportService
*/
protected function getTpaClaimDumpData(string $table, array $params): array
{
$tpaClaimDumpDataCount = $this->db
->table($table)
->where('is_active', 1)
->where('file_id', $params['file_id'])
->where('ticket_id IS NULL')
->where('master_reject_reason IS NULL')
->countAllResults();
$batch_size = 100;
$total_batch = (int) ceil($tpaClaimDumpDataCount / $batch_size);
$batch_no = isset($params['batch_no']) ? (int) $params['batch_no'] : null;
$last_emp_id = (int) ($params['last_emp_id'] ?? 0);
return $this->db
->table($table)
->where('is_active', 1)
@ -296,7 +282,6 @@ abstract class BaseTpaClaimImportService
->where('master_reject_reason IS NULL')
->get()
->getResultArray();
}
/**
@ -307,10 +292,10 @@ abstract class BaseTpaClaimImportService
$EmployeeModel = new EmployeeModel();
$employeeData = $EmployeeModel
->select([
'employees.id AS emp_id',
'employees.id AS id',
'employees.email_corporate AS emp_mail',
'employees.mobile AS emp_mobile',
'employees.name AS emp_name',
'employees.name AS name',
'employees.emp_code AS emp_code',
// insured employee

View File

@ -141,12 +141,8 @@ class FhplClaimImportService extends BaseTpaClaimImportService
// Claim / Reference
'claim_id' => 'claim_number',
// Policy
'policy_no' => 'policy_no',
// Employee / Member
'employee_id' => 'emp_code',
'relationship' => 'relationship',
// Claim Dates
'admission_date' => 'doa',

View File

@ -81,7 +81,6 @@ class IciciClaimImportService extends BaseTpaClaimImportService
// Employee / Member
'employee_member_id' => 'emp_code',
'relation_group' => 'relationship',
// Claim
'claim_number' => 'claim_number',

View File

@ -116,10 +116,8 @@ class MediAssistClaimImportService extends BaseTpaClaimImportService
// Employee / Beneficiary details
'pribenef_employee_code' => 'emp_code',
'benef_relation' => 'relationship',
// Policy / Claim identifiers
'policy_no' => 'policy_no',
'claim_id' => 'claim_number',
'event_id' => 'tpa_no',
'claim_pre_auths' => 'tpa_claim_push_reference_no',

View File

@ -60,10 +60,8 @@ class RcareClaimImportService extends BaseTpaClaimImportService
// Employee / Member
'employee_member_id' => 'emp_code',
'relation' => 'relationship',
// Policy
'policy_number' => 'policy_no',
'policy_start_date' => 'date_of_incep',
// Claim Dates

View File

@ -314,7 +314,6 @@ class VidalClaimImportService extends BaseTpaClaimImportService
protected $ticketMasterMapping = [
// Policy / Claim identifiers
'insurer_policy_number' => 'policy_no',
'insurer_claim_number' => 'claim_number',
'tpa_claim_number' => 'tpa_claim_id',

View File

@ -0,0 +1,179 @@
<?php
namespace App\Libraries;
use ZipArchive;
class ZipService
{
protected $s3Service;
public function __construct()
{
$this->s3Service = new S3Service();
}
/**
* Zips a local folder and uploads it to S3
*/
public function zipAndUploadS3(string $localFolderPath, string $s3Folder = '', string $zipName = ''): array
{
// dd($localFolderPath, $s3Folder, $zipName);
if (!is_dir($localFolderPath)) {
return ['status' => false, 'message' => 'Local directory does not exist'];
}
// 1. Prepare naming
$folderName = basename($localFolderPath);
$zipName = $zipName ?: $folderName . '_' . time() . '.zip';
$tempZipPath = FCPATH . 'tmp/' . $zipName;
// 2. Create the Local Zip
$zipResult = $this->createLocalZip($localFolderPath, $tempZipPath);
if (!$zipResult['status']) {
return $zipResult;
}
try {
// 3. Upload to S3
$uploadResult = $this->s3Service->upload($tempZipPath, $s3Folder, $zipName);
// dd($uploadResult);
// 4. Cleanup
if (file_exists($tempZipPath)) {
unlink($tempZipPath);
}
$get_presinged_url = $this->s3Service->getPresignedUrl($uploadResult['key'], 2,880);
// To delete the original temprory folder after zipping and uploading
// $this->deleteDirectory($localFolderPath);
return ['status' => true, 'data' => $uploadResult, 'presigned_url' => $get_presinged_url];
} catch (\Exception $e) {
log_message('error', 'Zip/Upload Error: ' . $e->getMessage());
return ['status' => false, 'message' => $e->getMessage()];
}
}
/**
* Zips a local folder using native ZipArchive
*/
public function createLocalZip(string $localFolderPath, string $destinationPath): array
{
// 1. Validate Source Directory
if (!is_dir($localFolderPath)) {
return ['status' => false, 'message' => 'Source directory does not exist'];
}
// 2. Check if folder is empty (ignoring hidden files)
$filesInFolder = array_diff(scandir($localFolderPath), array('.', '..'));
if (empty($filesInFolder)) {
return ['status' => false, 'message' => 'No records found to compress'];
}
// 3. Ensure the destination directory exists and is writable
$destDir = dirname($destinationPath);
if (!is_dir($destDir)) {
mkdir($destDir, 0777, true);
}
$zip = new ZipArchive();
// 4. Open the zip file
$openZip = $zip->open($destinationPath, ZipArchive::CREATE | ZipArchive::OVERWRITE);
if ($openZip !== true) {
return ['status' => false, 'message' => "Could not open Zip. Error code: " . $openZip];
}
try {
$files = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($localFolderPath, \RecursiveDirectoryIterator::SKIP_DOTS),
\RecursiveIteratorIterator::LEAVES_ONLY
);
$fileCount = 0;
$sourcePath = realpath($localFolderPath);
foreach ($files as $file) {
if (!$file->isDir()) {
$filePath = $file->getRealPath();
// Calculate relative path correctly
$relativePath = ltrim(substr($filePath, strlen($sourcePath)), DIRECTORY_SEPARATOR);
// Add to zip
if ($zip->addFile($filePath, $relativePath)) {
$fileCount++;
}
}
}
// 5. Finalize
if ($fileCount > 0) {
if (!$zip->close()) {
return ['status' => false, 'message' => 'Failed to write ZIP file to disk (Check permissions/space)'];
}
} else {
$zip->close();
return ['status' => false, 'message' => 'No files were added to the archive'];
}
return [
'status' => true,
'path' => $destinationPath,
'count' => $fileCount,
'message' => 'Zip created successfully'
];
} catch (\Exception $e) {
// Only attempt to close if the zip object was successfully opened
if (isset($zip->status) && $zip->status !== ZipArchive::ER_OK) {
@$zip->close();
}
log_message('error', 'Local Zip Error: ' . $e->getMessage());
return ['status' => false, 'message' => 'from catch Exception: ' . $e->getMessage()];
}
}
private function deleteDirectory($dir)
{
if (!file_exists($dir)) {
return true;
}
if (!is_dir($dir)) {
// Use @ to suppress warnings if the file is already gone or locked
// return @unlink($dir);
return unlink($dir);
}
// scandir can return false if the directory isn't readable
$items = scandir($dir);
if ($items === false) {
return false;
}
foreach ($items as $item) {
if ($item == '.' || $item == '..') {
continue;
}
// Recursively call the function
if (!$this->deleteDirectory($dir . DIRECTORY_SEPARATOR . $item)) {
// If a child cannot be deleted, attempt to change its permissions and try once more
@chmod($dir . DIRECTORY_SEPARATOR . $item, 0777);
if (!$this->deleteDirectory($dir . DIRECTORY_SEPARATOR . $item)) {
return false;
}
}
}
// Finally, remove the empty directory
return @rmdir($dir);
}
}

View File

@ -399,8 +399,8 @@ class EmployeePolicyModel extends Model
->where('is_active',1)
->find();
}
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
public function getInceptionEmployeeDataForExportExcel($ref_data, $return_type = 0)
{
@ -2226,5 +2226,70 @@ class EmployeePolicyModel extends Model
// return $result;
}
// for this function using bulk e-card download as a zip
public function getEmployeeDataWithPolicyUsingClientPolicyIdOrEmployeePolicyIds($params, $limit = 100, $last_id = 0)
{
$client_policy_id = $params['client_policy_id'] ?? null;
$emp_policy_ids = $params['emp_policy_ids'] ?? null;
if (empty($client_policy_id) && empty($emp_policy_ids)) {
return [];
}
$builder = $this->db->table('employee_polices');
$builder->select('
employee_polices.id as emp_policy_id,
employee_polices.client_policy_id,
employees.name,
employees.emp_code,
employees.id as emp_id,
tpa.short_name,
employee_polices.tpa_id,
client_policy.policy_no
')
->join('client_policy', 'client_policy.id = employee_polices.client_policy_id')
->join('employees', 'employees.id = employee_polices.employee_id')
->join('tpa', 'tpa.id = client_policy.tpa_id')
->where([
'employees.emp_status' => 'active',
'employees.is_active' => '1',
'employee_polices.status' => 'active',
'employee_polices.is_active' => '1',
])
->where("employee_polices.tpa_id IS NOT NULL AND employee_polices.tpa_id <> ''");
// BATCHING LOGIC: Only get records greater than the last processed ID
if ($last_id > 0) {
$builder->where('employee_polices.id >', $last_id);
}
if ($client_policy_id) $builder->where('employee_polices.client_policy_id', $client_policy_id);
if ($emp_policy_ids) $builder->whereIn('employee_polices.id', $emp_policy_ids);
$builder->orderBy('employee_polices.id', 'ASC'); // Critical for keyset pagination
$builder->limit($limit);
return $builder->get()->getResultArray();
}
public function getClientPolicyDetailsByClientPolicyIdOrEmployeePolicyId($params)
{
$client_policy_id = $params['client_policy_id'] ?? null;
$emp_policy_id = $params['emp_policy_id'] ?? null;
if (empty($client_policy_id) && empty($emp_policy_id)) {
return [];
}
$builder = $this->db->table('client_policy');
$builder->select('client_policy.*')
->join('employee_polices ep', 'ep.client_policy_id = client_policy.id', 'left');
if ($client_policy_id) $builder->where('employee_polices.client_policy_id', $client_policy_id);
if ($emp_policy_id) $builder->where('employee_polices.id', $emp_policy_id);
return $builder->get()->getResultArray();
}
}

View File

@ -93,6 +93,7 @@ class TicketMasterModel extends Model
'required_docs',
'policy_transaction_id',
'tpa_claim_type',
'claim_dump_ref_id',
];