Merge_code

This commit is contained in:
sanjeev.p 2026-03-12 15:27:06 +05:30
commit 0498873ec5
26 changed files with 2167 additions and 359 deletions

View File

@ -15,6 +15,13 @@ class Acl
'#^/loginPos#' => ['public' => true],
'#^/getVerifyPosMobileNo#' => ['public' => true],
'#^/getVerifiedPosUserData#' => ['public' => true],
'#^/chat#' => ['public' => true],
'#^/widget#' => ['public' => true],
'#^/chatbottest#' => ['public' => true],
'#^/chatbot#' => ['public' => true],
'#^/getSSORedirectUrl#' => ['public' => true],
'#^/getEmployeePolicy#' => ['public' => true],
'#^/downloadFileTableFile#' => ['public' => true],
'#^/swagger#' => ['roles' => [ADMIN_ROLE_ID]],
'#^/getEmployeeActiveOrInactivePolicy#' => ['roles' => [ADMIN_ROLE_ID, HEAD_ROLE_ID]],
'#^/bulkEcardDownloadAsZip#' => ['roles' => [ADMIN_ROLE_ID, HEAD_ROLE_ID]],
@ -54,6 +61,34 @@ class Acl
'roles' => [ ADMIN_ROLE_ID,HEAD_ROLE_ID, MANAGER_ROLE_ID, STAFF_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => []
],
'#^/hrFileDownload#' => [
'roles' => [ ADMIN_ROLE_ID,HEAD_ROLE_ID, MANAGER_ROLE_ID, STAFF_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => []
],
'#^/sendPushNotification#' => [
'roles' => [ ADMIN_ROLE_ID,HEAD_ROLE_ID, MANAGER_ROLE_ID, STAFF_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => []
],
'#^/sendEmail#' => [
'roles' => [ ADMIN_ROLE_ID,HEAD_ROLE_ID, MANAGER_ROLE_ID, STAFF_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => []
],
'#^/getPolicyLevelEmployeeSummaryData#' => [
'roles' => [ ADMIN_ROLE_ID,HEAD_ROLE_ID, MANAGER_ROLE_ID, STAFF_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => []
],
'#^/cdTransactionData#' => [
'roles' => [ ADMIN_ROLE_ID,HEAD_ROLE_ID, MANAGER_ROLE_ID, STAFF_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => []
],
'#^/claimsSearch#' => [
'roles' => [ ADMIN_ROLE_ID,HEAD_ROLE_ID, MANAGER_ROLE_ID, STAFF_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [CLAIMS_TEAM_ID]
],
'#^/getBackToEnrolledDetails#' => [
'roles' => [ ADMIN_ROLE_ID,HEAD_ROLE_ID, MANAGER_ROLE_ID, STAFF_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => []
],
// ===================== USER MANAGEMENT =====================
'#^/user#' => [
@ -88,6 +123,18 @@ class Acl
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [FINANCE_TEAM_ID,POS_TEAM_ID]
],
'#^/dmsSearch#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [FINANCE_TEAM_ID,POS_TEAM_ID]
],
'#^/downloadGdriveFile#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [FINANCE_TEAM_ID,POS_TEAM_ID]
],
'#^/driveListFiles#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [FINANCE_TEAM_ID,POS_TEAM_ID]
],
'#^/bds_upload#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [FINANCE_TEAM_ID,POS_TEAM_ID]
@ -108,12 +155,60 @@ class Acl
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [FINANCE_TEAM_ID,POS_TEAM_ID]
],
'#^/importRules#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [FINANCE_TEAM_ID,POS_TEAM_ID]
],
// ===================== CLAIMS / TICKETS =====================
'#^/ticket#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [CLAIMS_TEAM_ID]
],
'#^/ticketSave#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [CLAIMS_TEAM_ID]
],
'#^/ticketList#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [CLAIMS_TEAM_ID]
],
'#^/ticketConversationSave#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [CLAIMS_TEAM_ID]
],
'#^/ticketConversationList#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [CLAIMS_TEAM_ID]
],
'#^/ticketType#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [CLAIMS_TEAM_ID]
],
'#^/ticketHistoryList#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [CLAIMS_TEAM_ID]
],
'#^/ticketAutoFetchDetails#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [CLAIMS_TEAM_ID]
],
'#^/initiateClaim#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [CLAIMS_TEAM_ID]
],
'#^/departments#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [CLAIMS_TEAM_ID]
],
'#^/get_ticket_data#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [CLAIMS_TEAM_ID]
],
'#^/claimView#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [CLAIMS_TEAM_ID]
],
'#^/claim_mis#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID],
'teams' => [CLAIMS_TEAM_ID]
@ -138,6 +233,22 @@ class Acl
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID,STAFF_ROLE_ID],
'teams' => []
],
'#^/add_advertise_image#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID,STAFF_ROLE_ID],
'teams' => []
],
'#^/remove_advertise_image#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID,STAFF_ROLE_ID],
'teams' => []
],
'#^/getAdvertiseImage#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID,STAFF_ROLE_ID],
'teams' => []
],
'#^/showAdvertiseImage#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID,STAFF_ROLE_ID],
'teams' => []
],
'#^/frontend_content#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID,STAFF_ROLE_ID],
'teams' => []
@ -146,6 +257,10 @@ class Acl
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID,STAFF_ROLE_ID],
'teams' => []
],
'#^/getFEContent#' => [
'roles' => [ HEAD_ROLE_ID,ADMIN_ROLE_ID, MANAGER_ROLE_ID, ACCOUNT_MANAGER_ROLE_ID,STAFF_ROLE_ID],
'teams' => []
],
// ===================== LOGS =====================
'#^/logs#' => [
@ -167,9 +282,25 @@ class Acl
// ===================== WEBHOOKS / 3RD PARTY =====================
'#^/dispatchWebhookData#' => ['public' => true],
'#^/retrieveWebhookData#' => ['public' => true],
// '#^/ICICI#' => ['public' => true],
// '#^/Vidal#' => ['public' => true],
// '#^/MediAssist#' => ['public' => true],
'#^/ecardRequest#' => ['public' => true],
'#^/getTPAID#' => ['public' => true],
'#^/fileDownload#' => ['public' => true],
'#^/generateAuthToken#' => ['public' => true],
'#^/createEnrollmentBatch#' => ['roles' => [ADMIN_ROLE_ID, HEAD_ROLE_ID], 'teams' => [ENROLLMENT_TEAM_ID]],
'#^/getEnrollmentBatchStatus#' => ['roles' => [ADMIN_ROLE_ID, HEAD_ROLE_ID], 'teams' => [ENROLLMENT_TEAM_ID]],
'#^/fetchUHIDDetails#' => ['roles' => [ADMIN_ROLE_ID, HEAD_ROLE_ID], 'teams' => [ENROLLMENT_TEAM_ID]],
'#^/FhplGetBenefDetails#' => ['roles' => [ADMIN_ROLE_ID]],
'#^/EcardRequest#' => ['public' => true],
'#^/HospitalNetwork#' => ['public' => true],
'#^/VidalGetBenefDetails#' => ['public' => true],
'#^/ClaimDetail#' => ['public' => true],
'#^/SubmitClaim#' => ['roles' => [ADMIN_ROLE_ID,HEAD_ROLE_ID,ACCOUNT_MANAGER_ROLE_ID,STAFF_ROLE_ID]],
'#^/IntimateClaim#' => ['roles' => [ADMIN_ROLE_ID,HEAD_ROLE_ID,ACCOUNT_MANAGER_ROLE_ID,STAFF_ROLE_ID]],
'#^/IRSubmission#' => ['roles' => [ADMIN_ROLE_ID,HEAD_ROLE_ID,ACCOUNT_MANAGER_ROLE_ID,STAFF_ROLE_ID]],
'#^/ClaimStatusUpdate#' => ['roles' => [ADMIN_ROLE_ID,HEAD_ROLE_ID,ACCOUNT_MANAGER_ROLE_ID,STAFF_ROLE_ID]],
'#^/syncTpaClaimToNhance#' => ['roles' => [ADMIN_ROLE_ID,HEAD_ROLE_ID,ACCOUNT_MANAGER_ROLE_ID,STAFF_ROLE_ID]],
'#^/HealthIndiaGetBenefDetails#' => ['roles' => [ADMIN_ROLE_ID,HEAD_ROLE_ID,ACCOUNT_MANAGER_ROLE_ID,STAFF_ROLE_ID]],
'#^/testTracelog#' => ['roles' => [ADMIN_ROLE_ID]],
// ===================== CLI =====================
'#^/cli/#' => ['public' => true],

View File

@ -227,6 +227,8 @@ $routes->group("/employee", ["filter" => "authMVC"], function ($routes) {
$routes->get("retail-endorsement-list", "EmployeeController::retailendorsementlist");
$routes->post("retail-endorsement-save", "EmployeeController::retailendorsementsave");
$routes->get("getTPADataVariationReport/(:num)", "EmployeeController::getTPADataVariationReport/$1");
$routes->get("getTPADataVariationReportView/(:num)", "EmployeeController::getTPADataVariationReport/$1/view");
$routes->get("proceedTPADataVariationNextStep/(:num)", "EmployeeController::proceedTPADataVariationNextStep/$1");
$routes->get("bulkGenerateEcardAndStoreinS3", "EmployeeController::bulkGenerateEcardAndStoreinS3");
$routes->get('clearCdSession', 'EmployeeController::clearCdSession');
$routes->get('checkSessionStatus', 'EmployeeController::checkSessionStatus');
@ -447,6 +449,8 @@ $routes->group("/util", ["filter" => "authMVC"], function ($routes) {
$routes->post('insufficientCdBalanceHrMailSend', 'EmployeeController::insufficientCdBalanceHrMailSend');
$routes->get('getTpaClaimDumpErrorData/(:any)', 'TicketServiceController::getTpaClaimDumpErrorData/$1');
$routes->get('croneDailyActivityReport', 'DashboardController::croneDailyActivityReport');
$routes->get('insertSampleTpaApiData/(:any)', 'TestingController::insertSampleTpaApiData/$1');
$routes->get('listEmployeeCountByClientPolicy', 'TestingController::listEmployeeCountByClientPolicy');
});
$routes->post("policy_tranction/sendInstallmentRemainderMail","PolicyTransactionController::sendInstallmentRemainderMail");

View File

@ -721,21 +721,43 @@ class DashboardController extends AdminController
return $this->respond(['status' => false, 'code' => 400, 'message' => 'No template found', 'message2' => 'Failed'], 200);
}
$emp_data = $this->employeePolicyModel->getEmployeePolicyForEcard($policy_id);
if (count($emp_data) == 0) {
return $this->respond(['status' => false, 'code' => 400, 'message' => 'No employees found', 'message2' => 'Failed'], 200);
}
$ids = array_column($emp_data, 'id');
$client_policy_data = $this->clientPolicyModel->where('id', $policy_id)->first();
$sendMail = false;
if ($client_policy_data['policy_type_id'] == 3 && $client_policy_data['is_addon'] == 3) {
$sendMail = true;
} else {
$relationships = array_column($emp_data, 'relationship');
if (in_array('Self', $relationships)) {
$sendMail = true;
}
}
if ($sendMail) {
$message = 'Mail Queued';
Jobs::addJob(['job_name' => 'sendMailForDownloadingECard','payload' => ['ids' => $ids,'client_policy_id' => $policy_id]]);
$this->myLogger->logme('error', 'sendManualEcard - Mail Queued');
} else {
$message = 'E-card has already been sent to those employees.';
$this->myLogger->logme('error', 'sendManualEcard - E-card has already been sent to those employees.');
}
// print_r(($ids)); die;
// print_r($this->clientPolicyModel->getLastQuery()); die;
// $this->myLogger->logme('error', "Policy details fetched: " . json_encode($client_policy_data));
Jobs::addJob(['job_name' => 'sendMailForDownloadingECard', 'payload' => ['ids' => $ids, 'client_policy_id' => $policy_id]]);
// Jobs::addJob(['job_name' => 'sendMailForDownloadingECard', 'payload' => ['ids' => $ids, 'client_policy_id' => $policy_id]]);
// $empEmpDataServiceController = new EmpDataServiceController();
// $empEmpDataServiceController->sendMailForDownloadingECard($ids);
return $this->respond(['status' => true, 'code' => 200, 'message' => 'Mail Queued'], 200);
return $this->respond(['status' => true, 'code' => 200, 'message' => $message], 200);
}
public function data_construct_for_bds($data)

View File

@ -3891,6 +3891,13 @@ class EmpDataServiceController extends BaseController
$policy_name = $this->getPolicyNameUsingClientPolicyId($client_policy_id);
$job_details = new Jobs();
$r = Jobs::addJob(['job_name' => 'visitOffBoard', 'payload' => [
'memberIds' => $employee_policy_table_primaryKey ?? [],
'policyNumber' => $policy_name['policy_no'] ?? null ,
'source' => 'NHANCE'
]]);
$r = Jobs::addJob(['job_name' => 'cashDepositCalculationForDeletion', 'payload' => [
'employeeIds' => $employee_policy_table_primaryKey,
'client_id' => $client_id,
@ -4703,7 +4710,7 @@ class EmpDataServiceController extends BaseController
public function getPolicyNameUsingClientPolicyId($client_policy_id)
{
return $this->clientPolicyModel->select('policy_type.policy_type as policy_name')
return $this->clientPolicyModel->select('policy_type.policy_type as policy_name, client_policy.policy_no')
->join('policy_type', 'policy_type.id = client_policy.policy_type_id')
->where('client_policy.id', $client_policy_id)
->first();

View File

@ -3568,7 +3568,7 @@ class EmployeeController extends AdminController
public function initiateWellnessOnboard($client_policy_id)
{
$r = Jobs::addJob(['job_name' => 'initiateWellnessOnboardJob','payload' => ['client_policy_id' => $client_policy_id]]);
//$this->initiateWellnessOnboardJob(['client_policy_id' => $client_policy_id]);
// $this->initiateWellnessOnboardJob(['client_policy_id' => $client_policy_id]);
return $this->respond(['status' => true, 'code' => 200, 'message' => 'Process started'], 200);
}
@ -3942,14 +3942,14 @@ class EmployeeController extends AdminController
}
}
public function getTPADataVariationReport($file_id)
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);
//loop emp data with TPA data for matches
foreach ($emp_data_wo_tpa_id as $db_key => $db_row)
@ -3969,10 +3969,10 @@ class EmployeeController extends AdminController
// die();
//not_in_tpa
$tpa_emp_codes = $TpaApiDataModel->select('emp_code')
->where('file_id', $file_id)
->where('is_active', 1)
->groupBy('emp_code')
->findAll();
->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);
@ -3986,20 +3986,697 @@ class EmployeeController extends AdminController
->where('is_active',1)
->where('file_id',$file_id)
->whereNotIn('emp_code',$master_emp_codes)
->findAll();
->findAll();
// d($not_in_nhance);die();
if( !empty($not_in_tpa) || !empty($not_in_nhance) || !empty($emp_data_wo_tpa_id) )
{
$this->exportVariationReportExcel($not_in_tpa,$not_in_nhance,$emp_data_wo_tpa_id);
}
else
{
return false;
}
// $this->exportVariationReportExcel([],[],[]);
if (!empty($not_in_tpa) || !empty($not_in_nhance) || !empty($emp_data_wo_tpa_id)) {
if ($type === 'download') {
$this->exportVariationReportExcel($not_in_tpa, $not_in_nhance, $emp_data_wo_tpa_id);
} else {
$response = [
'not_in_tpa' => $not_in_tpa,
'not_in_nhance' => $not_in_nhance,
'mismatch_data' => $emp_data_wo_tpa_id,
];
return $this->respond(
[
'status' => true,
'code' => 200,
'message' => '',
'data' => $response,
],
200
);
}
} else {
if ($type === 'download') {
return false;
}
return $this->respond(
[
'status' => false,
'code' => 202,
'message' => 'No data found',
'data' => [],
],
200
);
}
}
public function proceedTPADataVariationNextStep($file_id)
{
try {
if (empty($file_id)) {
return $this->respond(
[
'status' => false,
'code' => 400,
'message' => 'Invalid file reference',
'data' => [],
],
200
);
}
$file = $this->batchFileModel->find($file_id);
if (!$file) {
return $this->respond(
[
'status' => false,
'code' => 404,
'message' => 'File not found',
'data' => [],
],
200
);
}
$tab = $this->request->getGet('tab');
// If the user is proceeding from the "Not in Nhance" tab,
// generate an Employee Upload with Events compatible Excel file
// and trigger the usual upload pipeline.
if ($tab === 'not_in_nhance') {
$generationResult = $this->generateEmployeeUploadFromNotInNhance((int) $file_id, $file);
if (!$generationResult['status']) {
return $this->respond(
[
'status' => false,
'code' => 422,
'message' => $generationResult['message'] ?? 'Unable to generate employee upload file from Not in Nhance data.',
'data' => $generationResult['data'] ?? [],
],
200
);
}
} 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.
$generationResult = $this->generateCorrectionUploadFromNeedToReview((int) $file_id, $file);
if (!$generationResult['status']) {
return $this->respond(
[
'status' => false,
'code' => 422,
'message' => $generationResult['message'] ?? 'Unable to generate correction upload file from Need to Review data.',
'data' => $generationResult['data'] ?? [],
],
200
);
}
}
$this->myLogger->logme(
'error',
'TPA variation review completed and proceed to next clicked',
[
'file_id' => $file_id,
'user_id' => get_session_userid(),
'tab' => $tab,
]
);
return $this->respond(
[
'status' => true,
'code' => 200,
'message' => $tab === 'not_in_nhance'
? 'Employee upload file generated from Not in Nhance data and queued for processing.'
: ($tab === 'need_to_review'
? 'Correction upload file generated from Need to Review data and queued for processing.'
: 'Proceed to next step recorded successfully.'),
'data' => [],
],
200
);
} catch (\Throwable $e) {
$this->myLogger->logme(
'error',
'Error while processing TPA variation proceed to next: ' . $e->getMessage(),
['file_id' => $file_id]
);
return $this->respond(
[
'status' => false,
'code' => 500,
'message' => 'Unable to proceed to the next step at the moment.',
'data' => [],
],
200
);
}
}
/**
* Generate an Employee Upload with Events compatible Excel file
* from the Not in Nhance TPA variation data and push it into the
* existing employee upload pipeline.
*
* @param int $batchFileId Batch file id used for TPA variation report.
* @param array $batchFile Batch file row from DB.
*
* @return array ['status' => bool, 'message' => string, 'data' => array]
*/
protected function generateEmployeeUploadFromNotInNhance(int $batchFileId, array $batchFile): array
{
try {
$clientId = (int) ($batchFile['client_id'] ?? 0);
$clientPolicyId = (int) ($batchFile['client_policy_id'] ?? 0);
$clientBranchId = (int) ($batchFile['client_branch_id'] ?? 0);
if (!$clientId || !$clientPolicyId || !$clientBranchId) {
return [
'status' => false,
'message' => 'Incomplete batch file information. Client / policy / branch missing.',
'data' => [],
];
}
$TpaApiDataModel = new TpaApiDataModel();
// Get master emp codes from Nhance for this client & policy
$masterEmpRows = $this->employeePolicyModel->getTPADataVariationReport(
$clientId,
$clientPolicyId,
$batchFileId,
[],
true
);
if (!is_array($masterEmpRows)) {
$masterEmpRows = [];
}
$masterEmpCodes = array_column($masterEmpRows, 'emp_code');
// Fetch Not in Nhance rows for this batch file
$notInNhance = $TpaApiDataModel->select('*')
->where('is_active', 1)
->where('file_id', $batchFileId)
->whereNotIn('emp_code', $masterEmpCodes)
->findAll();
if (empty($notInNhance)) {
return [
'status' => false,
'message' => 'No "Not in Nhance" records found for this file.',
'data' => [],
];
}
$empServiceController = new EmployeeServiceController();
$inceptionColumns = $empServiceController->getInceptionExcelColumns();
if (empty($inceptionColumns)) {
return [
'status' => false,
'message' => 'Unable to load inception Excel column configuration.',
'data' => [],
];
}
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setTitle('Employees');
// Header row from EmployeeServiceController column definitions
$colIndex = 1;
foreach ($inceptionColumns as $columnDef) {
$headerText = $columnDef['col_name'] ?? '';
$columnLetter = Coordinate::stringFromColumnIndex($colIndex);
$sheet->setCellValue($columnLetter . '1', $headerText);
$colIndex++;
}
// Helper to safely format dates as d-M-Y when possible
$formatDate = static function ($value): string {
if (empty($value)) {
return '';
}
$ts = strtotime($value);
if ($ts === false) {
return (string) $value;
}
return date('d-M-Y', $ts);
};
// Map Not in Nhance TPA rows into the inception Excel structure
$rowIndex = 2;
$sno = 1;
foreach ($notInNhance as $tpaRow) {
$colIndex = 1;
foreach ($inceptionColumns as $key => $columnDef) {
$value = '';
switch ($key) {
case 'sno':
$value = $sno;
break;
case 'emp_id':
$value = $tpaRow['emp_code'] ?? '';
break;
case 'name_of_emp_dep':
$value = $tpaRow['name'] ?? '';
break;
case 'dob':
$value = $formatDate($tpaRow['dob'] ?? '');
break;
case 'gender':
$value = $tpaRow['gender'] ?? '';
break;
case 'relationship':
// Normalize relation text to match allowed values
$relation = (string) ($tpaRow['relation'] ?? '');
$relation = trim(strtolower($relation));
$map = [
'self' => 'Self',
'employee' => 'Self',
'spouse' => 'Spouse',
'wife' => 'Spouse',
'husband' => 'Spouse',
'son' => 'Son',
'daughter' => 'Daughter',
'father' => 'Father',
'mother' => 'Mother',
'father-in-law' => 'Father in Law',
'father in law' => 'Father in Law',
'mother-in-law' => 'Mother in Law',
'mother in law' => 'Mother in Law',
];
$value = $map[$relation] ?? ($tpaRow['relation'] ?? '');
break;
case 'basic_cover_si':
$value = $tpaRow['si'] ?? '';
break;
case 'doc':
// Use DOJ from TPA data as Date of Coverage best-effort
$value = $formatDate($tpaRow['doj'] ?? '');
break;
case 'doj':
$value = $formatDate($tpaRow['doj'] ?? '');
break;
case 'pre_existing_ailments':
// Default to "0" (No) so validation passes for mandatory field
$value = '0';
break;
case 'change_event':
// For addition / dependent_addition, this is mandatory.
$value = 'addition';
break;
default:
// Non-mapped columns (phone, email, etc.) left blank by default.
$value = '';
break;
}
$columnLetter = Coordinate::stringFromColumnIndex($colIndex);
$sheet->setCellValue($columnLetter . $rowIndex, $value);
$colIndex++;
}
$rowIndex++;
$sno++;
}
// Auto-size columns
$totalColumns = count($inceptionColumns);
for ($c = 1; $c <= $totalColumns; $c++) {
$columnLetter = Coordinate::stringFromColumnIndex($c);
$sheet->getColumnDimension($columnLetter)->setAutoSize(true);
}
// Persist the Excel file to the same folder used by manual uploads
$fileName = sprintf(
'not_in_nhance_employee_upload_%d_%s.xlsx',
$batchFileId,
date('Ymd_His')
);
$filePath = WRITEPATH . 'uploads/excel/' . $fileName;
$writer = new Xlsx($spreadsheet);
$writer->save($filePath);
// Create a new entry in the files table so that the
// existing Employee Upload with Events pipeline can process it.
$loggedInUserId = $batchFile['created_by'] ?? get_session_userid();
$action = 'addition';
$newFileId = $this->fileModel->insert([
'file_name' => $fileName,
'client_id' => $clientId,
'policy_id' => $clientPolicyId,
'created_by' => $loggedInUserId,
'status' => 'inprogress',
'action' => $action,
'client_branch_id'=> $clientBranchId,
'uploaded_by' => 1,
'hr_file_id' => null,
'hr_id' => null,
]);
if (!$newFileId || !is_numeric($newFileId)) {
$this->myLogger->logme(
'error',
'Failed to insert generated Not in Nhance employee upload file into files table',
[
'batch_file_id' => $batchFileId,
'client_id' => $clientId,
'client_policy_id' => $clientPolicyId,
'client_branch_id' => $clientBranchId,
'file_name' => $fileName,
'insert_result' => $newFileId,
]
);
return [
'status' => false,
'message' => 'Unable to create file record for generated employee upload.',
'data' => [],
];
}
// Run the same format validation used for manual uploads.
$validationResult = $empServiceController->excelFileFormatValidation(['file_id' => $newFileId]);
if (isset($validationResult['error_summary']) && count($validationResult['error_summary'])) {
return [
'status' => false,
'message' => 'File upload was successful, but file format validation failed. Please review the error report.',
'data' => ['file_id' => $newFileId],
];
}
return [
'status' => true,
'message' => 'Employee upload file generated from Not in Nhance data and queued for processing.',
'data' => ['file_id' => $newFileId],
];
} catch (\Throwable $e) {
$this->myLogger->logme(
'error',
'Error while generating employee upload from Not in Nhance'.
json_encode( [
'batch_file_id' => $batchFileId,
'exception_message' => $e->getMessage(),
'exception_file' => $e->getFile(),
'exception_line' => $e->getLine(),
'exception_trace' => $e->getTraceAsString(),
'client_id' => $batchFile['client_id'] ?? null,
'client_policy_id' => $batchFile['client_policy_id'] ?? null,
'client_branch_id' => $batchFile['client_branch_id'] ?? null,
], JSON_PRETTY_PRINT)
);
return [
'status' => false,
'message' => 'Unexpected error while generating employee upload file.',
'data' => [],
];
}
}
/**
* Generate a Correction Excel file from the Need to Review
* TPA variation data and push it into the existing correction
* upload pipeline.
*
* Each mismatched field (name, dob, relationship, email_corporate)
* becomes a separate row in the Excel, using the correction
* headers defined in EmployeeServiceController::$correction_excel_columns.
*
* @param int $batchFileId Batch file id used for TPA variation report.
* @param array $batchFile Batch file row from DB.
*
* @return array ['status' => bool, 'message' => string, 'data' => array]
*/
protected function generateCorrectionUploadFromNeedToReview(int $batchFileId, array $batchFile): array
{
try {
$clientId = (int) ($batchFile['client_id'] ?? 0);
$clientPolicyId = (int) ($batchFile['client_policy_id'] ?? 0);
$clientBranchId = (int) ($batchFile['client_branch_id'] ?? 0);
if (!$clientId || !$clientPolicyId || !$clientBranchId) {
return [
'status' => false,
'message' => 'Incomplete batch file information. Client / policy / branch missing.',
'data' => [],
];
}
$TpaApiDataModel = new TpaApiDataModel();
// Reuse the same DB + TPA reconciliation used in getTPADataVariationReport
$dbRows = $this->employeePolicyModel->getTPADataVariationReport(
$clientId,
$clientPolicyId,
$batchFileId
);
if (!is_array($dbRows) || !count($dbRows)) {
return [
'status' => false,
'message' => 'No employee data found for Need to Review.',
'data' => [],
];
}
$mismatchRows = [];
foreach ($dbRows as $dbRow) {
$tpaRows = $TpaApiDataModel->select('*')
->where('emp_code', $dbRow['emp_code'])
->where('file_id', $batchFileId)
->where('is_active', 1)
->findAll();
if (!count($tpaRows)) {
continue;
}
$match = $this->reconcileDbWithTpa($dbRow, $tpaRows);
if (($match['status'] ?? '') !== 'matched') {
continue;
}
$tpaRecord = $match['tpa_record'] ?? [];
$notMatching = $match['not_matching'] ?? [];
if (!is_array($notMatching) || !count($notMatching)) {
continue;
}
// Only consider fields that are supported by the correction Excel headers
$allowedFields = ['name', 'dob', 'relationship', 'email_corporate'];
foreach ($notMatching as $field) {
if (!in_array($field, $allowedFields, true)) {
continue;
}
$mismatchRows[] = [
'emp_code' => $dbRow['emp_code'] ?? '',
'name' => $dbRow['name'] ?? '',
'field' => $field,
// Use TPA value as the corrected value to be applied in Nhance
'value' => $tpaRecord[$field] ?? '',
];
}
}
if (!count($mismatchRows)) {
return [
'status' => false,
'message' => 'No mismatched records found to generate correction upload.',
'data' => [],
];
}
$empServiceController = new EmployeeServiceController();
$correctionColumns = $empServiceController->getCorrectionExcelColumns();
if (empty($correctionColumns)) {
return [
'status' => false,
'message' => 'Unable to load correction Excel column configuration.',
'data' => [],
];
}
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setTitle('Correction');
// Header row from EmployeeServiceController column definitions
$colIndex = 1;
foreach ($correctionColumns as $columnDef) {
$headerText = $columnDef['col_name'] ?? '';
$columnLetter = Coordinate::stringFromColumnIndex($colIndex);
$sheet->setCellValue($columnLetter . '1', $headerText);
$colIndex++;
}
$todayDisplay = date('d-M-Y');
$rowIndex = 2;
$sno = 1;
foreach ($mismatchRows as $row) {
$colIndex = 1;
$field_name = $row['field'] ?? '';
$field_value = ($field_name == 'dob' ? change_date_format($row['value'] ?? '', 'Y-m-d', 'd-M-Y') : $row['value'] ?? '' );
foreach ($correctionColumns as $key => $columnDef) {
$value = '';
switch ($key) {
case 'sno':
$value = $sno;
break;
case 'emp_id':
$value = $row['emp_code'] ?? '';
break;
case 'name_of_emp_dep':
$value = $row['name'] ?? '';
break;
case 'field':
$value = $field_name;
break;
case 'value':
$value = $field_value ?? '';
break;
case 'date_of_correction':
$value = $todayDisplay;
break;
case 'change_event':
$value = 'correction';
break;
case 'remarks':
$value = '';
break;
default:
$value = '';
break;
}
$columnLetter = Coordinate::stringFromColumnIndex($colIndex);
$sheet->setCellValue($columnLetter . $rowIndex, $value);
$colIndex++;
}
$rowIndex++;
$sno++;
}
// Auto-size columns
$totalColumns = count($correctionColumns);
for ($c = 1; $c <= $totalColumns; $c++) {
$columnLetter = Coordinate::stringFromColumnIndex($c);
$sheet->getColumnDimension($columnLetter)->setAutoSize(true);
}
// Persist the Excel file to the same folder used by manual uploads
$fileName = sprintf(
'need_to_review_correction_upload_%d_%s.xlsx',
$batchFileId,
date('Ymd_His')
);
$filePath = WRITEPATH . 'uploads/excel/' . $fileName;
$writer = new Xlsx($spreadsheet);
$writer->save($filePath);
// Insert into files table so the existing correction pipeline can process it.
$loggedInUserId = $batchFile['created_by'] ?? get_session_userid();
$newFileId = $this->fileModel->insert([
'file_name' => $fileName,
'client_id' => $clientId,
'policy_id' => $clientPolicyId,
'created_by' => $loggedInUserId,
'status' => 'inprogress',
'action' => 'correction',
'client_branch_id'=> $clientBranchId,
'uploaded_by' => 1,
'hr_file_id' => null,
'hr_id' => null,
]);
if (!$newFileId || !is_numeric($newFileId)) {
$this->myLogger->logme(
'error',
'Failed to insert generated Need to Review correction upload file into files table',
[
'batch_file_id' => $batchFileId,
'client_id' => $clientId,
'client_policy_id' => $clientPolicyId,
'client_branch_id' => $clientBranchId,
'file_name' => $fileName,
'insert_result' => $newFileId,
]
);
return [
'status' => false,
'message' => 'Unable to create file record for generated correction upload.',
'data' => [],
];
}
// Run the same format validation used for manual uploads so that
// the correction file enters the normal processing pipeline.
$validationResult = $empServiceController->excelFileFormatValidation(['file_id' => $newFileId]);
if (isset($validationResult['error_summary']) && count($validationResult['error_summary'])) {
return [
'status' => false,
'message' => 'File upload was successful, but correction file format validation failed. Please review the error report.',
'data' => ['file_id' => $newFileId],
];
}
return [
'status' => true,
'message' => 'Correction upload file generated from Need to Review data and queued for processing.',
'data' => ['file_id' => $newFileId],
];
} catch (\Throwable $e) {
$this->myLogger->logme(
'error',
'Error while generating correction upload from Need to Review'.
json_encode(
[
'batch_file_id' => $batchFileId,
'exception_message' => $e->getMessage(),
'exception_file' => $e->getFile(),
'exception_line' => $e->getLine(),
'exception_trace' => $e->getTraceAsString(),
'client_id' => $batchFile['client_id'] ?? null,
'client_policy_id' => $batchFile['client_policy_id'] ?? null,
'client_branch_id' => $batchFile['client_branch_id'] ?? null,
],
JSON_PRETTY_PRINT
)
);
return [
'status' => false,
'message' => 'Unexpected error while generating correction upload file.',
'data' => [],
];
}
}
@ -4581,14 +5258,17 @@ class EmployeeController extends AdminController
$statusCode = $response->getStatusCode();
$rawBody = $response->getBody();
$result = json_decode($rawBody, true);
// print_rr($result);
// 4. Handle based on HTTP Status Code
if ($statusCode >= 200 && $statusCode < 300) {
// 4. Handle based on HTTP Status Code - BUG FIX: Changed = to == for proper comparison
if ($statusCode == 200) {
$this->myLogger->logme('error', "VISIT_OFFBOARD API Success (Code $statusCode): Policy deleted.");
return [
'status' => true,
'data' => $result
$return_data = [
'memberIds' => $params['memberIds'] ?? [],
'api_result' => $result
];
$this->updateVisitoffboardStatus($return_data);
return $return_data;
}
// Log API-level errors (4xx or 5xx)
@ -4611,6 +5291,73 @@ class EmployeeController extends AdminController
}
}
/**
* Updates the wellness onboard status in the database for deleted members.
*
* Marks employee policy records as deleted in the wellness system after
* a successful API response from the wellness onboard service.
*
* @param array $data Contains 'memberIds' array and 'api_result' from API response
* @return bool Returns true if update was successful or no action needed, false on error
*/
public function updateVisitoffboardStatus(array $data): bool
{
try {
// Validate input data structure
if (empty($data) || !is_array($data)) {
$this->myLogger->logme('error', 'VISIT_OFFBOARD_STATUS_UPDATE: Invalid data parameter');
return false;
}
// Check if API result exists
if (empty($data['api_result'])) {
$this->myLogger->logme('error', 'VISIT_OFFBOARD_STATUS_UPDATE: No API result found in data');
return false;
}
$apiResult = $data['api_result'];
// Verify API success status - BUG FIX: Proper key access and validation
if (($apiResult['message'] ?? null) !== 'success') {
$this->myLogger->logme('error', 'VISIT_OFFBOARD_STATUS_UPDATE: API response not successful - ' . json_encode($apiResult));
return false;
}
// Extract member IDs safely - BUG FIX: Corrected key from memberids to memberIds
$memberIds = $data['memberIds'] ?? [];
if (empty($memberIds) || !is_array($memberIds)) {
$this->myLogger->logme('warn', 'VISIT_OFFBOARD_STATUS_UPDATE: No valid memberIds provided for update');
return true; // Not an error if no members to update
}
if(!empty($apiResult['missingMemberIds']) && is_array($apiResult['missingMemberIds']))
{
$this->myLogger->logme('error', 'VISIT_OFFBOARD_STATUS_UPDATE: missing member IDs found - ' . json_encode($apiResult['missingMemberIds']));
}
// Update wellness_onboard status for deleted members - Append '_DEL' to existing value
$updateResult = $this->employeePolicyModel
->whereIn('id', $memberIds)
->set('wellness_onboard', "CONCAT(wellness_onboard, '_DEL')", false)
->update();
if ($updateResult !== false) {
$this->myLogger->logme('error', 'VISIT_OFFBOARD_STATUS_UPDATE: Updated ' . $updateResult . ' employee policy records with wellness_onboard_DEL status');
return true;
} else {
$this->myLogger->logme('error', 'VISIT_OFFBOARD_STATUS_UPDATE: Database update operation failed');
return false;
}
} catch (\Exception $e) {
$this->myLogger->logme('error', 'VISIT_OFFBOARD_STATUS_UPDATE: Exception occurred - ' . $e->getMessage() . ' - File: ' . $e->getFile() . ' - Line: ' . $e->getLine());
return false;
}
}
public function insufficientCdBalanceHrMailSend()
{
$post_data = $this->request->getJson(true);

View File

@ -2404,6 +2404,9 @@ class EmployeeRestController extends AdminController
if ($this->request->is('get')) {
$client_id = $this->request->getGet('client_id') ?? null;
$data['claim_status'] = $this->claimStatusModel
->select('id,ticket_type, display_name as claim_status')
->where('is_active', 1)
@ -2411,12 +2414,57 @@ class EmployeeRestController extends AdminController
->groupBy('display_name')
->findAll();
$data['ticket_type'] = [
["ticket_type" => "1", "type_name" => "Claim-GMC"],
["ticket_type" => "2", "type_name" => "Claim-GPA"],
["ticket_type" => "3", "type_name" => "EDLI"],
["ticket_type" => "4", "type_name" => "GTLI"],
];
if (!empty($client_id)) {
if (is_string($client_id) && preg_match('/^[a-f0-9]{32}$/i', $client_id)) {
$client_data = $this->clientModel->where('MD5(id)', $client_id)->first();
$client_id = $client_data['id'] ?? null;
}
$client_policy_data = $this->clientPolicyModel
->where('client_id', $client_id)
->where('is_active', 1)
->groupBy('policy_type_id')
->findAll();
$data['ticket_type'] = [];
$addedTypes = [];
foreach ($client_policy_data as $value) {
if (in_array($value['policy_type_id'], [2,3,4,5]) && !in_array('1', $addedTypes)) {
$data['ticket_type'][] = ["ticket_type" => "1", "type_name" => "Claim-GMC"];
$addedTypes[] = '1';
} elseif (in_array($value['policy_type_id'], [1]) && !in_array('2', $addedTypes)) {
$data['ticket_type'][] = ["ticket_type" => "2", "type_name" => "Claim-GPA"];
$addedTypes[] = '2';
} elseif (in_array($value['policy_type_id'], [6]) && !in_array('3', $addedTypes)) {
$data['ticket_type'][] = ["ticket_type" => "3", "type_name" => "EDLI"];
$addedTypes[] = '3';
} elseif (in_array($value['policy_type_id'], [7]) && !in_array('4', $addedTypes)) {
$data['ticket_type'][] = ["ticket_type" => "4", "type_name" => "GTLI"];
$addedTypes[] = '4';
} elseif (in_array($value['policy_type_id'], [72]) && !in_array('72', $addedTypes)) {
$data['ticket_type'][] = ["ticket_type" => "72", "type_name" => "OPD"];
$addedTypes[] = '72';
}
}
usort($data['ticket_type'], fn($a,$b) => $a['ticket_type'] <=> $b['ticket_type']);
} else {
$data['ticket_type'] = [
["ticket_type" => "1", "type_name" => "Claim-GMC"],
["ticket_type" => "2", "type_name" => "Claim-GPA"],
["ticket_type" => "3", "type_name" => "EDLI"],
["ticket_type" => "4", "type_name" => "GTLI"],
];
}
$claim_type = $this->ticketController->claimType;
unset($claim_type[1][2]);

View File

@ -2575,4 +2575,29 @@ class EmployeeServiceController extends AdminController
return $result;
}
/**
* Returns the inception Excel column configuration used for
* validating and processing Employee Upload with Events files.
* This allows other controllers to generate compatible Excel files.
*
* @return array
*/
public function getInceptionExcelColumns(): array
{
return $this->inception_excel_columns;
}
/**
* Returns the correction Excel column configuration used for
* validating and processing Employee correction files.
* This is reused by other controllers when they need to generate
* a correction-compatible Excel programmatically.
*
* @return array
*/
public function getCorrectionExcelColumns(): array
{
return $this->correction_excel_columns;
}
}

View File

@ -240,42 +240,57 @@ class FhplApiController extends BaseController
}
// Extract claim status
$claimData = $response['data'][0];
$tpa_claim_no = $claimData['CLAIM_ID'] ?? '';
$currentStatus = $claimData['CLAIM_STATUS'] ?? '';
$tpa_claim_type = $claimData['CLAIM_TYPE'] ?? '';
$tpa_ailments = $claimData['AILMENT'] ?? '';
// $claimData = $response['data'][0];
$allClaimData = $response['data'];
$validStatuses = [
"In-Progress" => 5,
"Under Process" => 5,
"Query" => 4,
"Paid" => 11,
"Rejected" => 8,
"Approved" => 8,
"Required Information" => 4,
];
$currentStatus = "";
foreach ($allClaimData as $claimData) {
$updateArray = [
'tpa_claim_status' => $currentStatus,
'updated_at' => date('Y-m-d H:i:s'),
];
if (isset($validStatuses[$currentStatus])) {
$updateArray['claim_status_id'] = $validStatuses[$currentStatus];
$tpa_claim_no = $claimData['CLAIM_ID'] ?? '';
$currentStatus = $claimData['CLAIM_STATUS'] ?? '';
$tpa_claim_type = $claimData['CLAIM_TYPE'] ?? '';
$tpa_ailments = $claimData['AILMENT'] ?? '';
$doa = !empty($claimData['DATE_OF_ADMISSION'] ?? null) ? date('Y-m-d', strtotime(str_replace('/', '-', $claimData['DATE_OF_ADMISSION']))) : null;
$validStatuses = [
"In-Progress" => 5,
"Under Process" => 5,
"Query" => 4,
"Paid" => 11,
"Rejected" => 8,
"Approved" => 8,
"Required Information" => 4,
];
$updateArray = [
'tpa_claim_status' => $currentStatus,
'updated_at' => date('Y-m-d H:i:s'),
'last_updated_by' => 'API',
];
if (isset($validStatuses[$currentStatus])) {
$updateArray['claim_status_id'] = $validStatuses[$currentStatus];
}
if (!empty($tpa_claim_type)) {
$updateArray['tpa_claim_type'] = $tpa_claim_type;
}
if (!empty($tpa_ailments)) {
$updateArray['tpa_ailments'] = $tpa_ailments;
}
if (empty($ticket['tpa_claim_id']) || $ticket['tpa_claim_id'] === null) {
$updateArray['tpa_claim_id'] = $tpa_claim_no;
}
if (empty($ticket['claim_number']) || $ticket['claim_number'] === null) {
$updateArray['claim_number'] = $tpa_claim_no;
}
if($ticket['doa'] == $doa || $ticket['claim_number'] == $tpa_claim_no){
$this->db->table('ticket_master')->where('id',$claimId)->update($updateArray);
log_message('error', "FHPL - Claim status SUCCESS | Updated ticket ID $claimId with claim status: $currentStatus");
}else{
log_message('error', "FHPL - Claim status NOT UPDATED | TicketID={$claimId} | TicketDOA={$ticket['doa']} | ClaimDOA={$doa} | Status={$currentStatus}");
}
}
if (!empty($tpa_claim_type)) {
$updateArray['tpa_claim_type'] = $tpa_claim_type;
}
if (!empty($tpa_ailments)) {
$updateArray['tpa_ailments'] = $tpa_ailments;
}
$this->db->table('ticket_master')->where('id',$claimId)->update($updateArray);
log_message('error', "FHPL - Claim status SUCCESS | Updated ticket ID $claimId with claim status: $currentStatus");
return ['status' => true,'message' => 'Claim status updated.','updated_status' => $currentStatus,'api_response' => $response];
@ -1022,6 +1037,10 @@ class FhplApiController extends BaseController
'tpa_id' => trim($row['TPA_TPADETAIL_ID'] ?? null),
'age' => is_numeric($row['AGE'] ?? null) ? (int) $row['AGE'] : null,
'si' => $row['BASE_SUMINSURED'] ?? null,
'doj' => !empty($row['DATE_OF_JOINING'] ?? null) ? date('Y-m-d', strtotime(str_replace('/', '-', $row['DATE_OF_JOINING']))) : null,
'is_active' => 1,
'created_by' => $file_info[0]['created_by'] ?? null,
];

View File

@ -300,45 +300,59 @@ class HealthIndiaApiController extends BaseController
}
// Extract claim status
$claimData = $response['data']['result'][0];
$tpa_claim_no = $claimData['tpA_CLAIM_NO'] ?? '';
$currentStatus = $claimData['claiM_STATUS'] ?? '';
$tpa_claim_type = $claimData['typE_OF_CLAIM'] ?? '';
$tpa_ailments = $claimData['ailment'] ?? '';
// $claimData = $response['data']['result'][0];
$allClaimData = $response['data']['result'];
$validStatuses = [
"In-Progress" => 5,
"Under Process" => 5,
"Query" => 4,
"Paid" => 11,
"Rejected" => 8,
"Approved" => 8,
"Required Information" => 4,
"Intimated and File NOT received" => 4,
];
$currentStatus = "";
foreach ($allClaimData as $claimData) {
$updateArray = [
'tpa_claim_status' => $currentStatus,
'tpa_claim_id' => $tpa_claim_no,
'claim_number' => $tpa_claim_no,
'updated_at' => date('Y-m-d H:i:s'),
];
if (isset($validStatuses[$currentStatus])) {
$updateArray['claim_status_id'] = $validStatuses[$currentStatus];
$tpa_claim_no = $claimData['tpA_CLAIM_NO'] ?? '';
$currentStatus = $claimData['claiM_STATUS'] ?? '';
$tpa_claim_type = $claimData['typE_OF_CLAIM'] ?? '';
$tpa_ailments = $claimData['ailment'] ?? '';
$doa = !empty($claimData['datE_OF_ADMISSION'] ?? null) ? date('Y-m-d', strtotime(str_replace('/', '-', $claimData['datE_OF_ADMISSION']))) : null;
$validStatuses = [
"In-Progress" => 5,
"Under Process" => 5,
"Query" => 4,
"Paid" => 11,
"Rejected" => 8,
"Approved" => 8,
"Required Information" => 4,
"Intimated and File NOT received" => 4,
];
$updateArray = [
'tpa_claim_status' => $currentStatus,
// 'tpa_claim_id' => $tpa_claim_no,
// 'claim_number' => $tpa_claim_no,
'updated_at' => date('Y-m-d H:i:s'),
'last_updated_by' => 'API',
];
if (isset($validStatuses[$currentStatus])) {
$updateArray['claim_status_id'] = $validStatuses[$currentStatus];
}
if (!empty($tpa_claim_type)) {
$updateArray['tpa_claim_type'] = $tpa_claim_type;
}
if (!empty($tpa_ailments)) {
$updateArray['tpa_ailments'] = $tpa_ailments;
}
if (empty($ticket['tpa_claim_id']) || $ticket['tpa_claim_id'] === null) {
$updateArray['tpa_claim_id'] = $tpa_claim_no;
}
if (empty($ticket['claim_number']) || $ticket['claim_number'] === null) {
$updateArray['claim_number'] = $tpa_claim_no;
}
if($ticket['doa'] == $doa || $ticket['claim_number'] == $tpa_claim_no){
$this->db->table('ticket_master')->where('id',$claimId)->update($updateArray);
log_message('error', "HEALTH_INDIA - Claim Status SUCCESS | Updated ticket ID $claimId with claim status: $currentStatus");
}else{
log_message('error', "HEALTH_INDIA - Claim status NOT UPDATED | TicketID={$claimId} | TicketDOA={$ticket['doa']} | ClaimDOA={$doa} | Status={$currentStatus}");
}
}
if (!empty($tpa_claim_type)) {
$updateArray['tpa_claim_type'] = $tpa_claim_type;
}
if (!empty($tpa_ailments)) {
$updateArray['tpa_ailments'] = $tpa_ailments;
}
$this->db->table('ticket_master')->where('id',$claimId)->update($updateArray);
log_message('error', "HEALTH_INDIA - Claim Status SUCCESS | Updated ticket ID $claimId with claim status: $currentStatus");
return [
'status' => true,
'message' => 'Claim status updated.',
@ -1067,6 +1081,9 @@ class HealthIndiaApiController extends BaseController
'tpa_id' => trim($row['memberId'] ?? null),
'age' => is_numeric($row['age'] ?? null) ? (int) $row['age'] : null,
'si' => $row['baseSumInsured'] ?? null,
'doj' => !empty($row['dateofPolicyJoining'] ?? null) ? date('Y-m-d', strtotime(str_replace('/', '-', $row['dateofPolicyJoining']))) : null,
'is_active' => 1,
'created_by' => $file_info[0]['created_by'] ?? null,
];

View File

@ -238,6 +238,10 @@ class JobWorker extends AdminController
'getEmployeeEcardFromTmpFolderAndZipToS3' => [
'type' => 'CC', // Handler Category
'handler' => 'App\Controllers\EmployeeController',
],
'visitOffBoard' => [
'type' => 'CC', // Handler Category
'handler' => 'App\Controllers\EmployeeController',
]
];

View File

@ -573,78 +573,89 @@ class MediAssistApiController extends BaseController
}
// Extract Claim Status
$claimData = $response['data']['claimsData'][0];
$currentStatus = $claimData['claim_Current_Status'] ?? '';
$tpa_claim_no = $claimData['tpA_CLAIM_NO'] ?? '';
$tpa_claim_type = $claimData['typE_OF_CLAIM'] ?? '';
$tpa_ailments = ($claimData['ailment'] ?? '') . ' - ' . ($claimData['ailmenT_DESC'] ?? '');
$allClaimData = $response['data']['claimsData'];
// VALID STATUS LIST
$validStatuses = [
"Claim Received" => 1,
"In Progress" => 5,
"Processed" => 11,
"Claim Paid" => 11,
"Denied" => 13,
"Cancelled" => 13,
"Information Awaited" => 4,
"Confirmation Awaited" => 4,
"Information Awaited Reminder" => 4,
"Information Awaited Final Reminder" => 4,
"Insurer Concurrence Awaited" => 6,
"Closed" => 12,
"Physical Documents Awaited" => 9,
"Processed - Payment Initiated" => 10,
"Processed - Transaction Failed" => 10,
"Processed - Account Details Updated" => 10,
"Processed - Debit Note Raised With Insurer for Payment"=> 10,
"Processed - Payment Initiated by Insurer" => 10,
"Payment - Refunded to Insurer" => 14,
"Processed - Processing Payment" => 10,
"Processed - Physical Documents Awaited" => 9,
// Extra Mappings (based on your DB list)
"NON ID" => 1,
"ID NOT GENERATED" => 2,
"CDA" => 3,
"REJECTED" => 8,
"APPROVED" => 9,
"PAYMENT INITIATED" => 10,
"SETTLED" => 11,
"RETURNED" => 14,
"UNDER PROCESS - TPA" => 61,
"DENIAL REVIEW AWAITED" => 66,
];
$currentStatus = "";
foreach ($allClaimData as $claimData) {
$updateArray = [
'tpa_claim_status' => $currentStatus,
'updated_at' => date('Y-m-d H:i:s'),
];
$currentStatus = $claimData['claim_Current_Status'] ?? '';
$tpa_claim_no = $claimData['tpA_CLAIM_NO'] ?? '';
$tpa_claim_type = $claimData['typE_OF_CLAIM'] ?? '';
$tpa_ailments = ($claimData['ailment'] ?? '') . ' - ' . ($claimData['ailmenT_DESC'] ?? '');
if (isset($validStatuses[$currentStatus])) {
$updateArray['claim_status_id'] = $validStatuses[$currentStatus];
// VALID STATUS LIST
$validStatuses = [
"Claim Received" => 1,
"In Progress" => 5,
"Processed" => 11,
"Claim Paid" => 11,
"Denied" => 13,
"Cancelled" => 13,
"Information Awaited" => 4,
"Confirmation Awaited" => 4,
"Information Awaited Reminder" => 4,
"Information Awaited Final Reminder" => 4,
"Insurer Concurrence Awaited" => 6,
"Closed" => 12,
"Physical Documents Awaited" => 9,
"Processed - Payment Initiated" => 10,
"Processed - Transaction Failed" => 10,
"Processed - Account Details Updated" => 10,
"Processed - Debit Note Raised With Insurer for Payment"=> 10,
"Processed - Payment Initiated by Insurer" => 10,
"Payment - Refunded to Insurer" => 14,
"Processed - Processing Payment" => 10,
"Processed - Physical Documents Awaited" => 9,
// Extra Mappings (based on your DB list)
"NON ID" => 1,
"ID NOT GENERATED" => 2,
"CDA" => 3,
"REJECTED" => 8,
"APPROVED" => 9,
"PAYMENT INITIATED" => 10,
"SETTLED" => 11,
"RETURNED" => 14,
"UNDER PROCESS - TPA" => 61,
"DENIAL REVIEW AWAITED" => 66,
];
$updateArray = [
'tpa_claim_status' => $currentStatus,
'updated_at' => date('Y-m-d H:i:s'),
'last_updated_by' => 'API',
];
if (isset($validStatuses[$currentStatus])) {
$updateArray['claim_status_id'] = $validStatuses[$currentStatus];
}
if (empty($ticket['tpa_claim_id']) || $ticket['tpa_claim_id'] === null) {
$updateArray['tpa_claim_id'] = $tpa_claim_no;
}
if (empty($ticket['claim_number']) || $ticket['claim_number'] === null) {
$updateArray['claim_number'] = $tpa_claim_no;
}
if (!empty($tpa_claim_type)) {
$updateArray['tpa_claim_type'] = $tpa_claim_type;
}
if (!empty($tpa_ailments)) {
$updateArray['tpa_ailments'] = $tpa_ailments;
}
if($ticket['doa'] == $this->mediDate($claimData['datE_OF_ADMISSION'] ?? null) || $ticket['claim_number'] == $tpa_claim_no){
// UPDATE ticket_master
$this->db->table('ticket_master')->where('id', $claimId)->update($updateArray);
// LOG UPDATE
log_message('error',"MEDI_ASSIST - Claim Status SUCCESS | Updated ticket ID $claimId with Claim Status: $currentStatus");
}else{
log_message('error', "MEDI_ASSIST | Fetch Claim Status | Claim Status NOT UPDATED | TicketID={$claimId} | TicketDOA={$ticket['doa']} | ClaimDOA={$claimData['datE_OF_ADMISSION']} | Status={$currentStatus}");
}
}
if (empty($ticket['tpa_claim_id']) || $ticket['tpa_claim_id'] === null) {
$updateArray['tpa_claim_id'] = $tpa_claim_no;
}
if (empty($ticket['claim_number']) || $ticket['claim_number'] === null) {
$updateArray['claim_number'] = $tpa_claim_no;
}
if (!empty($tpa_claim_type)) {
$updateArray['tpa_claim_type'] = $tpa_claim_type;
}
if (!empty($tpa_ailments)) {
$updateArray['tpa_ailments'] = $tpa_ailments;
}
// UPDATE ticket_master
$this->db->table('ticket_master')->where('id', $claimId)->update($updateArray);
// LOG UPDATE
log_message('error',"MEDI_ASSIST - Claim Status SUCCESS | Updated ticket ID $claimId with Claim Status: $currentStatus");
return ['status' => true,'message' => 'Claim Status updated.','updated_status' => $currentStatus,'api_response' => $response];
}
@ -796,6 +807,10 @@ class MediAssistApiController extends BaseController
'gender' => strtoupper($row['benefSex'] ?? null),
'self' => strtolower($row['relName'] ?? '') === 'self' ? 1 : 0,
'si' => $row['sum_insured'] ?? null,
'doj' => $this->mediDate($row['benefWEF'] ?? null),
'tpa_id' => trim($row['benefMediAssistID'] ?? null),
'age' => is_numeric($row['benefAge'] ?? null)
? (int) $row['benefAge']
@ -890,6 +905,9 @@ class MediAssistApiController extends BaseController
// CALL API
$response = call_third_party_api($url, $method, $headers, $body);
log_message('error','MEDI_ASSIST - 2 hours Claim Status API Response: ' . json_encode($response));
if ($response['status'] != true || empty($response['data']['claimsData'][0])) {
log_message('error','MEDI_ASSIST - Claim Status FAILED | for ticket ID: ' . $claimId.' | response: '.json_encode($response));
$error_data[$claimId] = [
@ -900,77 +918,94 @@ class MediAssistApiController extends BaseController
}
// Extract Claim Status
$claimData = $response['data']['claimsData'][0];
$currentStatus = $claimData['claim_Current_Status'] ?? '';
$tpa_claim_no = $claimData['tpA_CLAIM_NO'] ?? '';
$tpa_claim_type = $claimData['typE_OF_CLAIM'] ?? '';
$tpa_ailments = ($claimData['ailment'] ?? '') . ' - ' . ($claimData['ailmenT_DESC'] ?? '');
// $allClaimData = $response['data']['claimsData'][0];
$allClaimData = $response['data']['claimsData'];
// VALID STATUS LIST
$validStatuses = [
"Claim Received" => 1,
"In Progress" => 5,
"Processed" => 11,
"Claim Paid" => 11,
"Denied" => 13,
"Cancelled" => 13,
"Information Awaited" => 4,
"Confirmation Awaited" => 4,
"Information Awaited Reminder" => 4,
"Information Awaited Final Reminder" => 4,
"Insurer Concurrence Awaited" => 6,
"Closed" => 12,
"Physical Documents Awaited" => 9,
"Processed - Payment Initiated" => 10,
"Processed - Transaction Failed" => 10,
"Processed - Account Details Updated" => 10,
"Processed - Debit Note Raised With Insurer for Payment"=> 10,
"Processed - Payment Initiated by Insurer" => 10,
"Payment - Refunded to Insurer" => 14,
"Processed - Processing Payment" => 10,
"Processed - Physical Documents Awaited" => 9,
// Extra Mappings (based on your DB list)
"NON ID" => 1,
"ID NOT GENERATED" => 2,
"CDA" => 3,
"REJECTED" => 8,
"APPROVED" => 9,
"PAYMENT INITIATED" => 10,
"SETTLED" => 11,
"RETURNED" => 14,
"UNDER PROCESS - TPA" => 61,
"DENIAL REVIEW AWAITED" => 66,
];
foreach ($allClaimData as $claimData) {
$currentStatus = $claimData['claim_Current_Status'] ?? '';
$tpa_claim_no = $claimData['tpA_CLAIM_NO'] ?? '';
$tpa_claim_type = $claimData['typE_OF_CLAIM'] ?? '';
$tpa_ailments = ($claimData['ailment'] ?? '') . ' - ' . ($claimData['ailmenT_DESC'] ?? '');
$updateArray = [
'tpa_claim_status' => $currentStatus,
'tpa_claim_id' => $tpa_claim_no,
'claim_number' => $tpa_claim_no,
'updated_at' => date('Y-m-d H:i:s'),
];
if (isset($validStatuses[$currentStatus])) {
$updateArray['claim_status_id'] = $validStatuses[$currentStatus];
}
if (!empty($tpa_claim_type)) {
$updateArray['tpa_claim_type'] = $tpa_claim_type;
}
if (!empty($tpa_ailments)) {
$updateArray['tpa_ailments'] = $tpa_ailments;
}
// VALID STATUS LIST
$validStatuses = [
// UPDATE ticket_master
$this->db->table('ticket_master')->where('id', $claimId)->update($updateArray);
$status_updated_count ++;
// LOG UPDATE
log_message('error',"MEDI_ASSIST - Claim Status SUCCESS | Updated ticket ID $claimId with Claim Status: $currentStatus");
"Claim Received" => 1,
"In Progress" => 5,
"Processed" => 11,
"Claim Paid" => 11,
"Denied" => 13,
"Cancelled" => 13,
"Information Awaited" => 4,
"Confirmation Awaited" => 4,
"Information Awaited Reminder" => 4,
"Information Awaited Final Reminder" => 4,
"Insurer Concurrence Awaited" => 6,
"Closed" => 12,
"Physical Documents Awaited" => 9,
"Processed - Payment Initiated" => 10,
"Processed - Transaction Failed" => 10,
"Processed - Account Details Updated" => 10,
"Processed - Debit Note Raised With Insurer for Payment"=> 10,
"Processed - Payment Initiated by Insurer" => 10,
"Payment - Refunded to Insurer" => 14,
"Processed - Processing Payment" => 10,
"Processed - Physical Documents Awaited" => 9,
// Extra Mappings (based on your DB list)
"NON ID" => 1,
"ID NOT GENERATED" => 2,
"CDA" => 3,
"REJECTED" => 8,
"APPROVED" => 9,
"PAYMENT INITIATED" => 10,
"SETTLED" => 11,
"RETURNED" => 14,
"UNDER PROCESS - TPA" => 61,
"DENIAL REVIEW AWAITED" => 66,
];
$updateArray = [
'tpa_claim_status' => $currentStatus,
'updated_at' => date('Y-m-d H:i:s'),
'last_updated_by' => 'API',
];
if (isset($validStatuses[$currentStatus])) {
$updateArray['claim_status_id'] = $validStatuses[$currentStatus];
}
if (empty($ticket['tpa_claim_id']) || $ticket['tpa_claim_id'] === null) {
$updateArray['tpa_claim_id'] = $tpa_claim_no;
}
if (empty($ticket['claim_number']) || $ticket['claim_number'] === null) {
$updateArray['claim_number'] = $tpa_claim_no;
}
if (!empty($tpa_claim_type)) {
$updateArray['tpa_claim_type'] = $tpa_claim_type;
}
if (!empty($tpa_ailments)) {
$updateArray['tpa_ailments'] = $tpa_ailments;
}
if($ticket['doa'] == $this->mediDate($claimData['datE_OF_ADMISSION'] ?? null) || $ticket['claim_number'] == $tpa_claim_no){
// UPDATE ticket_master
$this->db->table('ticket_master')->where('id', $claimId)->update($updateArray);
$status_updated_count ++;
// LOG UPDATE
log_message('error',"MEDI_ASSIST - Claim Status SUCCESS | Updated ticket ID $claimId with Claim Status: $currentStatus");
}else{
log_message('error', "MEDI_ASSIST | 2 hours | Claim Status NOT UPDATED | TicketID={$claimId} | TicketDOA={$ticket['doa']} | ClaimDOA={$claimData['datE_OF_ADMISSION']} | Status={$currentStatus}");
}
}
}
log_message('error',"MEDI_ASSIST - Claim Status ENDED | 2 hours | Total Tickets={".count($TicketData)."} | Status Updated={$status_updated_count} | Errors={".count($error_data)."}");
return $this->response->setJSON([
'status' => true,
'message' => 'Claim Status updated.',

View File

@ -5618,17 +5618,18 @@ class PolicyTransactionController extends BaseController
$policy_end_date = trim($row[11]);
$revenue_type = trim($row[12]);
$base_premium = trim($row[16]);
$non_commission_premium_amount = trim($row[17]);
$tp_premium = trim($row[18]);
$igst = trim($row[19]);
$cgst = trim($row[20]);
$sgst = trim($row[21]);
$stamp_duty = trim($row[22]);
$base_premium = cleanNumber($row[16]);
$non_commission_premium_amount = cleanNumber($row[17]);
$tp_premium = cleanNumber($row[18]);
$igst = cleanNumber($row[19]);
$cgst = cleanNumber($row[20]);
$sgst = cleanNumber($row[21]);
$stamp_duty = cleanNumber($row[22]);
$agreed_amount = cleanNumber($row[23]);
$agreed_bp_percentage = cleanNumber($row[24]);
$agreed_tp_percentage = cleanNumber($row[25]);
// $total = trim($row[23]);
$agreed_amount = trim($row[23]);
$agreed_bp_percentage = trim($row[24]);
$agreed_tp_percentage = trim($row[25]);
// $actual_bp_amount = trim($row[27]);
// $actual_tp_amount = trim($row[28]);
// $actual_bp_percentage = trim($row[29]);
@ -5647,16 +5648,16 @@ class PolicyTransactionController extends BaseController
$rewards = 0;
$calculation = calculateMotorPolicyAmounts([
'base_premium' => trim($row[16]),
'non_commission_premium_amount' => trim($row[17]),
'tp_premium' => trim($row[18]),
'igst' => trim($row[19]),
'cgst' => trim($row[20]),
'sgst' => trim($row[21]),
'stamp_duty' => trim($row[22]),
'agreed_amount' => trim($row[23]),
'agreed_bp_percentage' => trim($row[24]),
'agreed_tp_percentage' => trim($row[25]),
'base_premium' => $base_premium,
'non_commission_premium_amount' => $non_commission_premium_amount,
'tp_premium' => $tp_premium,
'igst' => $igst,
'cgst' => $cgst,
'sgst' => $sgst,
'stamp_duty' => $stamp_duty,
'agreed_amount' => $agreed_amount,
'agreed_bp_percentage' => $agreed_bp_percentage,
'agreed_tp_percentage' => $agreed_tp_percentage,
'standard_bp_percentage' => 15.00,
'standard_tp_percentage' => 2.5
]);

View File

@ -652,12 +652,16 @@ class SalesController extends BaseController
$data['additional_assigned_ids'] = json_encode($data['additional_assigned_ids']);
}
if (!$this->activityModel->insert($data)) {
$activityId = $this->activityModel->insert($data);
if (!$activityId) {
return $this->fail($this->activityModel->errors(), ResponseInterface::HTTP_BAD_REQUEST);
}
$data['activity_id'] = $activityId;
// add google calender event
$response = $this->addCalenderEvent($data);
log_message("error", '[GOOGLE_CALENDER] addCalenderEvent response: ' . json_encode($response));
$activityId = $this->activityModel->getInsertID();
$activity = $this->activityModel->find((int)$activityId);
@ -1962,6 +1966,23 @@ public function salesManagerLevelDashboard($userId, $current_fin_year = null, $f
];
}
$activity_data = $this->activityModel->where('activity_id', $input['activity_id'])->first();
$emails[] = $user_data['email'];
if (isset($activity_data['additional_assigned_ids']) && !empty($activity_data['additional_assigned_ids'])) {
$additional_assigned_ids = json_decode($activity_data['additional_assigned_ids'], true) ?? [];
foreach ($additional_assigned_ids as $additional_assigned_id) {
$additional_user_data = $this->userModel->where('id', $additional_assigned_id)->first();
if (!empty($additional_user_data['email'])) {
$emails[] = $additional_user_data['email'];
}
}
}
log_message('error', '[GOOGLE_CALENDER] User emails: ' . json_encode($emails));
/* ---------------- SUMMARY ---------------- */
$activityType = ucfirst($input['activity_type']);
@ -1988,7 +2009,7 @@ public function salesManagerLevelDashboard($userId, $current_fin_year = null, $f
'summary' => $summary,
'meeting_date' => $input['scheduled_date'],
'description' => $input['notes'] ?? '',
'emails' => [$user_data['email']],
'emails' => $emails,
];
log_message('error', '[GOOGLE_CALENDER] Google Calendar Payload: ' . json_encode($eventData));

View File

@ -5,8 +5,11 @@ namespace App\Controllers;
use App\Controllers\BaseController;
use App\Models\EmployeePolicyModel;
use App\Models\ClientPolicyModel;
use App\Models\TpaApiDataModel;
use App\Models\BatchFileModel;
use App\Models\InsurerBranchModel;
use App\Models\RFQModel;
use App\Models\EmployeeModel;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\API\ResponseTrait;
use Dompdf\Dompdf;
@ -1120,4 +1123,185 @@ class TestingController extends BaseController
'metabaseUrl' => 'https://nsights.nhanceindia.in',
]);
}
/**
* Insert sample data into tpa_api_data for testing variance report (Not in NHANCE, Not in TPA, Need to Review).
* Uses client_policy (policy_status=1, is_active=1), employee_policies (active), and employees.
*
* @param int|null $client_policy_id Optional. If not provided, first eligible policy is used.
* @return \CodeIgniter\HTTP\ResponseInterface
*/
public function insertSampleTpaApiData($client_policy_id = null)
{
$db = \Config\Database::connect();
$clientPolicyModel = new ClientPolicyModel();
$employeePolicyModel = new EmployeePolicyModel();
$employeeModel = new EmployeeModel();
$tpaApiDataModel = new TpaApiDataModel();
$batchFileModel = new BatchFileModel();
// 1. Get policies: policy_status = 1, is_active = 1
$policyBuilder = $clientPolicyModel
->where('policy_status', 1)
->where('is_active', 1);
if ($client_policy_id !== null && $client_policy_id !== '') {
$policyBuilder->where('id', (int) $client_policy_id);
}
$policies = $policyBuilder->orderBy('id', 'ASC')->findAll();
if (empty($policies)) {
return $this->respond([
'status' => false,
'message' => 'No active client policy found (policy_status=1, is_active=1).',
'data' => [],
], 400);
}
$policy = $policies[0];
$client_policy_id = (int) $policy['id'];
$client_id = (int) $policy['client_id'];
$client_branch_id = !empty($policy['client_branch_id']) ? (int) $policy['client_branch_id'] : 0;
// 2. Get related employees from employee_policies (active) + employees
$empPolicies = $db->table('employee_polices ep')
->select('ep.id AS emp_policy_id, ep.employee_id, ep.tpa_id, e.emp_code, e.name, e.dob, e.gender, e.relationship')
->join('employees e', 'e.id = ep.employee_id')
->where('ep.client_policy_id', $client_policy_id)
->where('ep.is_active', 1)
->whereIn('ep.status', ['active', 'expired'])
->where('e.is_active', 1)
->get()
->getResultArray();
if (empty($empPolicies)) {
return $this->respond([
'status' => false,
'message' => 'No active employee policies found for this client policy.',
'data' => ['client_policy_id' => $client_policy_id],
], 400);
}
// 3. Create a test batch file so we have a file_id for tpa_api_data
$createdBy = function_exists('get_session_userid') ? get_session_userid() : 1;
$batchCode = 'TPA_SAMPLE_' . date('YmdHis') . '_' . bin2hex(random_bytes(4));
$batchFileId = $batchFileModel->insert([
'client_id' => $client_id,
'client_policy_id' => $client_policy_id,
'client_branch_id' => $client_branch_id,
'batch_code' => $batchCode,
'file_name' => 'sample_tpa_data_test_' . date('Y-m-d_His') . '.xlsx',
'insurer_or_tpa' => 'tpa',
'event_type' => 'api',
'actions' => 'fetch',
'status' => 'partially success',
'count' => 0,
'created_by' => $createdBy,
'is_active' => 1,
]);
if (!$batchFileId) {
return $this->respond([
'status' => false,
'message' => 'Failed to create test batch file.',
'data' => [],
], 500);
}
$file_id = (int) $batchFileId;
$tpaApiDataModel->skipValidation(true);
$inserted = ['not_in_nhance' => 0, 'need_to_review' => 0];
$toInsert = [];
// 4. Not in NHANCE: insert TPA records with emp_codes that do NOT exist in NHANCE for this policy
$fakeEmpCodes = ['TPA_SAMPLE_NOTINNHANCE_1', 'TPA_SAMPLE_NOTINNHANCE_2'];
foreach ($fakeEmpCodes as $i => $empCode) {
$toInsert[] = [
'file_id' => $file_id,
'emp_code' => $empCode,
'name' => 'Sample TPA Only ' . ($i + 1),
'dob' => '1990-01-' . str_pad((string)(15 + $i), 2, '0', STR_PAD_LEFT),
'relation' => 'Self',
'gender' => ($i % 2 === 0) ? 'M' : 'F',
'self' => 'Sample TPA Only ' . ($i + 1),
'tpa_id' => 'TPA' . (1000 + $i),
'age' => 32 + $i,
'is_active' => 1,
'desc' => 'Sample data Not in NHANCE',
'created_by'=> $createdBy,
];
$inserted['not_in_nhance']++;
}
// 5. Need to Review: same employee as in NHANCE but with different name/dob/gender
$needReview = array_slice($empPolicies, 0, min(2, count($empPolicies)));
foreach ($needReview as $emp) {
$dob = $emp['dob'];
if (is_string($dob) && preg_match('/^(\d{4})-(\d{2})-(\d{2})/', $dob, $m)) {
$altDob = $m[1] . '-' . $m[2] . '-' . str_pad((string)((int)$m[3] + 1), 2, '0', STR_PAD_LEFT);
} else {
$altDob = '1995-06-15';
}
$toInsert[] = [
'file_id' => $file_id,
'emp_code' => $emp['emp_code'],
'name' => '[TPA Altered] ' . ($emp['name'] ?? 'Unknown'),
'dob' => $altDob,
'relation' => $emp['relationship'] ?? 'Self',
'gender' => (strtoupper($emp['gender'] ?? 'M') === 'M') ? 'F' : 'M',
'self' => $emp['name'] ?? 'Unknown',
'tpa_id' => $emp['tpa_id'] ?? ('T' . $emp['employee_id']),
'age' => 30,
'is_active' => 1,
'desc' => 'Sample data Need to Review (mismatch)',
'created_by'=> $createdBy,
];
$inserted['need_to_review']++;
}
foreach ($toInsert as $row) {
$tpaApiDataModel->insert($row);
}
// Not in TPA: we do NOT insert those into tpa_api_data; NHANCE already has employees. So any employee
// we did not add to tpa_api_data will appear as "Not in TPA". We added only "Need to Review" and
// "Not in NHANCE" rows; the rest of NHANCE employees remain without TPA rows => they show as Not in TPA.
return $this->respond([
'status' => true,
'message' => 'Sample TPA API data inserted successfully.',
'data' => [
'file_id' => $file_id,
'client_policy_id' => $client_policy_id,
'client_id' => $client_id,
'batch_code' => $batchCode,
'inserted' => $inserted,
'not_in_tpa_note' => 'Employees in NHANCE that were not added to TPA data will appear as "Not in TPA" when you run the variance report for this file.',
],
], 200);
}
/**
* List employee count per client policy.
* No input parameters. Checks all client_policy records and counts linked employee_policies per policy.
*
* @return \CodeIgniter\HTTP\ResponseInterface
*/
public function listEmployeeCountByClientPolicy()
{
$db = \Config\Database::connect();
$rows = $db->table('client_policy cp')
->select('cp.id AS client_policy_id, COUNT(ep.id) AS employee_policy_count', false)
->join('employee_polices ep', 'ep.client_policy_id = cp.id', 'left')
->groupBy('cp.id')
->orderBy('cp.id', 'ASC')
->get()
->getResultArray();
$list = array_map(function ($row) {
return [
'client_policy_id' => (int) $row['client_policy_id'],
'employee_policy_count' => (int) $row['employee_policy_count'],
];
}, $rows);
return $this->respond([
'status' => true,
'message' => 'Employee count per client policy.',
'data' => $list,
], 200);
}
}

View File

@ -1777,8 +1777,12 @@ class TicketController extends BaseController
$ticket_id = $this->request->getPost('ticket_master_id');
$old_ticket_data = $this->ticketMasterModel->where('id', $ticket_id)->where('is_active', 1)->first();
$ticket_data['claim_status_id'] = $this->getLastMatchedStatus($ticket_data, $old_ticket_data);
$ticket_data['last_updated_by'] = 'USER';
// print_rr($ticket_data); die;
$this->myLogger->logme('error', "[UPDATE_CLAIM] Ticket Master ID: {data}", ['data' => $ticket_id]);
$this->myLogger->logme('error', "[UPDATE_CLAIM] Old Ticket Data: {data}", ['data' => json_encode($old_ticket_data, JSON_PRETTY_PRINT)]);
$this->myLogger->logme('error', "[UPDATE_CLAIM] New Ticket Data: {data}", ['data' => json_encode($ticket_data, JSON_PRETTY_PRINT)]);
if ($ticket_data) {
$return_value = $this->ticketMasterModel->where('id', $ticket_id)->set($ticket_data)->update();
@ -2400,6 +2404,8 @@ class TicketController extends BaseController
th.old_value,
th.new_value,
th.created_at,
th.updated_by,
CONCAT_WS(' ', creator.first_name, creator.last_name) AS modified_by,
-- Claim Status
old_status.claim_status as old_status_value,
@ -2414,7 +2420,7 @@ class TicketController extends BaseController
new_insured_emp.name as new_insured_id_name,
ticket_master.ticket_type_id
FROM
ticket_history th

View File

@ -495,40 +495,52 @@ class VidalApiController extends BaseController
}
// Extract claim status
$claimData = $response['data']['data']['claims'][0];
$tpa_claim_no = $claimData['claimNumber'] ?? '';
$currentStatus = $claimData['status'] ?? '';
$tpa_claim_type = $claimData['claimType'] ?? '';
// $claimData = $response['data']['data']['claims'][0];
$allClaimData = $response['data']['data']['claims'];
$currentStatus = "";
foreach ($allClaimData as $claimData) {
$tpa_claim_no = $claimData['claimNumber'] ?? '';
$currentStatus = $claimData['status'] ?? '';
$tpa_claim_type = $claimData['claimType'] ?? '';
$doa = !empty($claimData['doa'] ?? null) ? date('Y-m-d', strtotime(str_replace('/', '-', $claimData['doa']))) : null;
// VALID STATUS LIST
$validStatuses = [
"In-Progress" => 5,
"Required Information" => 4,
"Paid" => 11,
"Rejected" => 8,
"Approved" => 8,
];
$updateArray = [
'tpa_claim_status' => $currentStatus,
'tpa_claim_id' => $tpa_claim_no,
// 'claim_number' => $tpa_claim_no, // already updated
'updated_at' => date('Y-m-d H:i:s'),
];
if (isset($validStatuses[$currentStatus])) {
$updateArray['claim_status_id'] = $validStatuses[$currentStatus];
// VALID STATUS LIST
$validStatuses = [
"In-Progress" => 5,
"Required Information" => 4,
"Paid" => 11,
"Rejected" => 8,
"Approved" => 8,
];
$updateArray = [
'tpa_claim_status' => $currentStatus,
'tpa_claim_id' => $tpa_claim_no,
// 'claim_number' => $tpa_claim_no, // already updated
'updated_at' => date('Y-m-d H:i:s'),
'last_updated_by' => 'API',
];
if (isset($validStatuses[$currentStatus])) {
$updateArray['claim_status_id'] = $validStatuses[$currentStatus];
}
if (!empty($tpa_claim_type)) {
$updateArray['tpa_claim_type'] = $tpa_claim_type;
}
if($ticket['doa'] == $doa || $ticket['claim_number'] == $tpa_claim_no){
// UPDATE ticket_master
$this->db->table('ticket_master')->where('id', $claimId)->update($updateArray);
// LOG UPDATE
log_message('error', "VIDAL - Claim Status SUCCESS | Updated ticket ID $claimId with claim status: $currentStatus");
}else{
log_message('error', "VIDAL - Claim Status NOT UPDATED | TicketID={$claimId} | TicketDOA={$ticket['doa']} | ClaimDOA={$doa} | Status={$currentStatus}");
}
}
if (!empty($tpa_claim_type)) {
$updateArray['tpa_claim_type'] = $tpa_claim_type;
}
// UPDATE ticket_master
$this->db->table('ticket_master')->where('id', $claimId)->update($updateArray);
// LOG UPDATE
log_message('error', "VIDAL - Claim Status SUCCESS | Updated ticket ID $claimId with claim status: $currentStatus");
return ['status' => true,'message' => 'Claim status updated.','updated_status' => $currentStatus,'api_response' => $response];
}
@ -611,44 +623,62 @@ class VidalApiController extends BaseController
}
// Extract claim status
$claimData = $response['data']['data']['claims'][0];
$tpa_claim_no = $claimData['claimNumber'] ?? '';
$currentStatus = $claimData['status'] ?? '';
$tpa_claim_type = $claimData['claimType'] ?? '';
// $claimData = $response['data']['data']['claims'][0];
$allClaimData = $response['data']['data']['claims'];
foreach ($allClaimData as $claimData) {
$tpa_claim_no = $claimData['claimNumber'] ?? '';
$currentStatus = $claimData['status'] ?? '';
$tpa_claim_type = $claimData['claimType'] ?? '';
$doa = !empty($claimData['doa'] ?? null) ? date('Y-m-d', strtotime(str_replace('/', '-', $claimData['doa']))) : null;
// VALID STATUS LIST
$validStatuses = [
"In-Progress" => 5,
"Required Information" => 4,
"Paid" => 11,
"Rejected" => 8,
"Approved" => 8,
];
// VALID STATUS LIST
$validStatuses = [
"In-Progress" => 5,
"Required Information" => 4,
"Paid" => 11,
"Rejected" => 8,
"Approved" => 8,
];
$updateArray = [
'tpa_claim_status' => $currentStatus,
'tpa_claim_id' => $tpa_claim_no,
// 'claim_number' => $tpa_claim_no, // already updated
'updated_at' => date('Y-m-d H:i:s'),
];
if (isset($validStatuses[$currentStatus])) {
$updateArray['claim_status_id'] = $validStatuses[$currentStatus];
$updateArray = [
'tpa_claim_status' => $currentStatus,
// 'claim_number' => $tpa_claim_no, // already updated
'updated_at' => date('Y-m-d H:i:s'),
'last_updated_by' => 'API',
];
if (isset($validStatuses[$currentStatus])) {
$updateArray['claim_status_id'] = $validStatuses[$currentStatus];
}
if (!empty($tpa_claim_type)) {
$updateArray['tpa_claim_type'] = $tpa_claim_type;
}
if (empty($ticket['tpa_claim_id']) || $ticket['tpa_claim_id'] === null) {
$updateArray['tpa_claim_id'] = $tpa_claim_no;
}
if (empty($ticket['claim_number']) || $ticket['claim_number'] === null) {
$updateArray['claim_number'] = $tpa_claim_no;
}
// UPDATE ticket_master
if($ticket['doa'] == $doa || $ticket['claim_number'] == $tpa_claim_no){
$this->db->table('ticket_master')->where('id', $claimId)->update($updateArray);
// LOG UPDATE
log_message('error', "VIDAL - Claim Status SUCCESS | Updated ticket ID $claimId with claim status: $currentStatus");
$status_updated_count ++;
}else{
log_message('error', "VIDAL - Claim Status NOT UPDATED | TicketID={$claimId} | TicketDOA={$ticket['doa']} | ClaimDOA={$doa} | Status={$currentStatus}");
}
}
if (!empty($tpa_claim_type)) {
$updateArray['tpa_claim_type'] = $tpa_claim_type;
}
// UPDATE ticket_master
$this->db->table('ticket_master')->where('id', $claimId)->update($updateArray);
// LOG UPDATE
log_message('error', "VIDAL - Claim Status SUCCESS | Updated ticket ID $claimId with claim status: $currentStatus");
$status_updated_count ++;
}
log_message('error', "VIDAL - Claim Status ENDED | Total Tickets={".count($TicketData)."} | Status Updated={$status_updated_count} | Errors={".count($error_data)."}");
return $this->response->setJSON([
'status' => true,
'message' => 'Claim status updated.',

View File

@ -3072,6 +3072,8 @@ if (!function_exists('validate_mobile_value')) {
if (!function_exists('validate_positive_number_value')) {
function validate_positive_number_value($value)
{
$value = cleanNumber($value);
if ($value === "" || $value === null) {
return ['status' => true, 'error' => null];
}

View File

@ -1382,3 +1382,16 @@ if (! function_exists('add_google_calender_event')) {
}
}
}
if (! function_exists('cleanNumber')) {
function cleanNumber($value){
if (empty($value)) {
return 0;
}
$value = str_replace(',', '', trim($value));
return is_numeric($value) ? (float)$value : 0;
}
}

View File

@ -368,7 +368,8 @@ abstract class BaseTpaClaimImportService
return $value;
}
}
return null;
return 61;
}
/**

View File

@ -374,7 +374,8 @@ class EmployeePolicyModel extends Model
public function getEmployeePolicyForEcard($policy_id = 0)
{
$result = $this->select([
'employee_polices.id'
'employee_polices.id',
'emp.relationship',
])
->join('employees emp', 'employee_polices.employee_id = emp.id');
if ($policy_id !=0 && !empty($policy_id)) {

View File

@ -3785,7 +3785,7 @@
$totalBilled[$key] = ($totalBilled[$key] ?? 0) + (float) ($row['billed_amt'] ?? 0);
// Store total_irda_amt once
if (!isset($totalIrdaMap[$key]) && ($row['total_irda_amt'] ?? 0) > 0) {
if (!isset($totalIrdaMap[$key])) {
$totalIrdaMap[$key] = (float) $row['total_irda_amt'];
}
@ -3802,11 +3802,24 @@
foreach ($result as $row) {
$ptId = $row['pt_id'].'-'.$row['insurer_id'];
if (!isset($ptSeen[$ptId])) {
$totalIrdaVal = $totalIrdaMap[$ptId] ?? 0;
$totalBilledVal = $totalBilled[$ptId] ?? 0;
$addMinus = false;
if($totalIrdaVal < 0){
$totalIrdaVal = abs($totalIrdaVal);
$totalBilledVal = abs($totalBilledVal);
$addMinus = true;
}
// First entry → set unbilled amount
$row['unbilled_amount'] = round(
(float) (($totalIrdaMap[$ptId] ?? 0) - ($totalBilled[$ptId] ?? 0)),
2
);
$row['unbilled_amount'] = round((float) ($totalIrdaVal - $totalBilledVal),2 );
if($addMinus){
$row['unbilled_amount'] = ($row['unbilled_amount'] * -1);
}
$ptSeen[$ptId] = true;
} else {
// Other entries → zero

View File

@ -94,6 +94,7 @@ class TicketMasterModel extends Model
'tpa_claim_type',
'tpa_ailments',
'claim_dump_ref_id',
'last_updated_by',
];

View File

@ -25,7 +25,9 @@ class TpaApiDataModel extends Model
'age',
'is_active',
'desc',
'created_by'
'created_by',
'si',
'doj'
];
// protected $useTimestamps = true;

View File

@ -13,7 +13,67 @@
overflow: hidden;
text-overflow: ellipsis;
}
.dataTables_length label {height: 21px !important;}
.dataTables_length label {
height: 21px !important;
}
/* TPA variation modal layout */
#tpa_variation_modal .modal-dialog {
max-width: 95%;
}
#tpa_variation_modal .modal-content {
max-height: 90vh;
}
#tpa_variation_modal .modal-body {
max-height: calc(85vh - 50px);
overflow-y: auto;
direction: ltr;
}
#tpa_variation_modal .table-responsive {
overflow-x: auto;
}
#tpa_variation_modal table {
white-space: nowrap;
font-size: 11px;
}
#tpa_variation_modal table thead th,
#tpa_variation_modal table tbody td {
padding: 2px 6px;
line-height: 1.1;
}
/* Tabs spacing & styling */
#tpa_variation_modal .nav-tabs {
border-bottom: 1px solid #dee2e6;
margin-bottom: 12px;
gap: 6px;
}
#tpa_variation_modal .nav-tabs .nav-item {
margin-right: 6px;
}
#tpa_variation_modal .nav-tabs .nav-link {
padding: 6px 14px;
border-radius: 4px 4px 0 0;
}
#tpa_variation_modal .nav-tabs .nav-link.active {
background-color: #f8f9fa;
border-color: #dee2e6 #dee2e6 transparent;
}
/* Modal footer buttons size */
#tpa_variation_modal .modal-footer .btn {
padding: 4px 12px;
font-size: 12px;
}
</style>
<div class="col-12" id="second_page">
@ -72,6 +132,7 @@
<?php echo change_date_format($file['created_at'],'Y-m-d H:i:s', 'd M Y h:i a') ?> by <?php echo get_username($file['created_by']) ?>
</td>
<td>
<?php if ($file['status'] == 'failed') { ?>
<?php echo $file['status']; ?>
@ -157,36 +218,39 @@
<a href="javascript: void(0);" class="dropdown-toggle arrow-none btn btn-light btn-sm"
data-toggle="dropdown" aria-expanded="false"><i class="mdi mdi-dots-horizontal"></i></a>
<div class="dropdown-menu dropdown-menu-right">
<?php if($file['actions'] != 'export') { ?>
<?php if (str_starts_with($file['status'], 'failed')) { ?>
<a href="#"
data-id="<?= $file['id'] ?>"
data-client_id="<?= $file['client_id'] ?>"
data-client_policy_id="<?= $file['client_policy_id'] ?>"
data-insurer_or_tpa="<?= $file['insurer_or_tpa'] ?>"
data-event_type="<?= $file['event_type'] ?>"
data-actions="<?= $file['actions'] ?>"
data-client_branch_id="<?= $file['client_branch_id'] ?>"
data-issue_date="<?= $file['policy_issue_date'] ?>"
<div class="dropdown-menu dropdown-menu-right">
onclick="getBatchFileData(this)" class="dropdown-item upload_button" ><i class="mdi mdi-upload mr-2 text-muted font-18 vertical-middle"></i>Re-Upload</a>
<?php } ?>
<?php if (str_starts_with($file['status'], 'failed')) { ?>
<a href="#"
data-id="<?= $file['id'] ?>"
data-client_id="<?= $file['client_id'] ?>"
data-client_policy_id="<?= $file['client_policy_id'] ?>"
data-insurer_or_tpa="<?= $file['insurer_or_tpa'] ?>"
data-event_type="<?= $file['event_type'] ?>"
data-actions="<?= $file['actions'] ?>"
data-client_branch_id="<?= $file['client_branch_id'] ?>"
data-issue_date="<?= $file['policy_issue_date'] ?>"
<?php if ($file['actions'] == "import") { ?>
<a href="<?= base_url('/util/download_import_file/') . $file['id'] ?>" class="dropdown-item" style="color: #000;" aria-hidden="true" target="_blank" ><i class="mdi mdi-download mr-2 text-muted font-18 vertical-middle"></i>Download</a>
<?php } ?>
onclick="getBatchFileData(this)" class="dropdown-item upload_button" ><i class="mdi mdi-upload mr-2 text-muted font-18 vertical-middle"></i>Re-Upload</a>
<?php } ?>
<?php if ($file['actions'] == "fetch" && $file['status'] == 'partially success') { ?>
<a href="<?= base_url('employee/getTPADataVariationReport/') . $file['id'] ?>" class="dropdown-item" style="color: #000;" aria-hidden="true" target="_blank" ><i class="mdi mdi-download mr-2 text-muted font-18 vertical-middle"></i>Download TPA Variation report</a>
<?php if ($file['actions'] == "import") { ?>
<a href="<?= base_url('/util/download_import_file/') . $file['id'] ?>" class="dropdown-item" style="color: #000;" aria-hidden="true" target="_blank" ><i class="mdi mdi-download mr-2 text-muted font-18 vertical-middle"></i>Download</a>
<?php } ?>
<?php } ?>
<?php if ($file['actions'] == "fetch" && $file['status'] == 'partially success') { ?>
<a href="<?= base_url('employee/getTPADataVariationReport/') . $file['id'] ?>" class="dropdown-item" style="color: #000;" aria-hidden="true" target="_blank" ><i class="mdi mdi-download mr-2 text-muted font-18 vertical-middle"></i>Download TPA Variation report</a>
<a href="#" class="dropdown-item" style="color: #000;" aria-hidden="true" onclick="getTPADataVariationReport(<?= $file['id'] ?>)"><i class="mdi mdi-eye mr-2 text-muted font-18 vertical-middle"></i>View TPA Variation report</a>
<?php } ?>
</div>
</div>
<?php } ?>
</div>
</td>
</tr>
<?php }
} ?>
@ -228,10 +292,252 @@
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<!-- TPA Data Variation Modal -->
<div class="modal fade" id="tpa_variation_modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">TPA Data Variation Report</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="tpaVariationTabs" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="not-in-nhance-tab" data-toggle="tab" href="#not_in_nhance_tab" role="tab" aria-controls="not_in_nhance_tab" aria-selected="true">Not in Nhance</a>
</li>
<li class="nav-item">
<a class="nav-link" id="not-in-tpa-tab" data-toggle="tab" href="#not_in_tpa_tab" role="tab" aria-controls="not_in_tpa_tab" aria-selected="false">Not in TPA</a>
</li>
<li class="nav-item">
<a class="nav-link" id="need-to-review-tab" data-toggle="tab" href="#need_to_review_tab" role="tab" aria-controls="need_to_review_tab" aria-selected="false">Need to Review</a>
</li>
</ul>
<div class="tab-content pt-3" id="tpaVariationTabContent">
<div class="tab-pane fade show active" id="not_in_nhance_tab" role="tabpanel" aria-labelledby="not-in-nhance-tab">
<div class="table-responsive">
<table class="table table-bordered table-sm" id="not_in_nhance_table">
<thead></thead>
<tbody></tbody>
</table>
</div>
</div>
<div class="tab-pane fade" id="not_in_tpa_tab" role="tabpanel" aria-labelledby="not-in-tpa-tab">
<div class="table-responsive">
<table class="table table-bordered table-sm" id="not_in_tpa_table">
<thead></thead>
<tbody></tbody>
</table>
</div>
</div>
<div class="tab-pane fade" id="need_to_review_tab" role="tabpanel" aria-labelledby="need-to-review-tab">
<div class="table-responsive">
<table class="table table-bordered table-sm" id="need_to_review_table">
<thead></thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">Close</button>
<button type="button" id="tpaProceedButton" class="btn btn-primary btn-sm" onclick="handleTPAProceed()">Proceed</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<script>
let currentTPAVariationFileId = null;
const tpaVariationColumns = {
not_in_nhance: [
{ key: 'emp_code', label: 'Employee Code' },
{ key: 'name', label: 'Employee Name' },
{ key: 'relation', label: 'Relation' },
{ key: 'dob', label: 'Date of Birth' },
{ key: 'gender', label: 'Gender' },
{ key: 'age', label: 'Age' },
{ key: 'tpa_id', label: 'TPA Member ID' },
],
not_in_tpa: [
{ key: 'emp_code', label: 'Employee Code' },
{ key: 'name', label: 'Employee Name' },
{ key: 'relationship', label: 'Relation' },
{ key: 'dob', label: 'Date of Birth' },
{ key: 'gender', label: 'Gender' },
{ key: 'mobile', label: 'Mobile No' },
{ key: 'email_corporate', label: 'Corporate Email' },
{ key: 'policy_no', label: 'Policy No' },
{ key: 'tpa_name', label: 'TPA Name' },
{ key: 'change_event', label: 'Change Event' },
],
need_to_review: [
// DB side
{ key: 'emp_code', label: 'Employee Code' },
{ key: 'name', label: 'Employee Name' },
{ key: 'relationship', label: 'Relation' },
{ key: 'dob', label: 'Date of Birth' },
{ key: 'gender', label: 'Gender' },
{ key: 'policy_no', label: 'Policy No' },
{ key: 'uhid', label: 'UHID' },
{ key: 'change_event', label: 'Change Event' },
// TPA side
{ key: 'tpa_emp_code', label: 'TPA Employee Code' },
{ key: 'tpa_name', label: 'TPA Name' },
{ key: 'tpa_relation', label: 'TPA Relation' },
{ key: 'tpa_dob', label: 'TPA Date of Birth' },
{ key: 'tpa_gender', label: 'TPA Gender' },
{ key: 'tpa_tpa_id', label: 'TPA Member ID' },
{ key: 'tpa_age', label: 'TPA Age' },
// Mismatch info
{ key: 'mismatch_fields', label: 'Mismatch Fields' },
],
};
function renderVariationTable(tableSelector, rows, columns) {
const $table = $(tableSelector);
const $thead = $table.find('thead');
const $tbody = $table.find('tbody');
$thead.empty();
$tbody.empty();
const headerRow = $('<tr></tr>');
columns.forEach(col => {
headerRow.append($('<th></th>').text(col.label));
});
$thead.append(headerRow);
if (!rows || !rows.length) {
const emptyRow = $('<tr></tr>');
columns.forEach((col, index) => {
const td = $('<td></td>');
if (index === 0) {
td.addClass('text-center text-muted').text('No data found');
}
emptyRow.append(td);
});
$tbody.append(emptyRow);
return;
}
rows.forEach(row => {
const tr = $('<tr></tr>');
columns.forEach(col => {
let value = row[col.key];
if (value === null || value === undefined) {
value = '';
}
tr.append($('<td></td>').text(value));
});
$tbody.append(tr);
});
}
function populateTPAVariationModal(data) {
const notInNhance = data.not_in_nhance || [];
const notInTpa = data.not_in_tpa || [];
const reviewData = (data.mismatch_data || []).map(row => {
let mismatchFields = '';
const match = row.match || {};
const notMatching = match.not_matching || [];
if (Array.isArray(notMatching) && notMatching.length) {
mismatchFields = notMatching.join(', ');
} else if (match.status && match.status !== 'matched') {
mismatchFields = match.status;
}
const tpaRecord = match.tpa_record || {};
return Object.assign({}, row, {
mismatch_fields: mismatchFields,
tpa_emp_code: tpaRecord.emp_code || '',
tpa_name: tpaRecord.name || '',
tpa_relation: tpaRecord.relation || '',
tpa_dob: tpaRecord.dob || '',
tpa_gender: tpaRecord.gender || '',
tpa_tpa_id: tpaRecord.tpa_id || '',
tpa_age: tpaRecord.age || '',
});
});
destroyVariationDataTable('#not_in_nhance_table');
destroyVariationDataTable('#not_in_tpa_table');
destroyVariationDataTable('#need_to_review_table');
renderVariationTable('#not_in_nhance_table', notInNhance, tpaVariationColumns.not_in_nhance);
renderVariationTable('#not_in_tpa_table', notInTpa, tpaVariationColumns.not_in_tpa);
renderVariationTable('#need_to_review_table', reviewData, tpaVariationColumns.need_to_review);
initVariationDataTable('#not_in_nhance_table');
initVariationDataTable('#not_in_tpa_table');
initVariationDataTable('#need_to_review_table');
}
function showTPAVariationModal() {
const modalElement = document.getElementById('tpa_variation_modal');
if (!modalElement) {
return;
}
const modal = new bootstrap.Modal(modalElement);
modal.show();
// Ensure proceed button reflects the currently active tab when modal opens
const $activeTab = $('#tpaVariationTabs .nav-link.active');
updateTPAProceedButton($activeTab.attr('id'));
}
function initVariationDataTable(tableSelector) {
const $table = $(tableSelector);
$table.DataTable({
pageLength: 20,
lengthMenu: [[10, 20, 50, 100], [10, 20, 50, 100]],
searching: true,
paging: true,
ordering: false,
info: true,
autoWidth: false
});
}
function destroyVariationDataTable(tableSelector) {
const $table = $(tableSelector);
if ($.fn.DataTable.isDataTable($table)) {
$table.DataTable().clear().destroy();
}
}
function updateTPAProceedButton(activeId) {
const $button = $('#tpaProceedButton');
if (!$button.length) {
return;
}
// Default: visible
$button.removeClass('d-none');
if (activeId === 'not-in-nhance-tab') {
$button.text('Proceed - Not in Nhance');
} else if (activeId === 'need-to-review-tab') {
$button.text('Proceed - Need to Review');
} else if (activeId === 'not-in-tpa-tab') {
// Hide button for "Not in TPA" section
$button.addClass('d-none');
} else {
$button.text('Proceed');
}
}
$(document).ready(function() {
// Update proceed button label/visibility on tab change
$('#tpaVariationTabs a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
const activeId = $(e.target).attr('id');
updateTPAProceedButton(activeId);
});
$('#datatable-buttons').DataTable({
// dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" +
// "<'row'<'col-sm-12'tr>>" +
@ -281,7 +587,6 @@
paging: true
});
});
// Function to format a number in Indian Rupees format
@ -393,5 +698,109 @@
// });
}
function getTPADataVariationReport(file_id) {
currentTPAVariationFileId = file_id;
$('.loader').fadeIn();
$('.loader-mask').fadeIn();
let url = '<?= base_url('employee/getTPADataVariationReportView') ?>/' + file_id;
sendAjaxRequestForGlobal(url, 'GET', {}, function (response) {
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
if (response && response.status && response.data) {
populateTPAVariationModal(response.data);
showTPAVariationModal();
} else {
toastr.warning((response && response.message) || 'No data found for variation report.', 'WARNING');
}
}, function (xhr, status, error) {
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
console.error('Error fetching TPA variation data:', error);
toastr.error('An error occurred while fetching the variation report.', 'ERROR');
});
}
function proceedTPADataVariationNextStep(tabKey) {
if (!currentTPAVariationFileId) {
toastr.warning('Unable to identify the selected file.', 'WARNING');
return;
}
$('.loader').fadeIn();
$('.loader-mask').fadeIn();
const url = '<?= base_url('employee/proceedTPADataVariationNextStep') ?>/' + currentTPAVariationFileId + '?tab=' + encodeURIComponent(tabKey);
sendAjaxRequestForGlobal(url, 'GET', {}, function (response) {
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
if (response && response.status) {
toastr.success(response.message || 'Proceed to next step initiated successfully.', 'SUCCESS');
} else {
toastr.warning(response.message || 'Unable to proceed to next step.', 'WARNING');
}
window.location.reload();
}, function (xhr, status, error) {
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
toastr.error('An error occurred while proceeding to the next step.', 'ERROR');
console.error(error);
});
}
function proceedNotInNhance() {
proceedTPADataVariationNextStep('not_in_nhance');
}
function proceedNotInTPA() {
proceedTPADataVariationNextStep('not_in_tpa');
}
function proceedNeedToReview() {
proceedTPADataVariationNextStep('need_to_review');
}
function handleTPAProceed() {
const $activeTab = $('#tpaVariationTabs .nav-link.active');
const activeId = $activeTab.attr('id');
if (!activeId) {
toastr.warning('No active tab selected.', 'WARNING');
return;
}
const tabLabel = ($activeTab.text() || '').trim() || 'this tab';
confirmActionSweertAlert(
"Are you sure you want to proceed with the data in this tab?",
"Yes, Proceed",
"Cancel",
"warning"
).then(function(isConfirmed) {
if (!isConfirmed) {
return;
}
if (activeId === 'not-in-nhance-tab') {
proceedNotInNhance();
} else if (activeId === 'not-in-tpa-tab') {
proceedNotInTPA();
} else if (activeId === 'need-to-review-tab') {
proceedNeedToReview();
} else {
toastr.warning('Unknown tab selected.', 'WARNING');
}
});
}
</script>

View File

@ -1,4 +1,58 @@
<style>
/* UI improvements for module cards - all 5 in one row on large screens */
.module-cards-row .section {
min-height: 60px;
display: flex;
flex-direction: column;
padding: 0.5rem 0;
}
.module-cards-row .section-title {
display: flex;
align-items: center;
gap: 0.5rem;
min-height: 40px;
cursor: default;
margin-left: 25px;
}
.module-cards-row .section-title input[type="checkbox"] {
cursor: pointer;
flex-shrink: 0;
}
.module-cards-row .section-title .mdi {
margin-bottom: 0;
color: #555;
}
/* Fallback: ensure 5 equal columns on large screens if row-cols not supported */
@media (min-width: 992px) {
.module-cards-row > .col {
flex: 0 0 20%;
max-width: 20%;
}
}
/* Checkbox alignment - vertically center with labels */
.checkbox-item {
display: flex !important;
align-items: center !important;
gap: 0.5rem;
min-height: 1.5rem;
}
.checkbox-item input[type="checkbox"] {
margin: 0 !important;
flex-shrink: 0;
vertical-align: middle;
}
.checkbox-item label {
margin: 0 !important;
flex: 1;
cursor: pointer;
line-height: 1.4;
}
.checkbox-group {
margin-left: 8px !important;
}
<?php foreach ($hr_access_data as $key => $value) {
$key = $key + 1;
?>
@ -99,8 +153,8 @@
</div>
<div class="card-content">
<div class="content-inner" style="background-color: #F5FFFF;">
<div class="row">
<div class="col-md-6 col-lg-3">
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-5 module-cards-row">
<div class="col">
<div class="section">
<div class="section-title">
<input type="checkbox" class="main-checkbox"
@ -161,7 +215,7 @@
</div>
</div>
<div class="col-md-6 col-lg-3">
<div class="col">
<div class="section">
<div class="section-title">
<input type="checkbox" class="main-checkbox"
@ -236,7 +290,7 @@
</div>
</div>
<div class="col-md-6 col-lg-3">
<div class="col">
<div class="section">
<div class="section-title">
<input type="checkbox" class="main-checkbox"
@ -270,7 +324,7 @@
</div>
</div>
<div class="col-md-6 col-lg-3">
<div class="col">
<div class="section">
<div class="section-title">
<input type="checkbox" class="main-checkbox" name="<?= 'user' . $key ?>_modules" value="4" <?php if (in_array(4, $value['allowed_post_modules'])) {
@ -280,6 +334,17 @@
</div>
</div>
</div>
<div class="col">
<div class="section">
<div class="section-title">
<input type="checkbox" class="main-checkbox" name="<?= 'user' . $key ?>_modules" value="5" <?php if (in_array(5, $value['allowed_post_modules'] ?? [])) {
echo 'checked';
} ?>>
<i class="mdi mdi-chart-line mr-2"></i>Insights
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -20,7 +20,7 @@
<td><?php echo $row['display_name']; ?></td>
<td><?php echo $row['old_value'].' => '.$row['new_value']; ?></td>
<!-- <td><?php //echo $row['new_value']; ?></td> -->
<td><?php echo !empty($row['modified_by'])? $row['modified_by'] : "Created by employee"; ?></td>
<td><?php echo !empty($row['modified_by'])? $row['modified_by'] : "Created by employee"; ?> <?= $row['updated_by'] == "0" ? "(API)" : ""; ?></td>
<!-- <td><?php //echo $row['created_at']; ?></td> -->
<td><?php echo date("d-m-Y h:i:s A", strtotime($row['created_at'])) ?? " - "; ?></td>
</tr>