diff --git a/app/Config/Constants.php b/app/Config/Constants.php index 68a7209a..b9691662 100755 --- a/app/Config/Constants.php +++ b/app/Config/Constants.php @@ -134,3 +134,4 @@ define('UPLOAD_EXT_MAIL_ATTACHMENTS', ['pdf', 'jpg', 'jpeg', 'png', 'doc', 'docx define('UPLOAD_EXT_NON_EB_RACK_RATE', ['pdf', 'xls', 'xlsx']); define('UPLOAD_EXT_ASSET_FILES', ['pdf', 'xls', 'xlsx', 'csv']); define('UPLOAD_EXT_INSURER_CLAIM_FORM', ['pdf', 'doc', 'docx']); +define('INSURER_DEFAULT_CLAIM_FORM_FILE', 'Claim_Form_IRDAI.pdf'); diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 630da754..e18e3df7 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -466,6 +466,7 @@ $routes->group("/util", ["filter" => "authMVC"], function ($routes) { $routes->get('listEmployeeCountByClientPolicy', 'TestingController::listEmployeeCountByClientPolicy'); $routes->get('testMediAssistWellness','TestingController::testMediAssistWellness'); $routes->match(['get', 'post'], 'decryptVisitSso', 'ApiServiceController::decryptVisitSso'); // disabled for now do not remove this + $routes->get("getInsurerClaimFormDownloadUrl", "EmployeeRestController::getInsurerClaimFormDownloadUrl"); $routes->group('claims-collection-v2', static function ($routes) { $routes->get('preview', 'ClaimsCollectionV2DashboardController::preview'); @@ -752,6 +753,7 @@ $routes->group("employeeRest", ["filter" => ['GlobalPostFileUploadGuard', 'ratel $routes->get("cdTransactionData", "EmployeeRestController::cdTransactionData"); $routes->match( ['get', 'post'], 'claimsSearch','EmployeeRestController::claimsSearch'); $routes->get("claimView", "EmployeeRestController::claimView"); + $routes->get("getInsurerClaimFormDownloadUrl", "EmployeeRestController::getInsurerClaimFormDownloadUrl"); $routes->get("exportCashDepositData", "EmployeeRestController::exportCashDepositData"); $routes->get("hrFileList", "EmployeeRestController::hrFileList"); $routes->get("hrFileUploadMasters", "EmployeeRestController::hrFileUploadMasters"); diff --git a/app/Controllers/EmployeeRestController.php b/app/Controllers/EmployeeRestController.php index cc4767dc..dd4a261c 100755 --- a/app/Controllers/EmployeeRestController.php +++ b/app/Controllers/EmployeeRestController.php @@ -5941,4 +5941,196 @@ class EmployeeRestController extends AdminController return $this->respond(['status' => false, 'code' => 404, 'message' => 'Failed to sent mail.', 'result' => $result], 200); } + public function getInsurerClaimFormDownloadUrl() + { + $clientPolicyId = trim((string) ($this->request->getGet('client_policy_id') ?? '')); + + if ($clientPolicyId === '') { + $errorContext = [ + 'api' => 'getInsurerClaimFormDownloadUrl', + 'error' => 'client_policy_id is required', + 'client_policy_id' => null, + 'request_uri' => (string) current_url(), + 'request_method' => $this->request->getMethod(), + ]; + log_message('error', '[getInsurerClaimFormDownloadUrl] Missing required parameter | ' . json_encode($errorContext)); + $this->myLogger->logme('error', '[getInsurerClaimFormDownloadUrl] Missing required parameter | ' . json_encode($errorContext)); + + return $this->respond([ + 'status' => false, + 'code' => 400, + 'message' => 'client_policy_id is required', + 'data' => [], + ], 200); + } + + if (! ctype_digit($clientPolicyId) || (int) $clientPolicyId <= 0) { + $errorContext = [ + 'api' => 'getInsurerClaimFormDownloadUrl', + 'error' => 'Invalid client_policy_id', + 'client_policy_id' => $clientPolicyId, + 'request_uri' => (string) current_url(), + ]; + log_message('error', '[getInsurerClaimFormDownloadUrl] Invalid client_policy_id | ' . json_encode($errorContext)); + $this->myLogger->logme('error', '[getInsurerClaimFormDownloadUrl] Invalid client_policy_id | ' . json_encode($errorContext)); + + return $this->respond([ + 'status' => false, + 'code' => 400, + 'message' => 'client_policy_id must be a valid positive number', + 'data' => [], + ], 200); + } + + try { + $clientPolicy = $this->clientPolicyModel + ->select('client_policy.id, client_policy.insurer_id, client_policy.policy_no, client_policy.is_active, insurers.id as insurer_pk, insurers.name as insurer_name, insurers.short_name as insurer_short_name, insurers.is_active as insurer_is_active, insurers.insurer_claim_form, insurers.insurer_claim_form_original_name') + ->join('insurers', 'insurers.id = client_policy.insurer_id', 'left') + ->where('client_policy.id', (int) $clientPolicyId) + ->first(); + + if (empty($clientPolicy)) { + $errorContext = [ + 'api' => 'getInsurerClaimFormDownloadUrl', + 'error' => 'Client policy not found', + 'client_policy_id' => (int) $clientPolicyId, + 'request_uri' => (string) current_url(), + ]; + log_message('error', '[getInsurerClaimFormDownloadUrl] Client policy not found | ' . json_encode($errorContext)); + $this->myLogger->logme('error', '[getInsurerClaimFormDownloadUrl] Client policy not found | ' . json_encode($errorContext)); + + return $this->respond([ + 'status' => false, + 'code' => 404, + 'message' => 'Client policy not found for the given client_policy_id', + 'data' => [], + ], 200); + } + + if ((int) ($clientPolicy['is_active'] ?? 0) !== 1) { + $errorContext = [ + 'api' => 'getInsurerClaimFormDownloadUrl', + 'error' => 'Client policy is inactive', + 'client_policy_id' => (int) $clientPolicyId, + 'policy_no' => $clientPolicy['policy_no'] ?? null, + ]; + log_message('error', '[getInsurerClaimFormDownloadUrl] Inactive client policy | ' . json_encode($errorContext)); + $this->myLogger->logme('error', '[getInsurerClaimFormDownloadUrl] Inactive client policy | ' . json_encode($errorContext)); + + return $this->respond([ + 'status' => false, + 'code' => 404, + 'message' => 'Client policy is inactive', + 'data' => [], + ], 200); + } + + if (empty($clientPolicy['insurer_id'])) { + $errorContext = [ + 'api' => 'getInsurerClaimFormDownloadUrl', + 'error' => 'Insurer is not mapped to client policy', + 'client_policy_id' => (int) $clientPolicyId, + 'policy_no' => $clientPolicy['policy_no'] ?? null, + ]; + log_message('error', '[getInsurerClaimFormDownloadUrl] Insurer not mapped | ' . json_encode($errorContext)); + $this->myLogger->logme('error', '[getInsurerClaimFormDownloadUrl] Insurer not mapped | ' . json_encode($errorContext)); + + return $this->respond([ + 'status' => false, + 'code' => 404, + 'message' => 'Insurer is not mapped to this client policy', + 'data' => [], + ], 200); + } + + if ((int) ($clientPolicy['insurer_is_active'] ?? 0) !== 1) { + $errorContext = [ + 'api' => 'getInsurerClaimFormDownloadUrl', + 'error' => 'Insurer is inactive', + 'client_policy_id' => (int) $clientPolicyId, + 'insurer_id' => (int) $clientPolicy['insurer_id'], + 'insurer_name' => $clientPolicy['insurer_name'] ?? null, + ]; + log_message('error', '[getInsurerClaimFormDownloadUrl] Inactive insurer | ' . json_encode($errorContext)); + $this->myLogger->logme('error', '[getInsurerClaimFormDownloadUrl] Inactive insurer | ' . json_encode($errorContext)); + + return $this->respond([ + 'status' => false, + 'code' => 404, + 'message' => 'Insurer is inactive for this client policy', + 'data' => [], + ], 200); + } + + $insurerData = [ + 'id' => $clientPolicy['insurer_id'], + 'name' => $clientPolicy['insurer_name'] ?? '', + 'short_name' => $clientPolicy['insurer_short_name'] ?? '', + 'insurer_claim_form' => $clientPolicy['insurer_claim_form'] ?? null, + 'insurer_claim_form_original_name'=> $clientPolicy['insurer_claim_form_original_name'] ?? null, + ]; + + $claimFormAvailability = resolve_insurer_claim_form_file($insurerData); + + if (empty($claimFormAvailability['available'])) { + $errorContext = [ + 'api' => 'getInsurerClaimFormDownloadUrl', + 'error' => 'Insurer claim form file not found', + 'client_policy_id' => (int) $clientPolicyId, + 'insurer_id' => (int) $clientPolicy['insurer_id'], + 'insurer_name' => $clientPolicy['insurer_name'] ?? null, + 'insurer_short_name' => $clientPolicy['insurer_short_name'] ?? null, + 'stored_claim_form' => $clientPolicy['insurer_claim_form'] ?? null, + 'checked_paths' => $claimFormAvailability['checked_paths'] ?? [], + ]; + log_message('error', '[getInsurerClaimFormDownloadUrl] Claim form file not found | ' . json_encode($errorContext)); + $this->myLogger->logme('error', '[getInsurerClaimFormDownloadUrl] Claim form file not found | ' . json_encode($errorContext)); + + return $this->respond([ + 'status' => false, + 'code' => 404, + 'message' => 'Insurer claim form is not available for this client policy', + 'data' => [], + ], 200); + } + + $downloadUrl = base_url('claim-form-download/' . md5((string) $clientPolicy['insurer_id'])); + + log_message('info', '[getInsurerClaimFormDownloadUrl] Success | ' . json_encode([ + 'client_policy_id' => (int) $clientPolicyId, + 'insurer_id' => (int) $clientPolicy['insurer_id'], + 'file_source' => $claimFormAvailability['source'], + 'file_name' => $claimFormAvailability['file_name'], + 'download_url' => $downloadUrl, + ])); + + return $this->respond([ + 'status' => true, + 'code' => 200, + 'message' => 'Insurer claim form download URL fetched successfully', + 'data' => [ + 'download_url' => $downloadUrl, + ], + ], 200); + } catch (\Throwable $th) { + $errorContext = [ + 'api' => 'getInsurerClaimFormDownloadUrl', + 'error' => $th->getMessage(), + 'client_policy_id' => $clientPolicyId, + 'file' => $th->getFile(), + 'line' => $th->getLine(), + 'trace' => $th->getTraceAsString(), + ]; + log_message('error', '[getInsurerClaimFormDownloadUrl] Exception | ' . json_encode($errorContext)); + $this->myLogger->logme('error', '[getInsurerClaimFormDownloadUrl] Exception | ' . json_encode($errorContext)); + + return $this->respond([ + 'status' => false, + 'code' => 500, + 'message' => 'Unable to fetch insurer claim form download URL. Please try again later.', + 'data' => [], + ], 200); + } + } + } diff --git a/app/Controllers/MasterController.php b/app/Controllers/MasterController.php index 694d011b..32e868e3 100755 --- a/app/Controllers/MasterController.php +++ b/app/Controllers/MasterController.php @@ -670,21 +670,18 @@ class MasterController extends AdminController { $insurer = $this->insurerModel->where(['id' => (int) $id, 'is_active' => 1])->first(); - if (empty($insurer) || empty($insurer['insurer_claim_form'])) { + if (empty($insurer)) { throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound('Claim form file not found'); } - $storedFileName = basename($insurer['insurer_claim_form']); - $downloadFileName = !empty($insurer['insurer_claim_form_original_name']) - ? basename($insurer['insurer_claim_form_original_name']) - : $storedFileName; - $filePath = WRITEPATH . 'insurer_claim_form/' . $storedFileName; + $claimFormFile = resolve_insurer_claim_form_file($insurer); - if (!is_file($filePath)) { + if (empty($claimFormFile['available']) || empty($claimFormFile['file_path'])) { throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound('Claim form file not found'); } - return $this->response->download($filePath, null)->setFileName($downloadFileName); + return $this->response->download($claimFormFile['file_path'], null) + ->setFileName($claimFormFile['file_name']); } public function editInsurerGet($id = null) diff --git a/app/Controllers/TicketController.php b/app/Controllers/TicketController.php index 7b708c07..0e1b76a2 100644 --- a/app/Controllers/TicketController.php +++ b/app/Controllers/TicketController.php @@ -3415,28 +3415,16 @@ class TicketController extends BaseController return; } - if (!empty($insurer_data['insurer_claim_form'])) { - $storedFileName = basename($insurer_data['insurer_claim_form']); - $downloadFileName = !empty($insurer_data['insurer_claim_form_original_name']) - ? basename($insurer_data['insurer_claim_form_original_name']) - : $storedFileName; - $filePath = WRITEPATH . 'insurer_claim_form/' . $storedFileName; - - if (is_file($filePath)) { - return $this->response->download($filePath, null)->setFileName($downloadFileName); - } - } - - $fileName = $insurer_data['short_name'] . '.pdf'; - $filePath = ROOTPATH . 'public/claim_sample_forms/' . $fileName; + $claimFormFile = resolve_insurer_claim_form_file($insurer_data); try { - if (file_exists($filePath)) { - return $this->response->download($filePath, null); - } else { - $data['message'] = 'The Physical File Not Found'; - echo view('errors/404', $data); + if (!empty($claimFormFile['available']) && !empty($claimFormFile['file_path'])) { + return $this->response->download($claimFormFile['file_path'], null) + ->setFileName($claimFormFile['file_name']); } + + $data['message'] = 'The Physical File Not Found'; + echo view('errors/404', $data); } catch (\Exception $e) { $this->myLogger->logme('error', $e->getMessage()); return $this->response->setStatusCode(500)->setBody('An error occurred while downloading the file.'); diff --git a/app/Helpers/utility_helper.php b/app/Helpers/utility_helper.php index b8343762..00955f17 100755 --- a/app/Helpers/utility_helper.php +++ b/app/Helpers/utility_helper.php @@ -123,6 +123,68 @@ if (! function_exists('file_Upload_random_name')) { } } +if (! function_exists('resolve_insurer_claim_form_file')) { + function resolve_insurer_claim_form_file(array $insurer): array + { + $checkedPaths = []; + $claimFormDir = WRITEPATH . 'insurer_claim_form/'; + + if (!empty($insurer['insurer_claim_form'])) { + $storedFileName = basename($insurer['insurer_claim_form']); + $uploadedPath = $claimFormDir . $storedFileName; + $checkedPaths[] = $uploadedPath; + + if (is_file($uploadedPath)) { + return [ + 'available' => true, + 'file_path' => $uploadedPath, + 'file_name' => !empty($insurer['insurer_claim_form_original_name']) + ? basename($insurer['insurer_claim_form_original_name']) + : $storedFileName, + 'source' => 'uploaded', + 'checked_paths' => $checkedPaths, + ]; + } + } + + $defaultPath = $claimFormDir . INSURER_DEFAULT_CLAIM_FORM_FILE; + $checkedPaths[] = $defaultPath; + + if (is_file($defaultPath)) { + return [ + 'available' => true, + 'file_path' => $defaultPath, + 'file_name' => INSURER_DEFAULT_CLAIM_FORM_FILE, + 'source' => 'irdai_default', + 'checked_paths' => $checkedPaths, + ]; + } + + if (!empty($insurer['short_name'])) { + $legacyPath = ROOTPATH . 'public/claim_sample_forms/' . $insurer['short_name'] . '.pdf'; + $checkedPaths[] = $legacyPath; + + if (is_file($legacyPath)) { + return [ + 'available' => true, + 'file_path' => $legacyPath, + 'file_name' => $insurer['short_name'] . '.pdf', + 'source' => 'legacy', + 'checked_paths' => $checkedPaths, + ]; + } + } + + return [ + 'available' => false, + 'file_path' => null, + 'file_name' => null, + 'source' => null, + 'checked_paths' => $checkedPaths, + ]; + } +} + if (! function_exists('file_Upload_for_lead')) { function file_Upload_for_lead($fileToUpload, $filepath, array $allowedExtensions = UPLOAD_ALLOWED_EXTENSIONS) { diff --git a/app/Views/insurer_basic_info.php b/app/Views/insurer_basic_info.php index 47dadb1a..5e010955 100755 --- a/app/Views/insurer_basic_info.php +++ b/app/Views/insurer_basic_info.php @@ -202,13 +202,19 @@ input:checked + .slider:before {
- Allowed: PDF, DOC, DOCX. Max size: 5MB. - + Allowed: PDF, DOC, DOCX. Max size: 5MB. If no insurer form is uploaded, will be used. +
Download Claim Form - + + +
diff --git a/tests/smoke_get_insurer_claim_form_download_url.php b/tests/smoke_get_insurer_claim_form_download_url.php new file mode 100644 index 00000000..ac7b5a5d --- /dev/null +++ b/tests/smoke_get_insurer_claim_form_download_url.php @@ -0,0 +1,185 @@ +systemDirectory, '\\/ ') . DIRECTORY_SEPARATOR . 'bootstrap.php'; +require_once SYSTEMPATH . 'Config/DotEnv.php'; +(new CodeIgniter\Config\DotEnv(ROOTPATH))->load(); + +defined('ENVIRONMENT') || define('ENVIRONMENT', env('CI_ENVIRONMENT', 'development')); + +$boot = APPPATH . 'Config/Boot/' . ENVIRONMENT . '.php'; +if (is_file($boot)) { + require_once $boot; +} + +use App\Controllers\EmployeeRestController; +use CodeIgniter\HTTP\IncomingRequest; +use CodeIgniter\HTTP\URI; +use Config\Services; + +$pass = 0; +$fail = 0; +$results = []; + +function ok(string $label, bool $cond, string $detail = ''): void +{ + global $pass, $fail, $results; + if ($cond) { + $pass++; + $results[] = '[PASS] ' . $label . ($detail ? " — {$detail}" : ''); + } else { + $fail++; + $results[] = '[FAIL] ' . $label . ($detail ? " — {$detail}" : ''); + } +} + +function invokeApi(EmployeeRestController $controller, array $query): array +{ + $uri = new URI('http://localhost/nhance_v2/employeeRest/getInsurerClaimFormDownloadUrl'); + if ($query !== []) { + $uri->setQuery(http_build_query($query)); + } + + $request = new IncomingRequest( + config('App'), + $uri, + null, + new \CodeIgniter\HTTP\UserAgent() + ); + $request->setGlobal('get', $query); + + $response = Services::response(); + $logger = Services::logger(); + $controller->initController($request, $response, $logger); + + $response = $controller->getInsurerClaimFormDownloadUrl(); + $body = json_decode($response->getBody(), true); + + return is_array($body) ? $body : []; +} + +$db = db_connect('default'); +$controller = new EmployeeRestController(); + +$legacyPolicy = $db->query( + "SELECT cp.id AS client_policy_id, i.short_name + FROM client_policy cp + JOIN insurers i ON i.id = cp.insurer_id + WHERE cp.is_active = 1 + AND i.is_active = 1 + AND i.short_name = 'ICICIPRU' + LIMIT 1" +)->getRowArray(); + +$uploadedPolicy = $db->query( + "SELECT cp.id AS client_policy_id, i.short_name, i.insurer_claim_form + FROM client_policy cp + JOIN insurers i ON i.id = cp.insurer_id + WHERE cp.is_active = 1 + AND i.is_active = 1 + AND i.insurer_claim_form IS NOT NULL + AND i.insurer_claim_form <> '' + LIMIT 1" +)->getRowArray(); + +$inactivePolicy = $db->query( + 'SELECT id AS client_policy_id FROM client_policy WHERE is_active = 0 LIMIT 1' +)->getRowArray(); + +$missingParam = invokeApi($controller, []); +ok('Missing client_policy_id returns 400', ($missingParam['code'] ?? null) === 400, json_encode($missingParam)); + +$invalidParam = invokeApi($controller, ['client_policy_id' => 'abc']); +ok('Invalid client_policy_id returns 400', ($invalidParam['code'] ?? null) === 400, json_encode($invalidParam)); + +$notFound = invokeApi($controller, ['client_policy_id' => '999999999']); +ok('Unknown client_policy_id returns 404', ($notFound['code'] ?? null) === 404, json_encode($notFound)); + +if (!empty($inactivePolicy['client_policy_id'])) { + $inactive = invokeApi($controller, ['client_policy_id' => (string) $inactivePolicy['client_policy_id']]); + ok('Inactive client policy returns 404', ($inactive['code'] ?? null) === 404, json_encode($inactive)); +} + +if (!empty($legacyPolicy['client_policy_id'])) { + $legacyPath = ROOTPATH . 'public/claim_sample_forms/' . $legacyPolicy['short_name'] . '.pdf'; + $legacy = invokeApi($controller, ['client_policy_id' => (string) $legacyPolicy['client_policy_id']]); + $legacyResolved = resolve_insurer_claim_form_file(['short_name' => $legacyPolicy['short_name']]); + ok( + 'No uploaded form falls back to IRDAI default (ICICIPRU policy)', + ($legacy['status'] ?? false) === true + && ($legacy['code'] ?? null) === 200 + && !empty($legacy['data']['download_url']) + && count($legacy['data']) === 1 + && ($legacyResolved['source'] ?? '') === 'irdai_default', + 'legacy_file_exists=' . (is_file($legacyPath) ? 'yes' : 'no') . ' | ' . json_encode($legacy) + ); +} + +$irdaiDefaultPolicy = $db->query( + "SELECT cp.id AS client_policy_id, i.short_name + FROM client_policy cp + JOIN insurers i ON i.id = cp.insurer_id + WHERE cp.is_active = 1 + AND i.is_active = 1 + AND (i.insurer_claim_form IS NULL OR i.insurer_claim_form = '') + AND i.short_name NOT IN ('ICICIPRU', 'DIGITLIF', 'MAXLIFE', 'NIA', 'OIC', 'PIFL', 'RELIANCE') + LIMIT 1" +)->getRowArray(); + +if (!empty($irdaiDefaultPolicy['client_policy_id'])) { + $irdai = invokeApi($controller, ['client_policy_id' => (string) $irdaiDefaultPolicy['client_policy_id']]); + $irdaiResolved = resolve_insurer_claim_form_file(['short_name' => $irdaiDefaultPolicy['short_name']]); + ok( + 'IRDAI default claim form fallback', + ($irdai['status'] ?? false) === true + && ($irdai['code'] ?? null) === 200 + && !empty($irdai['data']['download_url']) + && count($irdai['data']) === 1 + && ($irdaiResolved['source'] ?? '') === 'irdai_default', + json_encode($irdai) + ); +} + +if (!empty($uploadedPolicy['client_policy_id'])) { + $uploadedPath = WRITEPATH . 'insurer_claim_form/' . basename((string) $uploadedPolicy['insurer_claim_form']); + $uploaded = invokeApi($controller, ['client_policy_id' => (string) $uploadedPolicy['client_policy_id']]); + $uploadedResolved = resolve_insurer_claim_form_file([ + 'insurer_claim_form' => $uploadedPolicy['insurer_claim_form'], + 'short_name' => $uploadedPolicy['short_name'] ?? '', + ]); + ok( + 'Uploaded claim form success', + ($uploaded['status'] ?? false) === true + && ($uploaded['code'] ?? null) === 200 + && !empty($uploaded['data']['download_url']) + && count($uploaded['data']) === 1 + && ($uploadedResolved['source'] ?? '') === 'uploaded', + 'file_exists=' . (is_file($uploadedPath) ? 'yes' : 'no') . ' | ' . json_encode($uploaded) + ); +} + +$cliPolicyId = $argv[1] ?? ($legacyPolicy['client_policy_id'] ?? null); +if ($cliPolicyId) { + $manual = invokeApi($controller, ['client_policy_id' => (string) $cliPolicyId]); + echo "\nManual test client_policy_id={$cliPolicyId}\n"; + echo json_encode($manual, JSON_PRETTY_PRINT) . "\n"; +} + +echo "\nSmoke test summary: {$pass} passed, {$fail} failed\n"; +foreach ($results as $line) { + echo $line . "\n"; +} + +exit($fail > 0 ? 1 : 0);