db = \Config\Database::connect(); $this->fhplTpaId = getenv('FHPL_PRIMARY_KEY_CONSTANT'); } public function generateAuthToken() { $url = env('FHPL_TOKEN_URL'); // x-www-form-urlencoded body $postData = http_build_query([ 'UserName' => env('FHPL_USER_NAME'), 'Password' => env('FHPL_PASSWORD'), 'grant_type' => env('FHPL_GRANT_TYPE'), ]); $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => 'GET', // SAME AS POSTMAN CURLOPT_POSTFIELDS => $postData, CURLOPT_HTTPHEADER => [ 'Content-Type: application/x-www-form-urlencoded', 'Accept: application/json', ], CURLOPT_TIMEOUT => 30, ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if (curl_errno($ch)) { return $this->response->setJSON([ 'status' => false, 'error' => curl_error($ch), ]); } curl_close($ch); return $this->response->setJSON([ 'status' => $httpCode === 200, 'http_code' => $httpCode, 'data' => json_decode($response, true), ]); } public function SubmitClaim($claimId = null) // 515 { helper('api'); $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 requestedAmount, tm.tpa_no as dependentUniqueId, cp.policy_no as policyNo, e.emp_code as memberId, tn.note as disease, cf.url as filePath ') ->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 (count($data) && $data['filePath'] == null) { log_message('error', "TPA CLAIM PUSH FAILED FHPL | claimId: '.$claimId.' - Claim or 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 FHPL | claimId: '.$claimId.' - PDF not found on server"); return; } // Convert PDF to Base64 $fileContent = base64_encode(file_get_contents($pdfPath)); // Generate FHPL Token $tokenResponse = json_decode($this->generateAuthToken()->getBody(), true); if (empty($tokenResponse['data']['access_token'])) { log_message('error', "TPA CLAIM PUSH FAILED FHPL | claimId: '.$claimId.' - FHPL Token generation failed"); return; } $token = $tokenResponse['data']['access_token']; // Build FHPL Request $body = [ "IssueID" => $data['dependentUniqueId'], // this key added after seeing the error in responce have to click with fhpl team "Userid" => getenv('FHPL_USER_NAME'), "PolicyNo" => $data['policyNo'], // "111700-TATAMTORS", "UhidNo" => $data['dependentUniqueId'], // "OIC40830846", "ClaimID" => (string) $data['id'], "DOA" => date('Y-m-d', strtotime($data['admissionDate'])), //"2025-10-11", "DateofDischarge"=> $data['dischargeDate'] ? date('Y-m-d', strtotime($data['dischargeDate'])) : null, "ClaimedAmount" => (float) $data['requestedAmount'], "DocumentType" => 20, // Fresh Claim "PayeeName" => $data['memberId'], "HospitalName" => $data['hospitalName'], "MobileNo" => $data['mobileNo'], "Documents" => [ [ "documentName" => $filename, "documentCategory" => "IRR", "filecontent" => $fileContent ] ] ]; $url = getenv('FHPL_BASE_URL') . "/api/ClaimSubmission"; $headers = [ "Authorization: Bearer " . $token, "Content-Type: application/json" ]; log_message('error', 'TPA CLAIM PUSH FHPL | claimId: '.$claimId.' | payload: '.json_encode($body)); $response = call_third_party_api($url, 'POST', $headers, $body); log_message('error', 'TPA CLAIM PUSH FHPL RESPONSE | ' . json_encode($response)); if($response['status'] != true){ log_message('error', 'TPA CLAIM PUSH FAILED FHPL | 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'][0]['ClaimsInfo'])) { $claimsInfo = json_decode($response['data'][0]['ClaimsInfo'], true); if (!empty($claimsInfo[0]['ClaimID'])) { $fhplClaimNo = $claimsInfo[0]['ClaimID']; $this->db->table('ticket_master') ->where('id', $claimId) ->update([ 'claim_number' => $fhplClaimNo, 'tpa_claim_id' => $fhplClaimNo, 'tpa_claim_push_reference_no' => $fhplClaimNo, 'updated_at' => date('Y-m-d H:i:s') ]); log_message('error', 'TPA CLAIM PUSH SUCCESS FHPL | claimId: '.$claimId.' | claimNO: '.$fhplClaimNo); }else { log_message('error', 'TPA CLAIM PUSH API SUCCESS BUT claimsInfo EMPTY | response: '.json_encode($response)); return; } } return; // return $this->response->setJSON($response); } public function ClaimDetail($claimId = null) //515 { helper('api'); $ticket = $this->db->table('ticket_master tm') ->select("tm.id, tm.tpa_claim_id as claimNo, cp.policy_no , cp.policy_start_date , cp.policy_end_date") ->join('client_policy cp','tm.client_policy_id=cp.id') ->where('tm.id',$claimId) ->get()->getRowArray(); if(!$ticket) return ['status'=>false,'message'=>'Invalid claim']; // Generate FHPL Token $tokenResponse = json_decode($this->generateAuthToken()->getBody(), true); if (empty($tokenResponse['data']['access_token'])) { return ['status' => false,'message' => 'FHPL Token generation failed']; } $token = $tokenResponse['data']['access_token']; $url = getenv('FHPL_BASE_URL')."/api/GetTPA_ClaimsDetails"; $body = [ "UserName" => getenv('FHPL_USER_NAME'), "Password" => getenv('FHPL_PASSWORD'), "PolicyNumber" => $ticket['policy_no'], //"GHI-81-25-00087313-000", "Fromdate" => $ticket['policy_start_date'],//"2025-04-26", "Todate" => $ticket['policy_end_date'],//"2025-04-27", ]; $headers = ["Authorization: Bearer ".$token,"Content-Type: application/json"]; $response = call_third_party_api($url,'POST',$headers,$body); // dd($response); if (empty($response['data'][0])) { log_message('error', 'CLAIM STATUS FAILED | for ticket ID: ' . $claimId.' | response: '.json_encode($response)); return ['status' => false,'message' => 'API call failed.','data' => $response ]; } $status = null; // find this claim foreach($response['data'] as $row){ if($row['CLAIM_ID']==$ticket['claimNo']){ $status = $row['CLAIM_STATUS']; } } $map = [ "In-Progress" => 5, "Under Process" => 5, "Query" => 4, "Paid" => 11, "Rejected" => 8, "Approved" => 8, "Required Information" => 4, ]; 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 | Updated ticket ID $claimId with claim status: $status"); } return ['status' => true,'message' => 'Claim status updated.','updated_status' => $status,'api_response' => $response]; } public function ClaimStatusUpdate() { helper('api'); $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') ->get()->getResultArray(); $count=0; foreach($tickets as $t){ $this->ClaimDetail($t['id']); $count++; } return $this->response->setJSON(['status'=>true,'updated'=>$count]); } public function EcardRequest($employeeId = null,$policyNo = null,$uhid = null) { helper('api'); // Generate FHPL Token $tokenResponse = json_decode($this->generateAuthToken()->getBody(), true); if (empty($tokenResponse['data']['access_token'])) { log_message('error', 'Ecard Request FAILED | employeeId: '.$employeeId.' | policyNo: '.$policyNo.' | Message: FHPL Token generation failed'); return null; } $token = $tokenResponse['data']['access_token']; $url = getenv('FHPL_BASE_URL')."/api/GetEcard"; $body = [ "UserName" => getenv('FHPL_USER_NAME'), "Password" => getenv('FHPL_PASSWORD'), "PolicyNumber" => $policyNo, //'10/12/2025/16/17', "EmployeeID" => $employeeId, //'101225', ]; $headers = ["Authorization: Bearer ".$token,"Content-Type: application/json"]; $response = call_third_party_api($url,'POST',$headers,$body); // dd($response); if (($response['status'] ?? false) !== true) { log_message('error', 'Ecard Request FAILED | response: ' . json_encode($response)); return null; } if (empty($response['data'][0])) { log_message('error', 'Ecard Request FAILED | Empty data | response: ' . json_encode($response)); return null; } $apiData = $response['data'][0]; if (($apiData['STATUS'] ?? '') === 'SUCCESS') { $ecardUrl = $apiData['E_Card'] ?? ''; if (!empty($ecardUrl)) { log_message( 'info', 'Ecard Request PUSH SUCCESS | employeeId: ' . $employeeId . ' | policyNo: ' . $policyNo . ' | ecardUrl: ' . $ecardUrl ); return $ecardUrl; } } log_message('error', 'Ecard Request FAILED | response: ' . json_encode($response)); return null; } public function FhplGetBenefDetails($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 | 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 | 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 | 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 | 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 FHPL Token $tokenResponse = json_decode($this->generateAuthToken()->getBody(), true); if (empty($tokenResponse['data']['access_token'])) { log_message('error', 'TPA ID PULL | FHPL Token generation failed'); if($function_calling_type == "job"){ return ['status' => false, 'message' => 'FHPL Token generation failed']; }else{ return $this->respond(['status' => false, 'message' => 'FHPL Token generation failed']); } } $token = $tokenResponse['data']['access_token']; $url = getenv('FHPL_BASE_URL') . "/api/GetEnrollmentDetailsPolicy"; $headers = [ "Authorization: Bearer " . $token, "Content-Type: application/json" ]; $startIndex = 0; $range = 100; $allMembers = []; while (true) { $body = [ "UserName" => getenv('FHPL_USER_NAME'), "Password" => getenv('FHPL_PASSWORD'), "PolicyNumber" => $policyNo, "StartIndex" => $startIndex, "Range" => $range ]; log_message('error', "TPA ID PULL | API parems " . json_encode([$url, 'POST', $headers, $body])); $response = call_third_party_api($url, 'POST', $headers, $body); if (($response['status'] ?? false) !== true) { log_message('error', 'FHPL API FAILED | response: ' . json_encode($response)); break; } if ( !isset($response['data']) || !is_array($response['data']) || count($response['data']) === 0 || !array_is_list($response['data']) // PHP 8+ safe check ) { // STOP when data is not a valid list break; } $allMembers = array_merge($allMembers, $response['data']); // Move to next page $startIndex += $range; } if(empty($allMembers)) { // 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."); } log_message('error', 'TPA ID PULL API FAILED | API failed: Empty menber data for this pull request'); if($function_calling_type == "job"){ return ['status' => false, 'message' => 'API call failed', 'data' => 'Empty menber data for this pull request']; }else{ return $this->respond(['status' => false, 'message' => 'API call failed', 'data' => 'Empty menber data for this pull request']); } } // dd($allMembers); //save API data as JSON for analysis $json = json_encode($allMembers, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); // $filename = time() . '.json'; $filePath = WRITEPATH . 'tmp/'.time().'_'.$requestData['file_id'].'.json'; file_put_contents($filePath, $json); //call a job for dump JSON data to DB $job_details = new Jobs(); $r = Jobs::addJob(['job_name' => 'saveFhplAPIData', 'payload' => [ 'file_id' => $requestData['file_id'],'json_file_path' => $filePath ]]); // ================= 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; foreach ($employeePolicyData as $policy) { $hasMatchForThisPolicy = false; foreach ($allMembers as $m) { if ( strtolower(trim($policy['name'])) === strtolower(trim($m['EMPLOYEE_NAME'] ?? '')) && ($policy['emp_code'] ?? '') == ($m['EMPLOYEE_ID'] ?? '') && strtolower($policy['relationship']) === strtolower($m['RELATION'] ?? '') ) { $hasMatchForThisPolicy = true; $sql = "UPDATE employee_polices SET tpa_id = ? WHERE id = ?"; $this->db->query($sql, [$m['TPA_TPADETAIL_ID'], $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', "✅ Updated tpa_id={$m['TPA_TPADETAIL_ID']} for emp_policy_id={$policy['emp_policy_id']} policy={$policyNo}"); } else { log_message('error', "⚠️ 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_data['name'] ?? null, 'emp_code' => $policy_data['emp_code'] ?? null, 'relationship' => $policy_data['relationship'] ?? null, 'gender' => $policy_data['gender'] ?? null, 'dob' => $policy_data['dob'] ?? null, ]; $batch_file_success = 'partially success'; log_message( 'error', "❌ No match for Nhance = " . json_encode($nhanceSideData) ); } // send e-card if(!empty($employee_policy_ids)){ log_message('error', "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']}"); } else { log_message('error', "Failed to update file table status."); } $totalCount = count($allMembers); log_message('error', "TPA ID PULL SUCCESS | 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(), // full array version (optional) 'function' => $th->getTrace()[0]['function'] ?? null, 'class' => $th->getTrace()[0]['class'] ?? null, ]; log_message('error', 'Exception thrown while calling GetBenefDetails 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 FhplGetBenefDetails($requestData = null) // { // helper('api'); // $policyNo = $requestData['policy_no'] ?? "10/12/2025/16/17"; // $client_policy_id = $requestData['client_policy_id'] ?? 0; // // Generate FHPL Token // $tokenResponse = json_decode($this->generateAuthToken()->getBody(), true); // if (empty($tokenResponse['data']['access_token'])) { // return $this->response->setJSON(['status' => false,'message' => 'FHPL Token generation failed']); // } // $token = $tokenResponse['data']['access_token']; // $url = getenv('FHPL_BASE_URL')."/api/GetEnrollmentDetailsPolicy"; // $headers = [ // "Authorization: Bearer ".$token, // "Content-Type: application/json" // ]; // $startIndex = 0; // $range = 100; // $allMembers = []; // do { // $body = [ // "UserName" => getenv('FHPL_USER_NAME'), // "Password" => getenv('FHPL_PASSWORD'), // "PolicyNumber" => $policyNo, // "StartIndex" => $startIndex, // "Range" => $range // ]; // $response = call_third_party_api($url,'POST',$headers,$body); // dd($response); // if(empty($response['data']['Members'])){ // break; // } // $allMembers = array_merge($allMembers,$response['data']['Members']); // $startIndex += $range; // } while($startIndex < ($response['data']['Total'] ?? 0)); // dd($allMembers); // // Now same matching logic you already have // $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; // foreach($employeePolicyData as $policy){ // foreach($allMembers as $m){ // if( // strtolower(trim($policy['name']))==strtolower(trim($m['Name'])) && // $policy['emp_code']==$m['MemberID'] && // strtolower($policy['relationship'])==strtolower($m['Relation']) // ){ // $this->db->table('employee_polices') // ->where('id',$policy['emp_policy_id']) // ->update(['tpa_id'=>$m['UHID']]); // $updated++; // } // } // } // return [ // 'status'=>true, // 'total_fetched'=>count($allMembers), // 'updated'=>$updated // ]; // } public function syncFhplClaimsToNhance() { helper('api'); // Generate FHPL Token $tokenResponse = json_decode($this->generateAuthToken()->getBody(), true); if (empty($tokenResponse['data']['access_token'])) { return $this->response->setJSON(['status' => false,'message' => 'FHPL Token generation failed']); } $token = $tokenResponse['data']['access_token']; $url = getenv('FHPL_BASE_URL')."/api/GetTPA_ClaimsDetails"; $headers = [ "Authorization: Bearer ".$token, "Content-Type: application/json" ]; $policies = $this->db->table('client_policy') ->where('tpa_id',$this->fhplTpaId) ->get()->getResultArray(); $finalResult=[]; foreach($policies as $policy){ $body = [ "UserName" => getenv('FHPL_USER_NAME'), "Password" => getenv('FHPL_PASSWORD'), "PolicyNumber" => $policy['policy_no'], "Fromdate" => $policy['policy_start_date'], "Todate" => $policy['policy_end_date'] ]; $response = call_third_party_api($url,'POST',$headers,$body); if(!empty($response['data'])){ $finalResult = array_merge($finalResult,$response['data']); } } // Insert / update ticket_master same way you already do for MediAssist foreach($finalResult as $row){ $status = $row['CLAIM_STATUS']; $map = [ "Under Process"=>5, "Paid"=>11, "Rejected"=>8, "Approved"=>8 ]; $claimStatus = $map[$status] ?? 1; $this->db->table('ticket_master')->insert([ 'policy_no'=>$row['POLICY_NO'], 'claim_number'=>$row['CLAIM_ID'], 'tpa_claim_id'=>$row['CLAIM_ID'], 'emp_code'=>$row['EMPLOYEE_NO'], 'insured_name'=>$row['PATIENT_NAME'], 'claim_amount'=>$row['CLAIM_AMOUNT'], 'hospital_name'=>$row['HOSPITAL_NAME'], 'doa'=>$row['DATE_OF_ADMISSION'], 'dod'=>$row['DATE_OF_DISCHARGE'], 'claim_status_id'=>$claimStatus, 'tpa_id'=>$this->fhplTpaId ]); } return ['status'=>true,'total'=>count($finalResult)]; } }