diff --git a/app/Controllers/HealthindiaapiController.php b/app/Controllers/HealthindiaapiController.php new file mode 100644 index 00000000..253c97b3 --- /dev/null +++ b/app/Controllers/HealthindiaapiController.php @@ -0,0 +1,751 @@ +db = \Config\Database::connect(); + $this->healthIndiaTpaId = getenv('HEALTH_INDIA_PRIMARY_KEY_CONSTANT'); + } + + public function generateAuthToken() + { + $url = getenv('HEALTH_INDIA_TOKEN_URL'); // https://software.healthindiatpa.com/HIITPABROKERAPI/JWT/GenerateJWTAuth + + // Basic Authentication credentials + $username = getenv('HEALTH_INDIA_USERNAME'); // /MU4gwfBYC71M1QnczasegH0vPM5IMbESO4iy4wbUrQ= + $password = getenv('HEALTH_INDIA_PASSWORD'); // KoVi+w2WGA+ET6fHN3kdBamHNsDKbA+kUtuF++4jWcg= + + $ch = curl_init(); + + curl_setopt_array($ch, [ + CURLOPT_URL => $url, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_HTTPHEADER => [ + 'Authorization: Basic ' . base64_encode($username . ':' . $password), + 'Content-Type: application/json', + ], + CURLOPT_TIMEOUT => 30, + ]); + + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + + if (curl_errno($ch)) { + log_message('error', 'HEALTH_INDIA TOKEN GENERATION FAILED | Error: ' . curl_error($ch)); + curl_close($ch); + return $this->response->setJSON([ + 'status' => false, + 'error' => curl_error($ch), + ]); + } + + curl_close($ch); + + $responseData = json_decode($response, true); + + if ($httpCode === 200 && isset($responseData['status']) && $responseData['status'] === true) { + log_message('error', 'HEALTH_INDIA TOKEN GENERATION SUCCESS | Token: ' . ($responseData['result'][0]['access_token'] ?? 'N/A')); + } else { + log_message('error', 'HEALTH_INDIA TOKEN GENERATION FAILED | Response: ' . $response); + } + + return $this->response->setJSON([ + 'status' => $httpCode === 200, + 'http_code' => $httpCode, + 'data' => $responseData, + ]); + } + + public function SubmitClaim($claimId = null) + { + helper('api'); + + log_message('error', 'TPA CLAIM PUSH HEALTH_INDIA | Started for claimId: ' . $claimId); + + $data = $this->db->table('ticket_master tm') + ->select(' + tm.id, + tm.emp_mobile as mobileNo, + tm.emp_mail as emailId, + tm.doa as admissionDate, + tm.dod as dischargeDate, + tm.hospital_name as hospitalName, + tm.claim_amount as claimedAmount, + tm.tpa_no as memberId, + tm.ailment as ailmentDescription, + cp.policy_no as policyNumber, + e.emp_code as employeeCode, + tn.note as disease, + cf.url as filePath, + tm.claim_type as claimType, + tm.claim_category as benefitType + ') + ->join('employees e', 'e.id = tm.emp_id', 'left') + ->join('client_policy cp', 'tm.client_policy_id = cp.id', 'left') + ->join('ticket_notes tn', 'tn.ticket_id = tm.id', 'left') + ->join('claim_files cf', "cf.ticket_id = tm.id AND cf.file_type = 2 AND cf.mime_type='application/pdf'", 'left') + ->where('tm.id', $claimId) + ->get() + ->getRowArray(); + + if (!$data) { + log_message('error', "TPA CLAIM PUSH FAILED HEALTH_INDIA | claimId: {$claimId} - Claim not found"); + return; + } + + if ($data['filePath'] == null) { + log_message('error', "TPA CLAIM PUSH FAILED HEALTH_INDIA | claimId: {$claimId} - File Missing"); + return; + } + + // Build absolute file path + $filename = basename($data['filePath']); + $pdfPath = WRITEPATH . 'uploads/claim_files/' . $filename; + + if (!file_exists($pdfPath)) { + log_message('error', "TPA CLAIM PUSH FAILED HEALTH_INDIA | claimId: {$claimId} - PDF not found on server at path: {$pdfPath}"); + return; + } + + // Convert PDF to Base64 + $fileContent = base64_encode(file_get_contents($pdfPath)); + + // Generate Health India Token + $tokenResponse = json_decode($this->generateAuthToken()->getBody(), true); + if (empty($tokenResponse['data']['result'][0]['access_token'])) { + log_message('error', "TPA CLAIM PUSH FAILED HEALTH_INDIA | claimId: {$claimId} - Token generation failed"); + return; + } + $token = $tokenResponse['data']['result'][0]['access_token']; + + // Map claim type: Reimbursement or Cashless + $claimTypeMap = [ + 'reimbursement' => 'Reimbursement', + 'cashless' => 'Cashless', + ]; + $mappedClaimType = $claimTypeMap[strtolower($data['claimType'] ?? 'reimbursement')] ?? 'Reimbursement'; + + // Map benefit type: IPD or OPD + $benefitTypeMap = [ + 'ipd' => 'IPD', + 'opd' => 'OPD', + ]; + $mappedBenefitType = $benefitTypeMap[strtolower($data['benefitType'] ?? 'ipd')] ?? 'IPD'; + + // Build Health India Claim Submission Request (API Section 5) + $body = [ + "policY_NUMBER" => $data['policyNumber'], + "employeE_CODE" => $data['employeeCode'], + "membeR_ID" => $data['memberId'], + "claiM_TYPE" => $mappedClaimType, + "benefiT_TYPE" => $mappedBenefitType, + "claimeD_AMOUNT" => (string) $data['claimedAmount'], + "datE_OF_ADMISSION" => date('Y-m-d', strtotime($data['admissionDate'])), + "ailmenT_DESCRIPTION" => $data['ailmentDescription'] ?? 'NA', + "hospitaL_CODE" => "", // Not available in your data + "hospitaL_NAME" => $data['hospitalName'] ?? '', + "hospitaL_ADDRESS" => "", // Not available + "hospitaL_NUMBER" => "", // Not available + "pdF_BYTES" => [$fileContent] + ]; + + $url = getenv('HEALTH_INDIA_BASE_URL') . "/Intimation/GetClaimIntimation"; + + $headers = [ + "Authorization: Bearer " . $token, + "Content-Type: application/json" + ]; + + log_message('error', 'TPA CLAIM PUSH HEALTH_INDIA | claimId: ' . $claimId . ' | URL: ' . $url . ' | payload: ' . json_encode($body)); + + $response = call_third_party_api($url, 'POST', $headers, $body); + + log_message('error', 'TPA CLAIM PUSH HEALTH_INDIA RESPONSE | claimId: ' . $claimId . ' | response: ' . json_encode($response)); + + if ($response['status'] != true) { + log_message('error', 'TPA CLAIM PUSH FAILED HEALTH_INDIA | claimId: ' . $claimId . ' | response: ' . json_encode($response)); + $this->db->table('ticket_master') + ->where('id', $claimId) + ->update(['tpa_push_response' => json_encode($response)]); + return; + } + + if ($response['status'] === true && !empty($response['data']['result'][0]['ccn'])) { + $ccn = $response['data']['result'][0]['ccn']; + $ccnExt = $response['data']['result'][0]['ccN_EXT'] ?? '0'; + + $this->db->table('ticket_master') + ->where('id', $claimId) + ->update([ + 'claim_number' => $ccn, + 'tpa_claim_id' => $ccn, + 'tpa_claim_push_reference_no' => $ccn . '(' . $ccnExt . ')', + 'updated_at' => date('Y-m-d H:i:s') + ]); + + log_message('error', 'TPA CLAIM PUSH SUCCESS HEALTH_INDIA | claimId: ' . $claimId . ' | CCN: ' . $ccn . ' | CCN_EXT: ' . $ccnExt); + } else { + log_message('error', 'TPA CLAIM PUSH HEALTH_INDIA API SUCCESS BUT CCN EMPTY | claimId: ' . $claimId . ' | response: ' . json_encode($response)); + return; + } + + return; + } + + public function ClaimDetail($claimId = null) + { + helper('api'); + + log_message('error', 'CLAIM STATUS HEALTH_INDIA | Started for claimId: ' . $claimId); + + $ticket = $this->db->table('ticket_master tm') + ->select("tm.id, tm.tpa_claim_id as ccn, cp.policy_no, cp.policy_start_date, cp.policy_end_date, tm.emp_code") + ->join('client_policy cp', 'tm.client_policy_id=cp.id') + ->where('tm.id', $claimId) + ->get()->getRowArray(); + + if (!$ticket) { + log_message('error', 'CLAIM STATUS FAILED HEALTH_INDIA | claimId: ' . $claimId . ' - Invalid claim'); + return ['status' => false, 'message' => 'Invalid claim']; + } + + // Generate Health India Token + $tokenResponse = json_decode($this->generateAuthToken()->getBody(), true); + + if (empty($tokenResponse['data']['result'][0]['access_token'])) { + log_message('error', 'CLAIM STATUS FAILED HEALTH_INDIA | claimId: ' . $claimId . ' - Token generation failed'); + return ['status' => false, 'message' => 'Token generation failed']; + } + + $token = $tokenResponse['data']['result'][0]['access_token']; + + $url = getenv('HEALTH_INDIA_BASE_URL') . "/Claims/GetClaims"; + + // Using claim number wise approach (Section 7.3 - option 3) + $body = [ + "policY_NUMBER" => $ticket['policy_no'], + "CCN" => $ticket['ccn'], + "CCN_EXT" => "0" + ]; + + $headers = [ + "Authorization: Bearer " . $token, + "Content-Type: application/json" + ]; + + log_message('error', 'CLAIM STATUS HEALTH_INDIA | claimId: ' . $claimId . ' | Request: ' . json_encode($body)); + + $response = call_third_party_api($url, 'POST', $headers, $body); + + log_message('error', 'CLAIM STATUS HEALTH_INDIA | claimId: ' . $claimId . ' | Response: ' . json_encode($response)); + + if (empty($response['data']['result'][0])) { + log_message('error', 'CLAIM STATUS FAILED HEALTH_INDIA | claimId: ' . $claimId . ' | Empty response data'); + return ['status' => false, 'message' => 'API call failed.', 'data' => $response]; + } + + $claimData = $response['data']['result'][0]; + $status = $claimData['claiM_STATUS'] ?? null; + + // Status mapping based on API documentation + $map = [ + "Under Process" => 5, + "Pending for Bill Entry" => 5, + "Query" => 4, + "Paid" => 11, + "Rejected" => 8, + "Approved" => 8, + "Outstanding" => 5, + ]; + + if ($status != null && isset($map[$status])) { + $this->db->table('ticket_master') + ->where('id', $claimId) + ->update([ + 'claim_status_id' => $map[$status], + 'tpa_claim_status' => $status + ]); + log_message('error', "CLAIM STATUS SUCCESS HEALTH_INDIA | Updated claimId: {$claimId} with status: {$status}"); + } else { + log_message('error', "CLAIM STATUS HEALTH_INDIA | claimId: {$claimId} | Unknown status: {$status}"); + } + + return [ + 'status' => true, + 'message' => 'Claim status updated.', + 'updated_status' => $status, + 'api_response' => $response + ]; + } + + public function ClaimStatusUpdate() + { + helper('api'); + + log_message('error', 'CLAIM STATUS UPDATE BULK HEALTH_INDIA | Started'); + + $tickets = $this->db->table('ticket_master tm') + ->select("tm.id, tm.tpa_claim_id, cp.policy_no") + ->join('client_policy cp', 'tm.client_policy_id=cp.id') + ->where('tm.tpa_claim_id IS NOT NULL') + ->where('cp.tpa_id', $this->healthIndiaTpaId) + ->get()->getResultArray(); + + $count = 0; + + foreach ($tickets as $t) { + $this->ClaimDetail($t['id']); + $count++; + } + + log_message('error', 'CLAIM STATUS UPDATE BULK HEALTH_INDIA | Completed | Updated: ' . $count); + + return $this->response->setJSON(['status' => true, 'updated' => $count]); + } + + public function EcardRequest($employeeId = null, $policyNo = null, $memberId = null) + { + helper('api'); + + log_message('error', "ECARD REQUEST HEALTH_INDIA | Started | employeeId: {$employeeId} | policyNo: {$policyNo} | memberId: {$memberId}"); + + // Generate Health India Token + $tokenResponse = json_decode($this->generateAuthToken()->getBody(), true); + if (empty($tokenResponse['data']['result'][0]['access_token'])) { + log_message('error', "ECARD REQUEST FAILED HEALTH_INDIA | employeeId: {$employeeId} | policyNo: {$policyNo} | Message: Token generation failed"); + return null; + } + $token = $tokenResponse['data']['result'][0]['access_token']; + + // API Section 3.3 - Individual member e-card + $url = getenv('HEALTH_INDIA_BASE_URL') . "/Member/GetMemberEcard"; + + $body = [ + "policY_NUMBER" => $policyNo, + "employeE_CODE" => $employeeId, + "membeR_ID" => $memberId + ]; + + $headers = [ + "Authorization: Bearer " . $token, + "Content-Type: application/json" + ]; + + log_message('error', 'ECARD REQUEST HEALTH_INDIA | Request: ' . json_encode($body)); + + $response = call_third_party_api($url, 'POST', $headers, $body); + + log_message('error', 'ECARD REQUEST HEALTH_INDIA | Response: ' . json_encode($response)); + + if (($response['status'] ?? false) !== true) { + log_message('error', 'ECARD REQUEST FAILED HEALTH_INDIA | response: ' . json_encode($response)); + return null; + } + + if (empty($response['data']['result'][0])) { + log_message('error', 'ECARD REQUEST FAILED HEALTH_INDIA | Empty data | response: ' . json_encode($response)); + return null; + } + + $apiData = $response['data']['result'][0]; + + if (($apiData['message'] ?? '') === 'SUCCESS') { + $ecardUrl = $apiData['membeR_ECARD'] ?? ''; + + if (!empty($ecardUrl)) { + log_message('error', "ECARD REQUEST SUCCESS HEALTH_INDIA | employeeId: {$employeeId} | policyNo: {$policyNo} | memberId: {$memberId} | ecardUrl: {$ecardUrl}"); + return $ecardUrl; + } + } + + log_message('error', 'ECARD REQUEST FAILED HEALTH_INDIA | response: ' . json_encode($response)); + return null; + } + + public function HealthIndiaGetBenefDetails($requestData = null) + { + $function_calling_type = $requestData['return_type'] ?? 'job'; + + try { + helper('api'); + + $policyNo = $requestData['policy_no'] ?? null; + $client_policy_id = $requestData['client_policy_id'] ?? null; + + if (empty($policyNo)) { + log_message('error', 'TPA ID PULL HEALTH_INDIA | policy_no missing in request'); + if ($function_calling_type == "job") { + return ['status' => false, 'message' => 'policy_no required']; + } else { + return $this->respond(['status' => false, 'message' => 'policy_no required']); + } + } + + if (empty($client_policy_id)) { + log_message('error', 'TPA ID PULL HEALTH_INDIA | client_policy_id missing in request'); + if ($function_calling_type == "job") { + return ['status' => false, 'message' => 'client_policy_id required']; + } else { + return $this->respond(['status' => false, 'message' => 'client_policy_id required']); + } + } + + log_message('error', "TPA ID PULL HEALTH_INDIA | called for policy_no: {$policyNo}, client_policy_id: {$client_policy_id}"); + + // Fetch file download dates + $batchFiles = $this->db->table('batch_files f') + ->select("f.created_at") + ->where('f.client_policy_id', $client_policy_id) + ->where('f.insurer_or_tpa', 'tpa') + ->where('f.actions', 'export') + ->get() + ->getResultArray(); + + if (empty($batchFiles)) { + log_message('error', 'TPA ID PULL FAILED HEALTH_INDIA | batchFiles is empty for this tpa id pull request'); + if ($function_calling_type == "job") { + return ['status' => false, 'message' => 'batchFiles not found']; + } else { + return $this->respond(['status' => false, 'message' => 'batchFiles not found']); + } + } + + // Generate Health India Token + $tokenResponse = json_decode($this->generateAuthToken()->getBody(), true); + if (empty($tokenResponse['data']['result'][0]['access_token'])) { + log_message('error', 'TPA ID PULL HEALTH_INDIA | Token generation failed'); + if ($function_calling_type == "job") { + return ['status' => false, 'message' => 'Token generation failed']; + } else { + return $this->respond(['status' => false, 'message' => 'Token generation failed']); + } + } + $token = $tokenResponse['data']['result'][0]['access_token']; + + // API Section 2.3 - Bulk Enrolment data Fetch + $url = getenv('HEALTH_INDIA_BASE_URL') . "/Enrollment/GetEnrollmentData"; + + $headers = [ + "Authorization: Bearer " . $token, + "Content-Type: application/json" + ]; + + $body = [ + "policY_NUMBER" => $policyNo + ]; + + log_message('error', "TPA ID PULL HEALTH_INDIA | API params: " . json_encode(['url' => $url, 'method' => 'POST', 'body' => $body])); + + $response = call_third_party_api($url, 'POST', $headers, $body); + + log_message('error', "TPA ID PULL HEALTH_INDIA | API Response: " . json_encode($response)); + + if (($response['status'] ?? false) !== true) { + log_message('error', 'HEALTH_INDIA API FAILED | response: ' . json_encode($response)); + + // update file table status after the tpa id failed to update + if (isset($requestData['file_id']) && !empty($requestData['file_id'])) { + $file_model = new BatchFileModel(); + $file_model->where('id', $requestData['file_id'])->set('status', 'failed-8')->update(); + log_message('error', "Files table status updated for the file id: {$requestData['file_id']}"); + } else { + log_message('error', "Failed to update file table status."); + } + + if ($function_calling_type == "job") { + return ['status' => false, 'message' => 'API call failed', 'data' => $response]; + } else { + return $this->respond(['status' => false, 'message' => 'API call failed', 'data' => $response]); + } + } + + if ( + !isset($response['data']['result']) || + !is_array($response['data']['result']) || + count($response['data']['result']) === 0 + ) { + log_message('error', 'TPA ID PULL API FAILED HEALTH_INDIA | Empty member data for this pull request'); + + // update file table status after the tpa id failed to update + if (isset($requestData['file_id']) && !empty($requestData['file_id'])) { + $file_model = new BatchFileModel(); + $file_model->where('id', $requestData['file_id'])->set('status', 'failed-8')->update(); + log_message('error', "Files table status updated for the file id: {$requestData['file_id']}"); + } else { + log_message('error', "Failed to update file table status."); + } + + if ($function_calling_type == "job") { + return ['status' => false, 'message' => 'API call failed', 'data' => 'Empty member data for this pull request']; + } else { + return $this->respond(['status' => false, 'message' => 'API call failed', 'data' => 'Empty member data for this pull request']); + } + } + + $allMembers = $response['data']['result']; + + // Save API data as JSON for analysis + $json = json_encode($allMembers, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + $filePath = WRITEPATH . 'tmp/' . time() . '_' . $requestData['file_id'] . '.json'; + file_put_contents($filePath, $json); + + log_message('error', "TPA ID PULL HEALTH_INDIA | Saved JSON to: {$filePath}"); + + // Call a job for dump JSON data to DB + $job_details = new Jobs(); + $r = Jobs::addJob([ + 'job_name' => 'saveHealthIndiaAPIData', + 'payload' => [ + 'file_id' => $requestData['file_id'], + 'json_file_path' => $filePath + ] + ]); + + log_message('error', "TPA ID PULL HEALTH_INDIA | Job added for saving API data"); + + // ================= MATCHING LOGIC ================= + + $employeePolicyModel = new EmployeePolicyModel(); + + $employeePolicyData = $employeePolicyModel + ->join('employees', 'employees.id = employee_polices.employee_id') + ->where('employee_polices.client_policy_id', $client_policy_id) + ->where('employee_polices.tpa_id IS NULL') + ->findAll(); + + $updated = 0; + $batch_file_success = 'success'; + $employee_policy_ids = []; + + foreach ($employeePolicyData as $policy) { + $hasMatchForThisPolicy = false; + + foreach ($allMembers as $m) { + // Match based on: employee name, employee code, and relation + if ( + strtolower(trim($policy['name'])) === strtolower(trim($m['insured_Name'] ?? '')) && + ($policy['emp_code'] ?? '') == ($m['employeeCode'] ?? '') && + strtolower($policy['relationship']) === strtolower($m['relation'] ?? '') + ) { + $hasMatchForThisPolicy = true; + + $sql = "UPDATE employee_polices SET tpa_id = ? WHERE id = ?"; + $this->db->query($sql, [$m['memberId'], $policy['emp_policy_id']]); + + // For e-card send + if (strtolower(trim($policy['relationship'])) == 'self') { + $employee_policy_ids[] = $policy['emp_policy_id']; + } + + if ($this->db->affectedRows() > 0) { + $updated++; + log_message('error', "✅ HEALTH_INDIA | Updated tpa_id={$m['memberId']} for emp_policy_id={$policy['emp_policy_id']} policy={$policyNo}"); + } else { + log_message('error', "⚠️ HEALTH_INDIA | No update (already set or not matched) for emp_policy_id={$policy['emp_policy_id']} policy={$policyNo}"); + } + } + } + + // Handle NO MATCH for this policy + if (!$hasMatchForThisPolicy) { + $nhanceSideData = [ + 'name' => $policy['name'] ?? null, + 'emp_code' => $policy['emp_code'] ?? null, + 'relationship' => $policy['relationship'] ?? null, + 'gender' => $policy['gender'] ?? null, + 'dob' => $policy['dob'] ?? null, + ]; + $batch_file_success = 'partially success'; + + log_message('error', "❌ HEALTH_INDIA | No match for Nhance = " . json_encode($nhanceSideData)); + } + } + + // Send e-card + if (!empty($employee_policy_ids)) { + log_message('error', "HEALTH_INDIA | sendMailForDownloadingECard JOB PUSHED."); + Jobs::addJob([ + 'job_name' => 'sendMailForDownloadingECard', + 'payload' => [ + 'ids' => $employee_policy_ids, + 'client_policy_id' => $client_policy_id + ] + ]); + } + + // Update file table status after the tpa id successfully updated + if (isset($requestData['file_id']) && !empty($requestData['file_id'])) { + $file_model = new BatchFileModel(); + $file_model->where('id', $requestData['file_id'])->set('status', $batch_file_success)->update(); + log_message('error', "Files table status updated for the file id: {$requestData['file_id']} with status: {$batch_file_success}"); + } else { + log_message('error', "Failed to update file table status."); + } + + $totalCount = count($allMembers); + + log_message('error', "TPA ID PULL SUCCESS HEALTH_INDIA | completed. Total fetched={$totalCount}, updated={$updated}"); + + if ($function_calling_type == "job") { + return [ + 'status' => true, + 'message' => 'Updated successfully', + 'total_fetched' => $totalCount, + 'total_updated' => $updated + ]; + } else { + return $this->respond([ + 'status' => true, + 'message' => 'Updated successfully', + 'total_fetched' => $totalCount, + 'total_updated' => $updated + ]); + } + } catch (\Throwable $th) { + // Update file table status after the tpa id failed to update + if (isset($requestData['file_id']) && !empty($requestData['file_id'])) { + $file_model = new BatchFileModel(); + $file_model->where('id', $requestData['file_id'])->set('status', 'failed-8')->update(); + log_message('error', "Files table status updated for the file id: {$requestData['file_id']}"); + } else { + log_message('error', "Failed to update file table status."); + } + + $errorData = [ + 'message' => $th->getMessage(), + 'file' => $th->getFile(), + 'line' => $th->getLine(), + 'code' => $th->getCode(), + 'trace' => $th->getTraceAsString(), + 'trace_array' => $th->getTrace(), + 'function' => $th->getTrace()[0]['function'] ?? null, + 'class' => $th->getTrace()[0]['class'] ?? null, + ]; + + log_message('error', 'Exception thrown while calling HealthIndiaGetBenefDetails API: ' . json_encode($errorData)); + + if ($function_calling_type == "job") { + return ['status' => false, 'message' => 'API call failed', 'data' => $errorData]; + } else { + return $this->respond(['status' => false, 'message' => 'API call failed', 'data' => $errorData]); + } + } + } + + public function syncHealthIndiaClaimsToNhance() + { + helper('api'); + + log_message('error', 'SYNC CLAIMS HEALTH_INDIA | Started'); + + // Generate Health India Token + $tokenResponse = json_decode($this->generateAuthToken()->getBody(), true); + + if (empty($tokenResponse['data']['result'][0]['access_token'])) { + log_message('error', 'SYNC CLAIMS FAILED HEALTH_INDIA | Token generation failed'); + return $this->response->setJSON(['status' => false, 'message' => 'Token generation failed']); + } + + $token = $tokenResponse['data']['result'][0]['access_token']; + + $url = getenv('HEALTH_INDIA_BASE_URL') . "/ClaimsMIS/GetClaimsMIS"; + + $headers = [ + "Authorization: Bearer " . $token, + "Content-Type: application/json" + ]; + + $policies = $this->db->table('client_policy') + ->where('tpa_id', $this->healthIndiaTpaId) + ->get()->getResultArray(); + + $finalResult = []; + + foreach ($policies as $policy) { + $body = [ + "policY_NUMBER" => $policy['policy_no'] + ]; + + log_message('error', 'SYNC CLAIMS HEALTH_INDIA | Fetching for policy: ' . $policy['policy_no']); + + $response = call_third_party_api($url, 'POST', $headers, $body); + + if (!empty($response['data']['result'])) { + $finalResult = array_merge($finalResult, $response['data']['result']); + log_message('error', 'SYNC CLAIMS HEALTH_INDIA | Fetched ' . count($response['data']['result']) . ' claims for policy: ' . $policy['policy_no']); + } + } + + log_message('error', 'SYNC CLAIMS HEALTH_INDIA | Total claims fetched: ' . count($finalResult)); + + // Insert / update ticket_master + $insertedCount = 0; + foreach ($finalResult as $row) { + $status = $row['Claim_Status'] ?? 'Under Process'; + + $map = [ + "Under Process" => 5, + "Pending for Bill Entry" => 5, + "Paid" => 11, + "Rejected" => 8, + "Approved" => 8, + "Outstanding" => 5, + ]; + + $claimStatus = $map[$status] ?? 1; + + // Check if claim already exists + $existing = $this->db->table('ticket_master') + ->where('tpa_claim_id', $row['CLAIM_NUMBER']) + ->get()->getRowArray(); + + if (!$existing) { + $this->db->table('ticket_master')->insert([ + 'policy_no' => $row['Policy_No'] ?? '', + 'claim_number' => $row['CLAIM_NUMBER'] ?? '', + 'tpa_claim_id' => $row['CLAIM_NUMBER'] ?? '', + 'emp_code' => $row['Employee_Code'] ?? '', + 'insured_name' => $row['PATIENT_NAME'] ?? '', + 'claim_amount' => $row['INTIMATED_AMOUNT'] ?? 0, + 'hospital_name' => $row['HOSPITAL_NAME'] ?? '', + 'doa' => !empty($row['DATEOF_ADMISSION']) ? date('Y-m-d', strtotime($row['DATEOF_ADMISSION'])) : null, + 'dod' => !empty($row['DATEOF_DISCHARGE']) ? date('Y-m-d', strtotime($row['DATEOF_DISCHARGE'])) : null, + 'claim_status_id' => $claimStatus, + 'tpa_id' => $this->healthIndiaTpaId, + 'created_at' => date('Y-m-d H:i:s') + ]); + $insertedCount++; + log_message('error', 'SYNC CLAIMS HEALTH_INDIA | Inserted claim: ' . ($row['CLAIM_NUMBER'] ?? 'N/A')); + } else { + log_message('error', 'SYNC CLAIMS HEALTH_INDIA | Skipped existing claim: ' . ($row['CLAIM_NUMBER'] ?? 'N/A')); + } + } + + log_message('error', 'SYNC CLAIMS HEALTH_INDIA | Completed | Total: ' . count($finalResult) . ' | Inserted: ' . $insertedCount); + + return $this->response->setJSON([ + 'status' => true, + 'total' => count($finalResult), + 'inserted' => $insertedCount + ]); + } +} \ No newline at end of file diff --git a/app/Controllers/UserController.php b/app/Controllers/UserController.php index daaadb9f..d2a32ac1 100755 --- a/app/Controllers/UserController.php +++ b/app/Controllers/UserController.php @@ -114,13 +114,11 @@ class UserController extends AdminController // Employee Code // ====================== 'emp_code' => [ - 'rules' => 'required|alpha_numeric|min_length[3]|max_length[20]|is_unique[user_profiles.emp_code,id,{PrimaryKey}]', + 'rules' => 'required|min_length[3]|max_length[15]', 'errors' => [ 'required' => 'Employee Code is required', - 'alpha_numeric' => 'Employee Code must be alphanumeric', 'min_length' => 'Employee Code must be at least 3 characters', - 'max_length' => 'Employee Code cannot exceed 20 characters', - 'is_unique' => 'Employee Code already exists' + 'max_length' => 'Employee Code cannot exceed 15 characters', ] ], @@ -141,11 +139,10 @@ class UserController extends AdminController // Email // ====================== 'email' => [ - 'rules' => 'required|valid_email|is_unique[user_profiles.email,id,{PrimaryKey}]', + 'rules' => 'required|valid_email', 'errors' => [ 'required' => 'Email is required', 'valid_email' => 'Please enter a valid email address', - 'is_unique' => 'Email already exists' ] ], @@ -153,11 +150,10 @@ class UserController extends AdminController // Mobile // ====================== 'mobile' => [ - 'rules' => 'required|regex_match[/^[6-9][0-9]{9}$/]|is_unique[user_profiles.mobile,id,{PrimaryKey}]', + 'rules' => 'required|regex_match[/^[6-9][0-9]{9}$/]', 'errors' => [ 'required' => 'Mobile number is required', 'regex_match' => 'Enter a valid 10-digit mobile number starting with 6, 7, 8, or 9', - 'is_unique' => 'Mobile number already exists' ] ], @@ -302,13 +298,11 @@ class UserController extends AdminController // Employee Code // ====================== 'emp_code' => [ - 'rules' => 'required|alpha_numeric|min_length[3]|max_length[20]|is_unique[user_profiles.emp_code,id,{PrimaryKey}]', + 'rules' => 'required|min_length[3]|max_length[15]', 'errors' => [ 'required' => 'Employee Code is required', - 'alpha_numeric' => 'Employee Code must be alphanumeric', 'min_length' => 'Employee Code must be at least 3 characters', - 'max_length' => 'Employee Code cannot exceed 20 characters', - 'is_unique' => 'Employee Code already exists' + 'max_length' => 'Employee Code cannot exceed 15 characters', ] ], @@ -329,11 +323,10 @@ class UserController extends AdminController // Email // ====================== 'email' => [ - 'rules' => 'required|valid_email|is_unique[user_profiles.email,id,{PrimaryKey}]', + 'rules' => 'required|valid_email', 'errors' => [ 'required' => 'Email is required', 'valid_email' => 'Please enter a valid email address', - 'is_unique' => 'Email already exists' ] ], @@ -341,11 +334,10 @@ class UserController extends AdminController // Mobile // ====================== 'mobile' => [ - 'rules' => 'required|regex_match[/^[6-9][0-9]{9}$/]|is_unique[user_profiles.mobile,id,{PrimaryKey}]', + 'rules' => 'required|regex_match[/^[6-9][0-9]{9}$/]', 'errors' => [ 'required' => 'Mobile number is required', 'regex_match' => 'Enter a valid 10-digit mobile number starting with 6, 7, 8, or 9', - 'is_unique' => 'Mobile number already exists' ] ], diff --git a/app/Views/UserList.php b/app/Views/UserList.php index 28cde270..ca47296c 100755 --- a/app/Views/UserList.php +++ b/app/Views/UserList.php @@ -581,7 +581,7 @@ table.dataTable tbody td {
- +
@@ -884,7 +884,20 @@ table.dataTable tbody td { +getFlashdata('error')) : ?> + getFlashdata('error') as $error) : ?> + + + +