Merge branch 'dev' of bitbucket.org:jubilian/nhance into dev
This commit is contained in:
commit
d4215c2409
1
.gitignore
vendored
1
.gitignore
vendored
@ -34,4 +34,5 @@ composer.lock
|
||||
.env
|
||||
.phpunit*
|
||||
phpqueue.sh
|
||||
.claude
|
||||
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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(),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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' => []]);
|
||||
|
||||
@ -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'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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,
|
||||
@ -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,
|
||||
@ -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,
|
||||
|
||||
|
||||
];
|
||||
|
||||
|
||||
@ -1494,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
|
||||
@ -1938,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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
|
||||
@ -95,6 +95,8 @@ class TicketMasterModel extends Model
|
||||
'tpa_ailments',
|
||||
'claim_dump_ref_id',
|
||||
'last_updated_by',
|
||||
'tpa_shortfall_no',
|
||||
'claim_created_by',
|
||||
|
||||
];
|
||||
|
||||
|
||||
@ -27,7 +27,8 @@ class TpaApiDataModel extends Model
|
||||
'desc',
|
||||
'created_by',
|
||||
'si',
|
||||
'doj'
|
||||
'doj',
|
||||
'rec_type'
|
||||
];
|
||||
|
||||
// protected $useTimestamps = true;
|
||||
|
||||
@ -286,7 +286,16 @@ for ($i = 0; $i < $batch_col_count; $i++) {
|
||||
data-placement="top"
|
||||
title="<?= esc($policy_display) ?>"><?= esc($policy_display) ?></td>
|
||||
<td><?php echo $file['event_type'] ?></td>
|
||||
<td><?php echo esc($insurer_or_tpa[$file['insurer_or_tpa'] ?? ''] ?? '') ?></td>
|
||||
|
||||
<td><?php echo $insurer_or_tpa[$file['insurer_or_tpa']] ?>
|
||||
|
||||
<?php $insurer_or_tpa_display = $insurer_or_tpa[$file['insurer_or_tpa']] == 'TPA' ? $file['tpa_short_name'] : $file['insurer_short_name'] ?>
|
||||
<a href=""
|
||||
class="fe-alert-circle" style="color: #000;" aria-hidden="true"
|
||||
data-toggle="tooltip" data-placement="top" title="<?php echo $insurer_or_tpa_display ?>"></a>
|
||||
|
||||
</td>
|
||||
|
||||
<td><?php echo $import_or_export[$file['actions']] ?? ucfirst($file['actions']) ?></td>
|
||||
<td><?php echo $file['count'] == null ? '-' : $file['count'] ?></td>
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user