diff --git a/.gitignore b/.gitignore index 1ab80e5d..adeb2bd5 100755 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,5 @@ composer.lock .env .phpunit* phpqueue.sh +.claude diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 7ed357a6..1531645b 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -626,6 +626,8 @@ $routes->get("downloadFileTableFile/(:any)", "EmployeeController::downloadFileLi $routes->group("employeeRest", ['filter' => ['ratelimit' , 'appSignature'] ], function ($routes) { + $routes->post('logout', 'RestAuthenticationController::logout'); + //Employee login api's $routes->post("verifyEmployeeNumber", "RestAuthenticationController::verifyEmployeeWithMobileNumber"); $routes->post("getVerifiedUserData", "RestAuthenticationController::getVerifiedUserData"); @@ -669,7 +671,7 @@ $routes->group("employeeRest", ['filter' => ['ratelimit' , 'appSignature'] ], fu $routes->group("employeeRest", ["filter" => ['GlobalPostFileUploadGuard', 'ratelimit' , 'appSignature', 'authJWT']], function ($routes) { - $routes->post('logout', 'RestAuthenticationController::logout'); + // $routes->post('logout', 'RestAuthenticationController::logout'); $routes->post("ecardRequest", "ApiServiceController::ecardRequest"); $routes->get("getWellnessURL", "ApiServiceController::getWellnessURL"); diff --git a/app/Controllers/ApiServiceController.php b/app/Controllers/ApiServiceController.php index 05d7c790..ea3103e9 100644 --- a/app/Controllers/ApiServiceController.php +++ b/app/Controllers/ApiServiceController.php @@ -231,11 +231,23 @@ class ApiServiceController extends BaseController // json_decode(file_get_contents(WRITEPATH.'/tmp/db.json'),true), // json_decode(file_get_contents(WRITEPATH.'/tmp/medi.json'),true) // ); - // print_rr($report); + // print_rr('tata'); // die(); + // $mediAssistController = new MediAssistApiController(); + // $mediAssistController->MediAssistGetBenefDetails( [ 'policy_no' => '97000063250400000012', 'file_id' =>'5704','client_policy_id' => '1839' ] ); + // $mediAssistController->MediAssistGetBenefDetails( [ 'policy_no' => '97000063250400000016', 'file_id' =>'5704','client_policy_id' => '2002' ] ); + // die(); + // $vidalApiController = new VidalApiController; + // $vidalApiController->VidalGetBenefDetails( [ 'policy_no' => '570000/48/2026/363', 'file_id' =>'5264','client_policy_id' => '9433'] ); + // $fhplApiController = new FhplApiController; + // $fhplApiController->FhplGetBenefDetails( [ 'policy_no' => '570000/48/2026/453', 'file_id' =>'9999','client_policy_id' => '3557'] ); + + // $healthIndiaApiController = new HealthIndiaApiController; + // $healthIndiaApiController->HealthIndiaGetBenefDetails( [ 'policy_no' => '97000063250400000116', 'file_id' =>'9998','client_policy_id' => '6523'] ); + // die(); //START OF THE PROGRAM log_message('error', "getTPAID payloads :" . json_encode($this->request->getPost() ?? [])); $tpa_id = $this->request->getPost('tpa_id') ?? null; @@ -452,7 +464,7 @@ class ApiServiceController extends BaseController $data = $db->table('employees e') ->select('pt.policy_type, e.name, e.email_corporate as email, e.mobile as phone, e.emp_code as memberId, e.gender, e.dob, e.relationship as relation, - cp.policy_no as policyNumber, ep.employee_id as employeeId, cp.policy_start_date as policyStartDate, cp.policy_end_date as policyEndDate , cp.wellness_plan_id as planId , cp.wellness_vendor_id') + cp.policy_no as policyNumber, ep.employee_id as employeeId,ep.id, cp.policy_start_date as policyStartDate, cp.policy_end_date as policyEndDate , cp.wellness_plan_id as planId , cp.wellness_vendor_id') ->join('employee_polices ep', 'e.id = ep.employee_id') ->join('client_policy cp', 'ep.client_policy_id = cp.id') ->join('policy_type pt', 'cp.policy_type_id = pt.id') @@ -480,20 +492,40 @@ class ApiServiceController extends BaseController } else if ($row['planId'] != null && empty($row['wellness_vendor_id'])) // VISIT { - $userParams['name'] = $row['name']; - $userParams['email'] = $row['email']; - $userParams['phone'] = $row['phone']; - $userParams['memberId'] = $row['employeeId']; // memberId is unique primary key. - $userParams['gender'] = $row['gender']; - $userParams['dob'] = $row['dob']; - $userParams['relation'] = $row['relation']; - $userParams['policyNumber'] = $row['policyNumber']; - $userParams['employeeId'] = $row['memberId']; - $userParams['policyStartDate']= $row['policyStartDate']; - $userParams['policyEndDate'] = $row['policyEndDate']; - $userParams['policyName'] = $row['policy_type']; - $userParams['planId'] = $row['planId']; - $userParams['moduleName'] = 'home'; + + //OLD PARAMS + // $userParams['name'] = $row['name']; + // $userParams['email'] = $row['email']; + // $userParams['phone'] = $row['phone']; + // $userParams['memberId'] = $row['employeeId']; // memberId is unique primary key. + // $userParams['gender'] = $row['gender']; + // $userParams['dob'] = $row['dob']; + // $userParams['relation'] = $row['relation']; + // $userParams['policyNumber'] = $row['policyNumber']; + // $userParams['employeeId'] = $row['memberId']; + // $userParams['policyStartDate']= $row['policyStartDate']; + // $userParams['policyEndDate'] = $row['policyEndDate']; + // $userParams['policyName'] = $row['policy_type']; + // $userParams['planId'] = $row['planId']; + // $userParams['moduleName'] = 'home'; + + //NEW PARAMS + $userParams['memberId'] = $row['id']; // employee policy primary key (which used while onboard)from DB + $userParams['phone'] = $row['phone']; + $userParams['email'] = $row['email']; + $userParams['relationship'] = $row['relation']; + $userParams['gender'] = $row['gender']; + $userParams['dob'] = $row['dob']; + $userParams['policyNumber'] = $row['policyNumber']; + $userParams['policyStartDate'] = $row['policyStartDate']; + $userParams['policyEndDate'] = $row['policyEndDate']; + $userParams['plan'] = $row['planId']; + $userParams['source'] = 'NAHANCE'; + $userParams['employeeId'] = $row['memberId']; + $userParams['firstName'] = $row['name']; + $userParams['middleName'] = ''; + $userParams['lastName'] = ''; + break; // stop after first GMC match } } diff --git a/app/Controllers/EmployeeController.php b/app/Controllers/EmployeeController.php index 3fc7e8fe..ff208769 100755 --- a/app/Controllers/EmployeeController.php +++ b/app/Controllers/EmployeeController.php @@ -497,6 +497,8 @@ class EmployeeController extends AdminController batch_files.amount, batch_files.status, batch_files.client_branch_id, + insurers.short_name as insurer_short_name, + tpa.short_name as tpa_short_name, DATE_FORMAT(batch_files.policy_issue_date, '%d/%m/%Y') AS policy_issue_date, CASE @@ -512,6 +514,8 @@ class EmployeeController extends AdminController ") ->join('client_policy', 'client_policy.id = batch_files.client_policy_id') + ->join('insurers', 'client_policy.insurer_id = insurers.id') + ->join('tpa', 'client_policy.tpa_id = tpa.id') ->join('client_branch', 'client_branch.id = batch_files.client_branch_id') ->join('policy_type', 'policy_type.id = client_policy.policy_type_id') ->join('clients', 'clients.id = client_policy.client_id') @@ -4029,71 +4033,202 @@ class EmployeeController extends AdminController public function getTPADataVariationReport($file_id, $type = 'download') { - $file_info = $this->batchFileModel->where('id', $file_id)->find(); - $client_id = $file_info[0]['client_id']; - $client_policy_id = $file_info[0]['client_policy_id']; - $TpaApiDataModel = new TpaApiDataModel(); - $emp_data_wo_tpa_id = $this->employeePolicyModel->getTPADataVariationReport($client_id, $client_policy_id, $file_id); + $fileInfo = $this->batchFileModel->find((int) $file_id); + if (empty($fileInfo)) { + if ($type === 'view') { + return []; + } + if ($type === 'download') { + return false; + } + return $this->respond(['status' => false, 'code' => 404, 'message' => 'File not found', 'data' => []], 200); + } - //loop emp data with TPA data for matches - foreach ($emp_data_wo_tpa_id as $db_key => $db_row) - { - //get TPA API data from table for current DB ep code - $tpa_temp_data = $TpaApiDataModel->select('*') - ->where('emp_code', $db_row['emp_code']) + $client_id = (int) ($fileInfo['client_id'] ?? 0); + $client_policy_id = (int) ($fileInfo['client_policy_id'] ?? 0); + // `call_type` controls whether we should force a fresh reconciliation. + // - job => always recompute + persist rec_type snapshot + // - manual => compute only on first call; otherwise use cached rec_type snapshot + // $callType = strtolower((string) ($this->request->getGet('call_type') ?? 'manual')); + $isJobCall = $type === 'job'; + + $tpaApiDataModel = new TpaApiDataModel(); + // Snapshot existence check: + // If any active row already has a non-empty rec_type, we consider this file + // already classified and can safely use cached mode for non-job calls. + $hasRecTypeSnapshot = $tpaApiDataModel->where('file_id', $file_id) + ->where('is_active', 1) + ->where('rec_type IS NOT NULL', null, false) + ->where('rec_type !=', '') + ->countAllResults() > 0; + + // Compute mode rules: + // 1) job calls always recompute and overwrite rec_type for deterministic refresh. + // 2) first non-job call computes when no snapshot exists. + // Cached mode is used only for second+ non-job calls. + $shouldComputeAndPersist = $isJobCall || !$hasRecTypeSnapshot; + // echo $shouldComputeAndPersist; + // die; + $this->myLogger->logme( + 'error', + 'TPA variation report mode selected: ' . json_encode([ + 'file_id' => (int) $file_id, + 'call_type' => $isJobCall, + 'mode' => $shouldComputeAndPersist ? 'compute' : 'cached', + ]) + ); + $emp_data_wo_tpa_id = []; + $not_in_nhance = []; + + if ($shouldComputeAndPersist) { + // Load once and index in memory to avoid N+1 queries during reconciliation. + $allActiveTpaRows = $tpaApiDataModel->select('*') ->where('file_id', $file_id) ->where('is_active', 1) ->findAll(); - $match= $this->reconcileDbWithTpa($db_row,$tpa_temp_data); - $emp_data_wo_tpa_id[$db_key]['match'] = $match; + + $tpaByEmpCode = []; + foreach ($allActiveTpaRows as $tpaRow) { + $tpaByEmpCode[$tpaRow['emp_code']][] = $tpaRow; + } + + $recTypeById = []; + foreach ($allActiveTpaRows as $tpaRow) { + // Default classification for active rows. + // Later loops will overwrite specific rows as `need_to_review` or `not_in_nhance`. + $recTypeById[$tpaRow['id']] = 'matched'; + } + + $emp_data_wo_tpa_id = $this->employeePolicyModel->getTPADataVariationReport($client_id, $client_policy_id, $file_id); + + // Reconcile DB records against TPA records and classify records for rec_type updates. + foreach ($emp_data_wo_tpa_id as $db_key => $db_row) { + $tpa_temp_data = $tpaByEmpCode[$db_row['emp_code']] ?? []; + $match = $this->reconcileDbWithTpa($db_row, $tpa_temp_data); + $emp_data_wo_tpa_id[$db_key]['match'] = $match; + + if (($match['status'] ?? '') === 'matched') { + $matchedTpaId = (int) ($match['tpa_record']['id'] ?? 0); + if ($matchedTpaId > 0) { + // If compare-fields list has differences, the row must be reviewed. + // Otherwise keep it as matched. + $recTypeById[$matchedTpaId] = empty($match['not_matching']) ? 'matched' : 'need_to_review'; + } + } else { + // No relation-level match found for this DB member. + // Mark all candidate TPA rows for the same emp_code as review-required. + foreach ($tpa_temp_data as $candidate) { + $candidateId = (int) ($candidate['id'] ?? 0); + if ($candidateId > 0) { + $recTypeById[$candidateId] = 'need_to_review'; + } + } + } + } + + $master_emp_codes = $this->employeePolicyModel->getTPADataVariationReport($client_id, $client_policy_id, $file_id, [], true); + $master_emp_codes = array_column($master_emp_codes, 'emp_code'); + + $not_in_nhance = []; + foreach ($allActiveTpaRows as $tpaRow) { + if (!in_array($tpaRow['emp_code'], $master_emp_codes, true)) { + // TPA member not found in Nhance master employee list for this client/policy. + $not_in_nhance[] = $tpaRow; + $recTypeById[(int) $tpaRow['id']] = 'not_in_nhance'; + } + } + + if (!empty($recTypeById)) { + $updateRows = []; + foreach ($recTypeById as $id => $recType) { + $updateRows[] = [ + 'id' => (int) $id, + 'rec_type' => $recType, + ]; + } + // Persist snapshot atomically so subsequent non-job calls can use cached mode. + $db = \Config\Database::connect(); + $db->transStart(); + $tpaApiDataModel->updateBatch($updateRows, 'id'); + $db->transComplete(); + } + } else { + // echo 'else';die; + // Cached mode: + // Read previously classified rows from rec_type, keep response shape compatible + // with existing UI/export (`mismatch_data` still contains DB row + match payload). + $not_in_nhance = $tpaApiDataModel->select('*') + ->where('is_active', 1) + ->where('file_id', $file_id) + ->where('rec_type', 'not_in_nhance') + ->findAll(); + + $needToReviewRows = $tpaApiDataModel->select('*') + ->where('is_active', 1) + ->where('file_id', $file_id) + ->where('rec_type', 'need_to_review') + ->findAll(); + + $needToReviewByEmpCode = []; + foreach ($needToReviewRows as $row) { + $needToReviewByEmpCode[$row['emp_code']][] = $row; + } + + $baseRows = $this->employeePolicyModel->getTPADataVariationReport($client_id, $client_policy_id, $file_id); + foreach ($baseRows as $db_row) { + $candidates = $needToReviewByEmpCode[$db_row['emp_code']] ?? []; + if (empty($candidates)) { + continue; + } + + $selectedTpa = null; + foreach ($candidates as $candidate) { + // Prefer same-relation row to mimic reconcileDbWithTpa relation matching. + if (strtolower((string) ($candidate['relation'] ?? '')) === strtolower((string) ($db_row['relationship'] ?? ''))) { + $selectedTpa = $candidate; + break; + } + } + if ($selectedTpa === null) { + $selectedTpa = $candidates[0]; + } + + $db_row['match'] = [ + 'status' => 'matched', + 'tpa_record' => $selectedTpa, + 'not_matching' => [], + ]; + $emp_data_wo_tpa_id[] = $db_row; + } } - // d($emp_data_wo_tpa_id); - - // die(); - //not_in_tpa - $tpa_emp_codes = $TpaApiDataModel->select('emp_code') + // Intentionally keep `not_in_tpa` live from current join/query logic + // (as requested) and do not source it from rec_type snapshot. + $tpa_emp_codes = $tpaApiDataModel->select('emp_code') ->where('file_id', $file_id) ->where('is_active', 1) ->groupBy('emp_code') ->findAll(); $tpa_emp_codes = array_column($tpa_emp_codes, 'emp_code'); - - $not_in_tpa = $this->employeePolicyModel->getTPADataVariationReport($client_id, $client_policy_id, $file_id,$tpa_emp_codes); - // d($not_in_tpa);die(); - - // not_in_nhance - $master_emp_codes = $this->employeePolicyModel->getTPADataVariationReport($client_id, $client_policy_id, $file_id,[],true); - $master_emp_codes = array_column($master_emp_codes, 'emp_code'); - - $not_in_nhance = $TpaApiDataModel->select('*') - ->where('is_active',1) - ->where('file_id',$file_id) - ->whereNotIn('emp_code',$master_emp_codes) - ->findAll(); - // d($not_in_nhance);die(); + $not_in_tpa = $this->employeePolicyModel->getTPADataVariationReport($client_id, $client_policy_id, $file_id, $tpa_emp_codes); if (!empty($not_in_tpa) || !empty($not_in_nhance) || !empty($emp_data_wo_tpa_id)) { - $response = [ - 'not_in_tpa' => $not_in_tpa, - 'not_in_nhance' => $not_in_nhance, - 'mismatch_data' => $emp_data_wo_tpa_id, + 'not_in_tpa' => $not_in_tpa, + 'not_in_nhance' => $not_in_nhance, + 'mismatch_data' => $emp_data_wo_tpa_id, ]; - - if ($type === 'internal') { - return $response; - }else if ($type === 'download') { + if ($type === 'view') { + return $this->respond(['status' => true, 'code' => 200, 'message' => '', 'data' => $response], 200); + } elseif ($type === 'download') { $this->exportVariationReportExcel($not_in_tpa, $not_in_nhance, $emp_data_wo_tpa_id); } else { - return $this->respond(['status' => true,'code' => 200,'message' => '','data' => $response,],200); + return $this->respond(['status' => true, 'code' => 200, 'message' => '', 'data' => $response], 200); } - } else { - - if ($type === 'internal') { + if ($type === 'view') { return []; } @@ -4101,12 +4236,13 @@ class EmployeeController extends AdminController return false; } - return $this->respond(['status' => false,'code' => 202,'message' => 'No data found','data' => [],],200); + return $this->respond(['status' => false, 'code' => 202, 'message' => 'No data found', 'data' => []], 200); } } public function proceedTPADataVariationNextStep($file_id) { + // echo $file_id;die; try { if (empty($file_id)) { return $this->respond( @@ -4153,6 +4289,24 @@ class EmployeeController extends AdminController 200 ); } + + if($generationResult['status']) + { + if($generationResult['data']['file_id']) + { + //initiate update references b/w tpa_api_data and employess + //initiate deleteion if any + } + else + { + //seems inception file id not there just put a log + $this->myLogger->logme( + 'error', + 'TPA RECON | Inception file id missing after generating employee upload from Not in Nhance data for file_id:' + ); + + } + } } elseif ($tab === 'need_to_review') { // For the "Need to Review" tab, generate a Correction Excel // using the same overall pipeline as the Not in Nhance implementation. @@ -6167,4 +6321,218 @@ class EmployeeController extends AdminController return rmdir($dir); } + /** + * Reconcile TPA API rows with Nhance employee + employee policy records. + * + * Why this function exists: + * - TPA ingestion stores raw member rows in `tpa_api_data`. + * - Downstream processing may need a stable linkage back to the exact + * `employee_polices.id` record that represents that member in Nhance. + * - This method resolves that linkage and writes it into `tpa_api_data.ref`. + * + * Matching strategy: + * 1) Resolve candidate Nhance members by `emp_code` scoped to the same file's + * client and policy context. + * 2) Perform strict exact match on: + * - emp_code + * - name + * - dob + * - gender + * - relation/relationship + * 3) Update `tpa_api_data.ref` only when the exact match is found. + * + * Important behavior: + * - Only active rows are considered on both sides. + * - Already linked rows (`ref` present) are skipped to avoid accidental override. + * - Updates are done in batch and wrapped in DB transaction for consistency. + * + * @param int|string $file_id Batch file id whose TPA rows must be reconciled. + * + * @return array{ + * status: bool, + * message: string, + * data: array{ + * file_id:int, + * scanned:int, + * matched:int, + * skipped_already_mapped:int, + * unmatched:int + * } + * } + */ + public function reconTpaApiDataWithEmployeepolicies($file_id): array + { + try { + $fileId = (int) $file_id; + if ($fileId <= 0) { + return [ + 'status' => false, + 'message' => 'Invalid file id provided.', + 'data' => [], + ]; + } + + $fileInfo = $this->batchFileModel->find($fileId); + if (empty($fileInfo)) { + return [ + 'status' => false, + 'message' => 'Batch file not found.', + 'data' => ['file_id' => $fileId], + ]; + } + + $clientId = (int) ($fileInfo['client_id'] ?? 0); + $clientPolicyId = (int) ($fileInfo['client_policy_id'] ?? 0); + if ($clientId <= 0 || $clientPolicyId <= 0) { + return [ + 'status' => false, + 'message' => 'Client/policy context missing for provided file id.', + 'data' => ['file_id' => $fileId], + ]; + } + + $db = \Config\Database::connect(); + + // Pull only active TPA rows for this file. We include `ref` to skip + // rows that are already mapped by any previous reconciliation run. + $tpaRows = $db->table('tpa_api_data') + ->select('id, emp_code, name, dob, relation, gender, ref') + ->where('file_id', $fileId) + ->where('is_active', 1) + ->get() + ->getResultArray(); + + if (empty($tpaRows)) { + return [ + 'status' => true, + 'message' => 'No active TPA rows found for reconciliation.', + 'data' => [ + 'file_id' => $fileId, + 'scanned' => 0, + 'matched' => 0, + 'skipped_already_mapped' => 0, + 'unmatched' => 0, + ], + ]; + } + + // Build Nhance-side candidate pool once, keyed by emp_code. + // Each candidate represents an active employee policy member. + $dbMembers = $db->table('employee_polices ep') + ->select(' + ep.id AS employee_policy_id, + emp.emp_code, + emp.name, + emp.relationship, + emp.dob, + emp.gender + ') + ->join('employees emp', 'ep.employee_id = emp.id') + ->where('ep.is_active', 1) + ->where('ep.status', 'active') + ->where('ep.client_policy_id', $clientPolicyId) + ->where('emp.client_id', $clientId) + ->where('emp.is_active', 1) + ->get() + ->getResultArray(); + + $membersByEmpCode = []; + foreach ($dbMembers as $member) { + $membersByEmpCode[$member['emp_code']][] = $member; + } + + $updates = []; + $matched = 0; + $skipped = 0; + $unmatched = 0; + + $normalize = static function ($value): string { + return strtolower(trim((string) $value)); + }; + + foreach ($tpaRows as $tpaRow) { + $existingRef = trim((string) ($tpaRow['ref'] ?? '')); + if ($existingRef !== '') { + $skipped++; + continue; + } + + $empCode = (string) ($tpaRow['emp_code'] ?? ''); + $candidates = $membersByEmpCode[$empCode] ?? []; + if (empty($candidates)) { + $unmatched++; + continue; + } + + $tName = $normalize($tpaRow['name'] ?? ''); + $tRel = $normalize($tpaRow['relation'] ?? ''); + $tDob = (string) ($tpaRow['dob'] ?? ''); + $tGender = strtoupper(trim((string) ($tpaRow['gender'] ?? ''))); + + // Strict exact matching only (no fallback): + // emp_code is already scoped via $membersByEmpCode. + // Remaining fields must all match together. + $picked = null; + foreach ($candidates as $candidate) { + $nameOk = $normalize($candidate['name'] ?? '') === $tName; + $relOk = $normalize($candidate['relationship'] ?? '') === $tRel; + $dobOk = (string) ($candidate['dob'] ?? '') === $tDob; + $genOk = strtoupper(trim((string) ($candidate['gender'] ?? ''))) === $tGender; + if ($nameOk && $relOk && $dobOk && $genOk) { + $picked = $candidate; + break; + } + } + + if ($picked === null) { + $unmatched++; + continue; + } + + $updates[] = [ + 'id' => (int) $tpaRow['id'], + 'ref' => (int) $picked['employee_policy_id'], + ]; + $matched++; + } + + if (!empty($updates)) { + $db->transStart(); + $db->table('tpa_api_data')->updateBatch($updates, 'id'); + $db->transComplete(); + } + + $payload = [ + 'file_id' => $fileId, + 'scanned' => count($tpaRows), + 'matched' => $matched, + 'skipped_already_mapped' => $skipped, + 'unmatched' => $unmatched, + ]; + + $this->myLogger->logme('error', 'TPA ref reconciliation completed: ' . json_encode($payload)); + + return [ + 'status' => true, + 'message' => 'TPA rows reconciled with employee policies successfully.', + 'data' => $payload, + ]; + } catch (\Throwable $e) { + $this->myLogger->logme( + 'error', + 'Error in reconTpaApiDataWithEmployeepolicies: ' . $e->getMessage(), + ['file_id' => $file_id] + ); + + return [ + 'status' => false, + 'message' => 'Unable to reconcile TPA rows with employee policies.', + 'data' => [ + 'file_id' => (int) $file_id, + 'error' => $e->getMessage(), + ], + ]; + } + } + } diff --git a/app/Controllers/EmployeeRestController.php b/app/Controllers/EmployeeRestController.php index affdd7dc..dd2464f0 100755 --- a/app/Controllers/EmployeeRestController.php +++ b/app/Controllers/EmployeeRestController.php @@ -1632,7 +1632,7 @@ class EmployeeRestController extends AdminController if (! empty($client)) { $client['client_logo'] = base_url() . 'public/uploads/logo/' . $client['client_logo']; - $clientPolicy = $this->clientPolicyModel->where('client_id', $client['id']) + $clientPolicy = $this->clientPolicyModel->where('client_id', $client['id']) ->where('client_branch_id', $this->request->getGet('client_branch_id'))->findAll(); return $this->respond(['status' => 'success', 'code' => 200, 'data' => ['client' => $client, 'client_policy' => $clientPolicy]], 200); } else { @@ -2413,6 +2413,7 @@ class EmployeeRestController extends AdminController ->select('id,ticket_type, display_name as claim_status') ->where('is_active', 1) ->where('display_name IS NOT NULL OR display_name <> ""') + ->whereIn('claim_status_id',[1,2,3,4]) ->groupBy('display_name') ->findAll(); @@ -3751,6 +3752,8 @@ class EmployeeRestController extends AdminController // $fetchData['relationship'] = strtolower($fetchData['relationship']) ?? $fetchData['relationship']; $fetchData['relationship'] = isset($fetchData['relationship']) ? strtolower($fetchData['relationship']) : null; + $fetchData['created_by'] = $fetchData['emp_id']; + $fetchData['claim_created_by'] = "USER"; // print_r($fetchData); die; $insert_status = $this->ticketMaster->insert($fetchData); @@ -4523,7 +4526,7 @@ class EmployeeRestController extends AdminController // print_r($post_data); die; - $ClientPolicyData = $this->clientPolicyModel + $Query = $this->clientPolicyModel ->select(" client_policy.id as client_policy_id , client_policy.client_id as client_id, @@ -4540,10 +4543,14 @@ class EmployeeRestController extends AdminController ->join('policy_type', 'policy_type.id = client_policy.policy_type_id', 'left') ->where('md5(client_policy.client_id)', $post_data['client_id']) ->where('client_policy.client_branch_id', $post_data['client_branch_id']) - ->where('client_policy.is_active', 1) + ->where('client_policy.is_active', 1); // ->where('client_policy.policy_status', $this->request->getGet('policy_status')) - ->whereIn('client_policy.id', $post_data['policy_id']) - ->first(); + if(is_array($post_data['policy_id'])){ + $Query->whereIn('client_policy.id', $post_data['policy_id']); + }else{ + $Query->where('client_policy.id', $post_data['policy_id']); + } + $ClientPolicyData = $Query->first(); if (empty($post_data['client_id'])) { return $this->respondCreated(['status' => false, 'message' => 'Client is required', 'data' => []]); diff --git a/app/Controllers/FhplApiController.php b/app/Controllers/FhplApiController.php index f43430f4..532776ff 100644 --- a/app/Controllers/FhplApiController.php +++ b/app/Controllers/FhplApiController.php @@ -785,7 +785,8 @@ class FhplApiController extends BaseController 'doa'=>$row['DATE_OF_ADMISSION'], 'dod'=>$row['DATE_OF_DISCHARGE'], 'claim_status_id'=>$claimStatus, - 'tpa_id'=>$this->fhplTpaId + 'tpa_id'=>$this->fhplTpaId, + 'claim_created_by'=>'TPA', ]); } @@ -974,6 +975,7 @@ class FhplApiController extends BaseController 'tpa_claim_type' => $row['CLAIM_TYPE'] ?? null, 'tpa_ailments' => $row['AILMENT'] ?? null, + 'claim_created_by' => 'TPA', 'created_at' => date('Y-m-d H:i:s'), ]; @@ -1037,6 +1039,7 @@ class FhplApiController extends BaseController 'is_active' => 1, 'created_by' => $file_info[0]['created_by'] ?? null, + 'action_flag_status' => $row['IsActive'] == 1 ? 'A' : 'D' ]; } diff --git a/app/Controllers/HealthIndiaApiController.php b/app/Controllers/HealthIndiaApiController.php index 01e86c12..0552700a 100644 --- a/app/Controllers/HealthIndiaApiController.php +++ b/app/Controllers/HealthIndiaApiController.php @@ -20,6 +20,7 @@ class HealthIndiaApiController extends BaseController protected $db; protected $healthIndiaTpaId; protected $claim_type_array; + protected $ticketController; public function __construct() { @@ -802,6 +803,7 @@ class HealthIndiaApiController extends BaseController 'dod' => !empty($row['DATEOF_DISCHARGE']) ? date('Y-m-d', strtotime($row['DATEOF_DISCHARGE'])) : null, 'claim_status_id' => $claimStatus, 'tpa_id' => $this->healthIndiaTpaId, + 'claim_created_by'=> 'TPA', 'created_at' => date('Y-m-d H:i:s') ]); $insertedCount++; @@ -1010,6 +1012,7 @@ class HealthIndiaApiController extends BaseController // TPA extras 'tpa_claim_status' => $status, + 'claim_created_by' => 'TPA', 'created_at' => date('Y-m-d H:i:s'), ]; @@ -1066,6 +1069,7 @@ class HealthIndiaApiController extends BaseController 'is_active' => 1, 'created_by' => $file_info[0]['created_by'] ?? null, + 'action_flag_status' => $row['insuredStatus'] == 'Active' ? 'A' : 'D' ]; } // log_message('error','HEALTH_INDIA - COUNT' . count($mappedRows)); diff --git a/app/Controllers/LeadsController.php b/app/Controllers/LeadsController.php index b6f5f35f..765afe8f 100644 --- a/app/Controllers/LeadsController.php +++ b/app/Controllers/LeadsController.php @@ -4774,7 +4774,7 @@ class LeadsController extends BaseController // πŸ”Ή Client Details (Single Row) $data['actual_lead_client_details'] = $this->leadModel - ->select('sales_actual_leads.company_name, clients.short_name, sales_actual_leads.email, sales_actual_leads.phone, sales_actual_leads.address, sales_actual_leads.website, sales_actual_leads.gst_number, sales_actual_leads.status, sales_actual_leads.assigned_to') + ->select('sales_actual_leads.company_name, clients.short_name, clients.client_type, sales_actual_leads.email, sales_actual_leads.phone, sales_actual_leads.address, sales_actual_leads.website, sales_actual_leads.gst_number, sales_actual_leads.status, sales_actual_leads.assigned_to') ->join('clients', 'clients.id = sales_actual_leads.client_id', 'left') ->where('sales_actual_leads.lead_id', $actual_lead_id) ->first(); // first row only @@ -5527,7 +5527,7 @@ class LeadsController extends BaseController * * @param string $recipientType insurer|client|internal */ - protected function downloadFileFromGoogleSheet(array $lead_data, string $recipientType = 'insurer'): array + protected function downloadFileFromGoogleSheet(array $lead_data, string $recipientType = 'insurer'): ?array { try { $leadId = (int) ($lead_data['id'] ?? 0); diff --git a/app/Controllers/MediAssistApiController.php b/app/Controllers/MediAssistApiController.php index 3a70329b..f4ceaff6 100644 --- a/app/Controllers/MediAssistApiController.php +++ b/app/Controllers/MediAssistApiController.php @@ -506,7 +506,7 @@ class MediAssistApiController extends BaseController tm.id, tm.tpa_no as memberId, tm.tpa_claim_push_reference_no as claimRefNo, - tm.tpa_claim_id, + tm.tpa_claim_id,tm.doa, tm.claim_number, cp.policy_no as policyNo, cp.policy_start_date as startDate, @@ -596,7 +596,7 @@ class MediAssistApiController extends BaseController "Confirmation Awaited" => 4, "Information Awaited Reminder" => 4, "Information Awaited Final Reminder" => 4, - "Insurer Concurrence Awaited" => 6, + "Insurer Concurrence Awaited" => 7, "Closed" => 12, "Physical Documents Awaited" => 9, @@ -807,7 +807,7 @@ class MediAssistApiController extends BaseController 'gender' => strtoupper($row['benefSex'] ?? null), 'self' => strtolower($row['relName'] ?? '') === 'self' ? 1 : 0, - 'si' => $row['sum_insured'] ?? null, + 'si' => $row['sum_Insured'] ?? null, 'doj' => $this->mediDate($row['benefWEF'] ?? null), @@ -845,7 +845,7 @@ class MediAssistApiController extends BaseController tm.id, tm.tpa_no as memberId, tm.tpa_claim_push_reference_no as claimRefNo, - tm.doa, + tm.doa,tm.claim_no, cp.policy_no as policyNo, cp.policy_start_date as startDate, cp.policy_end_date as endDate, @@ -944,7 +944,7 @@ class MediAssistApiController extends BaseController "Confirmation Awaited" => 4, "Information Awaited Reminder" => 4, "Information Awaited Final Reminder" => 4, - "Insurer Concurrence Awaited" => 6, + "Insurer Concurrence Awaited" => 7, "Closed" => 12, "Physical Documents Awaited" => 9, @@ -1191,7 +1191,7 @@ class MediAssistApiController extends BaseController "Confirmation Awaited" => 4, "Information Awaited Reminder" => 4, "Information Awaited Final Reminder" => 4, - "Insurer Concurrence Awaited" => 6, + "Insurer Concurrence Awaited" => 7, "Closed" => 12, "Physical Documents Awaited" => 9, @@ -1317,6 +1317,9 @@ class MediAssistApiController extends BaseController //others 'tpa_claim_type' => $value['typE_OF_CLAIM'], 'tpa_ailments' => ($value['ailment'] ?? '') . ' - ' . ($value['ailmenT_DESC'] ?? ''), + 'claim_created_by' => 'TPA', + 'tpa_claim_push_reference_no' => $value['clM_COMP_REFNO'] ?? null, + ]; diff --git a/app/Controllers/TicketController.php b/app/Controllers/TicketController.php index 146b748e..928f630a 100644 --- a/app/Controllers/TicketController.php +++ b/app/Controllers/TicketController.php @@ -737,6 +737,8 @@ class TicketController extends BaseController public function ticket_form($ticket_type) { $data = $this->ticket_form_data($ticket_type); + $data['tab_name'] = "Claims"; + $data['page_name'] = "Claims"; // dd($data); return $this->loadLayout('ticket_form_handler', $data); } @@ -1492,6 +1494,7 @@ class TicketController extends BaseController if ($ticket_data) { + $ticket_data['claim_created_by'] = "CRM"; $return_value = $this->ticketMasterModel->insert($ticket_data); if ($return_value) { //mail trigger part @@ -1936,7 +1939,7 @@ class TicketController extends BaseController ]); } $data = $this->request->getPost(); - $received_data = sanitizeInputArrayAdvanced($data); + $received_data = sanitizeInputArrayAdvanced($data, ['mail_content']); if (isset($received_data['id']) && $received_data['id'] != '') { $status = $this->ticketMailTemplateModel->save($received_data); diff --git a/app/Controllers/TicketServiceController.php b/app/Controllers/TicketServiceController.php index 8e96a780..24e5e463 100644 --- a/app/Controllers/TicketServiceController.php +++ b/app/Controllers/TicketServiceController.php @@ -1440,6 +1440,7 @@ class TicketServiceController extends AdminController if(!empty($data)){ $data['file_id'] = $file_id; + $data['claim_created_by'] = "DUMP"; //insert the claim data to ticket master table $insert = $ticketMasterModal->insert($data); $inserted_claim_list[] = $insert; diff --git a/app/Controllers/VidalApiController.php b/app/Controllers/VidalApiController.php index 23394231..06a78a57 100644 --- a/app/Controllers/VidalApiController.php +++ b/app/Controllers/VidalApiController.php @@ -1617,6 +1617,7 @@ class VidalApiController extends BaseController 'doj' => $doj, 'is_active' => 1, 'created_by' => $file_info[0]['created_by'] ?? null, + 'action_flag_status' => $row['isDeleted'] == 0 ? 'D' : 'A' ]; } diff --git a/app/Filters/GlobalPostFileUploadGuard.php b/app/Filters/GlobalPostFileUploadGuard.php index d5b3f4c8..5b303056 100644 --- a/app/Filters/GlobalPostFileUploadGuard.php +++ b/app/Filters/GlobalPostFileUploadGuard.php @@ -136,7 +136,7 @@ class GlobalPostFileUploadGuard implements FilterInterface $response->setStatusCode(403) ->setJSON([ 'status' => 'error', - 'message' => 'File upload rejected: Security policy violation.', + 'message' => 'File upload rejected: Security policy violation.' . ($reason ? " Reason: $reason." : ''), 'debug' => (ENVIRONMENT === 'development') ? $reason : null ]) ->send(); diff --git a/app/Libraries/TPAClaimsImportServices/AbhiClaimImportService.php b/app/Libraries/TPAClaimsImportServices/AbhiClaimImportService.php index 103989bf..4f6ff966 100644 --- a/app/Libraries/TPAClaimsImportServices/AbhiClaimImportService.php +++ b/app/Libraries/TPAClaimsImportServices/AbhiClaimImportService.php @@ -366,7 +366,7 @@ class AbhiClaimImportService extends BaseTpaClaimImportService $item['priority'] = 1; $item['mode_of_intimation'] = 5; $item['ticket_type_id'] = 1; - + $item['claim_created_by'] = 'DUMP_TPA'; $mapped[] = $item; } diff --git a/app/Libraries/TPAClaimsImportServices/FhplClaimImportService.php b/app/Libraries/TPAClaimsImportServices/FhplClaimImportService.php index 7123230c..f2de776f 100644 --- a/app/Libraries/TPAClaimsImportServices/FhplClaimImportService.php +++ b/app/Libraries/TPAClaimsImportServices/FhplClaimImportService.php @@ -432,6 +432,7 @@ class FhplClaimImportService extends BaseTpaClaimImportService $item['priority'] = 1; $item['mode_of_intimation'] = 5; $item['ticket_type_id'] = 1; + $item['claim_created_by'] = 'DUMP_TPA'; $mapped[] = $item; } diff --git a/app/Libraries/TPAClaimsImportServices/IciciClaimImportService.php b/app/Libraries/TPAClaimsImportServices/IciciClaimImportService.php index 6e055139..736d9f5a 100644 --- a/app/Libraries/TPAClaimsImportServices/IciciClaimImportService.php +++ b/app/Libraries/TPAClaimsImportServices/IciciClaimImportService.php @@ -347,6 +347,7 @@ class IciciClaimImportService extends BaseTpaClaimImportService $item['priority'] = 1; $item['mode_of_intimation'] = 5; $item['ticket_type_id'] = 1; + $item['claim_created_by'] = 'DUMP_TPA'; $mapped[] = $item; } diff --git a/app/Libraries/TPAClaimsImportServices/MediAssistClaimImportService.php b/app/Libraries/TPAClaimsImportServices/MediAssistClaimImportService.php index 4a2952fb..a853ade6 100644 --- a/app/Libraries/TPAClaimsImportServices/MediAssistClaimImportService.php +++ b/app/Libraries/TPAClaimsImportServices/MediAssistClaimImportService.php @@ -380,6 +380,7 @@ class MediAssistClaimImportService extends BaseTpaClaimImportService $item['priority'] = 1; $item['mode_of_intimation'] = 5; $item['ticket_type_id'] = 1; + $item['claim_created_by'] = 'DUMP_TPA'; $mapped[] = $item; } diff --git a/app/Libraries/TPAClaimsImportServices/RcareClaimImportService.php b/app/Libraries/TPAClaimsImportServices/RcareClaimImportService.php index afe95c4f..dc9cf54a 100644 --- a/app/Libraries/TPAClaimsImportServices/RcareClaimImportService.php +++ b/app/Libraries/TPAClaimsImportServices/RcareClaimImportService.php @@ -332,7 +332,7 @@ class RcareClaimImportService extends BaseTpaClaimImportService $item['priority'] = 1; $item['mode_of_intimation'] = 5; $item['ticket_type_id'] = 1; - + $item['claim_created_by'] = 'DUMP_TPA'; $mapped[] = $item; } diff --git a/app/Libraries/TPAClaimsImportServices/VidalClaimImportService.php b/app/Libraries/TPAClaimsImportServices/VidalClaimImportService.php index 70a1340c..b263109c 100644 --- a/app/Libraries/TPAClaimsImportServices/VidalClaimImportService.php +++ b/app/Libraries/TPAClaimsImportServices/VidalClaimImportService.php @@ -573,6 +573,7 @@ class VidalClaimImportService extends BaseTpaClaimImportService $item['priority'] = 1; $item['mode_of_intimation'] = 5; $item['ticket_type_id'] = 1; + $item['claim_created_by'] = 'DUMP_TPA'; $mapped[] = $item; } @@ -687,7 +688,8 @@ class VidalClaimImportService extends BaseTpaClaimImportService $item['file_id'] = $file_id; $item['created_by'] = get_session_userid() ?? null; $item['claim_type'] = isset($row['mainclaim_prepost_type']) && !empty($row['mainclaim_prepost_type']) && strtolower($row['mainclaim_prepost_type']) == 'normal' ? 1 : 3; - + $item['claim_created_by'] = 'DUMP_TPA'; + $mapped[] = $item; } diff --git a/app/Models/TicketMasterModel.php b/app/Models/TicketMasterModel.php index d78402b6..475df9b1 100644 --- a/app/Models/TicketMasterModel.php +++ b/app/Models/TicketMasterModel.php @@ -95,6 +95,8 @@ class TicketMasterModel extends Model 'tpa_ailments', 'claim_dump_ref_id', 'last_updated_by', + 'tpa_shortfall_no', + 'claim_created_by', ]; diff --git a/app/Models/TpaApiDataModel.php b/app/Models/TpaApiDataModel.php index e63193b3..af3feb11 100644 --- a/app/Models/TpaApiDataModel.php +++ b/app/Models/TpaApiDataModel.php @@ -27,7 +27,8 @@ class TpaApiDataModel extends Model 'desc', 'created_by', 'si', - 'doj' + 'doj', + 'rec_type' ]; // protected $useTimestamps = true; diff --git a/app/Views/batch_list.php b/app/Views/batch_list.php index f368adcd..9e5f256b 100755 --- a/app/Views/batch_list.php +++ b/app/Views/batch_list.php @@ -1,15 +1,105 @@ + $file) { + $batch_col_max_len[0] = max($batch_col_max_len[0], mb_strlen((string) ($key + 1))); + $batch_col_max_len[1] = max($batch_col_max_len[1], mb_strlen((string) ($file['batch_code'] ?? ''))); + $batch_col_max_len[2] = max($batch_col_max_len[2], mb_strlen((string) ($file['file_name'] ?? ''))); + $batch_col_max_len[3] = max($batch_col_max_len[3], mb_strlen((string) ($file['client_short_name'] ?? ''))); + $batch_col_max_len[4] = max($batch_col_max_len[4], mb_strlen((string) ($file['branch_name'] ?? ''))); + $policy_display_len = trim( + (isset($file['policy_type']) ? $file['policy_type'] : '') + . ' - ' + . (isset($file['policy_no']) ? $file['policy_no'] : '') + ); + $batch_col_max_len[5] = max($batch_col_max_len[5], mb_strlen($policy_display_len)); + $batch_col_max_len[6] = max($batch_col_max_len[6], mb_strlen((string) ($file['event_type'] ?? ''))); + $insLabel = $insurer_or_tpa[$file['insurer_or_tpa'] ?? ''] ?? ''; + $batch_col_max_len[7] = max($batch_col_max_len[7], mb_strlen((string) $insLabel)); + $actKey = $file['actions'] ?? ''; + $actLabel = $import_or_export[$actKey] ?? ucfirst((string) $actKey); + $batch_col_max_len[8] = max($batch_col_max_len[8], mb_strlen((string) $actLabel)); + $countStr = ($file['count'] ?? null) === null ? '-' : (string) $file['count']; + $batch_col_max_len[9] = max($batch_col_max_len[9], mb_strlen($countStr)); + $batch_col_max_len[10] = max($batch_col_max_len[10], mb_strlen((string) format_indian_number($file['amount']))); + $userTime = change_date_format($file['created_at'] ?? '', 'Y-m-d H:i:s', 'd M Y h:i a') + . ' by ' + . get_username($file['created_by'] ?? ''); + $batch_col_max_len[11] = max($batch_col_max_len[11], mb_strlen($userTime)); + $batch_col_max_len[12] = max($batch_col_max_len[12], mb_strlen((string) ($file['status'] ?? ''))); + $batch_col_max_len[13] = max($batch_col_max_len[13], 2); + } +} + +$batch_col_min_px = [48, 72, 100, 72, 80, 120, 88, 96, 72, 56, 80, 160, 96, 52]; +$batch_col_max_px = [64, 220, 480, 240, 240, 640, 200, 200, 140, 110, 160, 560, 320, 64]; +$batch_col_width_px = []; +for ($i = 0; $i < $batch_col_count; $i++) { + $chars = max($batch_col_max_len[$i], mb_strlen($batch_header_labels[$i])); + $px = (int) round($chars * 7.0 + 26); + $batch_col_width_px[$i] = min( + $batch_col_max_px[$i], + max($batch_col_min_px[$i], $px) + ); +} +?>
@@ -130,7 +239,7 @@
- +
@@ -159,15 +268,34 @@ - - + + - + + + @@ -347,7 +475,7 @@
S.No 
+ - + + + + +
diff --git a/app/Views/client_basic_info.php b/app/Views/client_basic_info.php index d2bae3a3..4cf5ab23 100755 --- a/app/Views/client_basic_info.php +++ b/app/Views/client_basic_info.php @@ -162,7 +162,7 @@ input:checked + .slider:before { - Allowed: PNG, JPG, JPEG. Size : 200KB Dimension : 100 X 100 Pixels + Allowed: JPG, JPEG, PNG. Size : 200KB Dimension : 100 X 100 Pixels
@@ -465,7 +465,7 @@ input:checked + .slider:before { $.each(res.data, function (index, item) { var row = ` -
${item.file_name}

Allowed: PNG, JPG, JPEG. +

Allowed: JPG, JPEG, PNG. diff --git a/app/Views/file_list.php b/app/Views/file_list.php index 759cdba6..1fcba673 100755 --- a/app/Views/file_list.php +++ b/app/Views/file_list.php @@ -220,7 +220,7 @@ - Allowed: XLS, XLSX. Size : 25MB Dimension : 100 X 100 + Allowed: XLS, XLSX. Size : 25MB diff --git a/app/Views/hr_file_upload.php b/app/Views/hr_file_upload.php index 62979743..50464d26 100644 --- a/app/Views/hr_file_upload.php +++ b/app/Views/hr_file_upload.php @@ -230,7 +230,7 @@ - Allowed: XLS, XLSX. Size : 25MB Dimension : 100 X 100 + Allowed: XLS, XLSX. Size : 25MB diff --git a/app/Views/import_export.php b/app/Views/import_export.php index 89584e0f..84fe0c7c 100755 --- a/app/Views/import_export.php +++ b/app/Views/import_export.php @@ -258,7 +258,7 @@ table.dataTable thead th {