FEAT_TPA_VARIATION_REPORT
This commit is contained in:
parent
6268a1e829
commit
052cf9df97
@ -213,6 +213,7 @@ $routes->group("/employee", ["filter" => "authMVC"], function ($routes) {
|
||||
$routes->post('get_emp_history','EmployeeController::getEmpHistory');
|
||||
$routes->get("retail-endorsement-list", "EmployeeController::retailendorsementlist");
|
||||
$routes->post("retail-endorsement-save", "EmployeeController::retailendorsementsave");
|
||||
$routes->get("getTPADataVariationReport/(:num)", "EmployeeController::getTPADataVariationReport/$1");
|
||||
});
|
||||
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@ use App\Models\PolicyPremium2Model;
|
||||
use App\Models\AuditHistoryModel;
|
||||
use App\Models\UserModel;
|
||||
use App\Models\PartnerEndorsementRequestModel;
|
||||
use App\Models\TpaApiDataModel;
|
||||
|
||||
|
||||
use App\Controllers\Jobs;
|
||||
@ -42,6 +43,8 @@ use CodeIgniter\API\ResponseTrait;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||||
|
||||
use Dompdf\Dompdf;
|
||||
use Dompdf\Options;
|
||||
@ -3579,5 +3582,388 @@ class EmployeeController extends AdminController
|
||||
}
|
||||
}
|
||||
|
||||
public function getTPADataVariationReport($file_id)
|
||||
{
|
||||
$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)
|
||||
{
|
||||
//get TPA API data from table for current DB ep code
|
||||
$tpa_temp_data = $TpaApiDataModel->select('*')
|
||||
->where('emp_code', $db_row['emp_code'])
|
||||
->where('file_id', $file_id)
|
||||
->where('is_active', 1)
|
||||
->findAll();
|
||||
$match= $this->reconcileDbWithTpa($db_row,$tpa_temp_data);
|
||||
$emp_data_wo_tpa_id[$db_key]['match'] = $match;
|
||||
}
|
||||
|
||||
// d($emp_data_wo_tpa_id);
|
||||
|
||||
// die();
|
||||
//not_in_tpa
|
||||
$tpa_emp_codes = $TpaApiDataModel->select('emp_code')
|
||||
->where('file_id', $file_id)
|
||||
->where('is_active', 1)
|
||||
->groupBy('emp_code')
|
||||
->findAll();
|
||||
$tpa_emp_codes = array_column($tpa_emp_codes, 'emp_code');
|
||||
|
||||
$not_in_tpa = $this->employeePolicyModel->getTPADataVariationReport($client_id, $client_policy_id, $file_id,$tpa_emp_codes);
|
||||
// d($not_in_tpa);die();
|
||||
|
||||
// not_in_nhance
|
||||
$master_emp_codes = $this->employeePolicyModel->getTPADataVariationReport($client_id, $client_policy_id, $file_id,[],true);
|
||||
$master_emp_codes = array_column($master_emp_codes, 'emp_code');
|
||||
|
||||
$not_in_nhance = $TpaApiDataModel->select('*')
|
||||
->where('is_active',1)
|
||||
->where('file_id',$file_id)
|
||||
->whereNotIn('emp_code',$master_emp_codes)
|
||||
->findAll();
|
||||
// d($not_in_nhance);die();
|
||||
|
||||
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([],[],[]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// not in use once all functionality workes well in this funciton then remvoe this function
|
||||
function compareDbWithTpa(array $db, array $tpaRows): array
|
||||
{
|
||||
$partialMatches = [];
|
||||
|
||||
// Normalize helper
|
||||
$normalizeName = function ($name) {
|
||||
return strtolower(
|
||||
preg_replace('/[.\s_]+/', '', trim($name))
|
||||
);
|
||||
};
|
||||
|
||||
foreach ($tpaRows as $tpa) {
|
||||
|
||||
// 0️⃣ emp_code must match
|
||||
if (($db['emp_code'] ?? '') !== ($tpa['emp_code'] ?? '')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$relationMatch = strtolower($db['relation'] ?? '') === strtolower($tpa['relation'] ?? '');
|
||||
$genderMatch = strtoupper($db['gender'] ?? '') === strtoupper($tpa['gender'] ?? '');
|
||||
$dobMatch = ($db['dob'] ?? '') === ($tpa['dob'] ?? '');
|
||||
|
||||
$nameMatch = $normalizeName($db['name'] ?? '') ===
|
||||
$normalizeName($tpa['name'] ?? '');
|
||||
|
||||
// ✅ FULL MATCH
|
||||
if ($nameMatch && $relationMatch && $genderMatch && $dobMatch) {
|
||||
return [
|
||||
'match' => 'full_match',
|
||||
'record'=> $tpa
|
||||
];
|
||||
}
|
||||
|
||||
// ⚠️ PARTIAL MATCH
|
||||
if ($relationMatch || $genderMatch || $dobMatch) {
|
||||
$partialMatches[] = [
|
||||
'record' => $tpa,
|
||||
'matched_on' => [
|
||||
'relation' => $relationMatch,
|
||||
'gender' => $genderMatch,
|
||||
'dob' => $dobMatch
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// If no full match but partial exists
|
||||
if (!empty($partialMatches)) {
|
||||
return [
|
||||
'match' => 'partial_match',
|
||||
'candidates' => $partialMatches
|
||||
];
|
||||
}
|
||||
|
||||
// Nothing matched
|
||||
return [
|
||||
'match' => 'no_match'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
function reconcileDbWithTpa(array $db, array $tpaRows): array
|
||||
{
|
||||
// Name normalization
|
||||
$normalizeName = function ($name) {
|
||||
return strtolower(
|
||||
preg_replace('/[.\s_]+/', '', trim($name))
|
||||
);
|
||||
};
|
||||
|
||||
foreach ($tpaRows as $tpa) {
|
||||
|
||||
// 1️⃣ emp_code + relation must match
|
||||
if (
|
||||
// ($db['emp_code'] ?? '') !== ($tpa['emp_code'] ?? '') ||
|
||||
strtolower($db['relationship']) !== strtolower($tpa['relation'])
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 2️⃣ Field comparison
|
||||
$diff = [];
|
||||
|
||||
if (
|
||||
($db['name'] ?? '') !==
|
||||
($tpa['name'] ?? '')
|
||||
) {
|
||||
$diff[] = 'name';
|
||||
}
|
||||
|
||||
if (($db['dob'] ?? '') !== ($tpa['dob'] ?? '')) {
|
||||
$diff[] = 'dob';
|
||||
}
|
||||
|
||||
if (
|
||||
strtoupper($db['gender'] ?? '') !==
|
||||
strtoupper($tpa['gender'] ?? '')
|
||||
) {
|
||||
$diff[] = 'gender';
|
||||
}
|
||||
|
||||
// 3️⃣ Match found
|
||||
return [
|
||||
'status' => 'matched',
|
||||
'tpa_record' => $tpa,
|
||||
'not_matching' => $diff // empty = perfect match
|
||||
];
|
||||
}
|
||||
|
||||
// 4️⃣ No match found
|
||||
return [
|
||||
'status' => 'no_match'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
function exportVariationReportExcel(
|
||||
array $notInTPA,
|
||||
array $notInNhance,
|
||||
array $reviewNeeded,
|
||||
string $filename = 'employee_review.xlsx'
|
||||
) {
|
||||
|
||||
function setCell($sheet, int $col, int $row, $value)
|
||||
{
|
||||
$cell = Coordinate::stringFromColumnIndex($col) . $row;
|
||||
$sheet->setCellValue($cell, $value);
|
||||
}
|
||||
|
||||
$EXPORT_COLUMNS = [
|
||||
|
||||
// Sheet 1 — Not in TPA
|
||||
'not_in_tpa' => [
|
||||
'emp_code' => 'Employee Code',
|
||||
'name' => 'Employee Name',
|
||||
'relationship' => 'Relation',
|
||||
'dob' => 'Date of Birth',
|
||||
'gender' => 'Gender',
|
||||
'mobile' => 'Mobile No',
|
||||
'email_corporate' => 'Corporate Email',
|
||||
'policy_no' => 'Policy No',
|
||||
'tpa_name' => 'TPA Name',
|
||||
'change_event' => 'Change Event',
|
||||
],
|
||||
|
||||
// Sheet 2 — Not in Nhance
|
||||
'not_in_nhance' => [
|
||||
'emp_code' => 'Employee Code',
|
||||
'name' => 'Employee Name',
|
||||
'relation' => 'Relation',
|
||||
'dob' => 'Date of Birth',
|
||||
'gender' => 'Gender',
|
||||
'age' => 'Age',
|
||||
'tpa_id' => 'TPA Member ID',
|
||||
],
|
||||
|
||||
// Sheet 3 — Review Needed (DB side)
|
||||
'review_main' => [
|
||||
'emp_code' => 'Employee Code',
|
||||
'name' => 'Employee Name',
|
||||
'relationship' => 'Relation',
|
||||
'dob' => 'Date of Birth',
|
||||
'gender' => 'Gender',
|
||||
'policy_no' => 'Policy No',
|
||||
'uhid' => 'UHID',
|
||||
'change_event' => 'Change event'
|
||||
],
|
||||
|
||||
// Sheet 3 — Review Needed (TPA side)
|
||||
'review_tpa' => [
|
||||
'emp_code' => 'TPA Employee Code',
|
||||
'name' => 'TPA Name',
|
||||
'relation' => 'TPA Relation',
|
||||
'dob' => 'TPA DOB',
|
||||
'gender' => 'TPA Gender',
|
||||
'tpa_id' => 'TPA Member ID',
|
||||
'age' => 'TPA Age',
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
$spreadsheet = new Spreadsheet();
|
||||
|
||||
/* =========================================================
|
||||
* SHEET 1 — NOT IN TPA
|
||||
* ========================================================= */
|
||||
$sheet1 = $spreadsheet->getActiveSheet();
|
||||
$sheet1->setTitle('Not in TPA');
|
||||
|
||||
$cols = $EXPORT_COLUMNS['not_in_tpa'];
|
||||
|
||||
$colNo = 1;
|
||||
foreach ($cols as $label) {
|
||||
setCell($sheet1, $colNo++, 1, $label);
|
||||
}
|
||||
|
||||
$rowNo = 2;
|
||||
foreach ($notInTPA as $row) {
|
||||
$colNo = 1;
|
||||
foreach ($cols as $key => $label) {
|
||||
setCell($sheet1, $colNo++, $rowNo, $row[$key] ?? '');
|
||||
}
|
||||
$rowNo++;
|
||||
}
|
||||
|
||||
foreach (range(1, count($cols)) as $c) {
|
||||
$sheet1->getColumnDimension(Coordinate::stringFromColumnIndex($c))->setAutoSize(true);
|
||||
}
|
||||
|
||||
/* =========================================================
|
||||
* SHEET 2 — NOT IN NHANCE
|
||||
* ========================================================= */
|
||||
$sheet2 = $spreadsheet->createSheet();
|
||||
$sheet2->setTitle('Not in Nhance');
|
||||
|
||||
$cols = $EXPORT_COLUMNS['not_in_nhance'];
|
||||
|
||||
$colNo = 1;
|
||||
foreach ($cols as $label) {
|
||||
setCell($sheet2, $colNo++, 1, $label);
|
||||
}
|
||||
|
||||
$rowNo = 2;
|
||||
foreach ($notInNhance as $row) {
|
||||
$colNo = 1;
|
||||
foreach ($cols as $key => $label) {
|
||||
setCell($sheet2, $colNo++, $rowNo, $row[$key] ?? '');
|
||||
}
|
||||
$rowNo++;
|
||||
}
|
||||
|
||||
foreach (range(1, count($cols)) as $c) {
|
||||
$sheet2->getColumnDimension(Coordinate::stringFromColumnIndex($c))->setAutoSize(true);
|
||||
}
|
||||
|
||||
/* =========================================================
|
||||
* SHEET 3 — REVIEW NEEDED
|
||||
* ========================================================= */
|
||||
$sheet3 = $spreadsheet->createSheet();
|
||||
$sheet3->setTitle('Review Needed');
|
||||
|
||||
$mainCols = $EXPORT_COLUMNS['review_main'];
|
||||
$tpaCols = $EXPORT_COLUMNS['review_tpa'];
|
||||
|
||||
// headers
|
||||
$colNo = 1;
|
||||
foreach ($mainCols as $label) {
|
||||
setCell($sheet3, $colNo++, 1, $label);
|
||||
}
|
||||
foreach ($tpaCols as $label) {
|
||||
setCell($sheet3, $colNo++, 1, $label);
|
||||
}
|
||||
|
||||
// rows
|
||||
$rowNo = 2;
|
||||
foreach ($reviewNeeded as $row) {
|
||||
|
||||
// main (DB)
|
||||
$colNo = 1;
|
||||
foreach ($mainCols as $key => $label) {
|
||||
setCell($sheet3, $colNo++, $rowNo, $row[$key] ?? '');
|
||||
}
|
||||
|
||||
$tpaData = [];
|
||||
$notMatching = [];
|
||||
|
||||
if (($row['match']['status'] ?? '') === 'matched') {
|
||||
$tpaData = $row['match']['tpa_record'] ?? [];
|
||||
$notMatching = $row['match']['not_matching'] ?? [];
|
||||
}
|
||||
|
||||
// TPA
|
||||
foreach ($tpaCols as $key => $label) {
|
||||
setCell($sheet3, $colNo++, $rowNo, $tpaData[$key] ?? '');
|
||||
}
|
||||
|
||||
// highlight mismatches
|
||||
foreach ($notMatching as $field) {
|
||||
|
||||
if (isset($mainCols[$field])) {
|
||||
$idx = array_keys($mainCols);
|
||||
$pos = array_search($field, $idx);
|
||||
$cell = Coordinate::stringFromColumnIndex($pos + 1) . $rowNo;
|
||||
$sheet3->getStyle($cell)->getFill()
|
||||
->setFillType(Fill::FILL_SOLID)
|
||||
->getStartColor()->setARGB('FFFFFF00');
|
||||
}
|
||||
|
||||
if (isset($tpaCols[$field])) {
|
||||
$idx = array_keys($tpaCols);
|
||||
$pos = array_search($field, $idx);
|
||||
$cell = Coordinate::stringFromColumnIndex(count($mainCols) + $pos + 1) . $rowNo;
|
||||
$sheet3->getStyle($cell)->getFill()
|
||||
->setFillType(Fill::FILL_SOLID)
|
||||
->getStartColor()->setARGB('FFFFFF00');
|
||||
}
|
||||
}
|
||||
|
||||
$rowNo++;
|
||||
}
|
||||
|
||||
foreach (range(1, count($mainCols) + count($tpaCols)) as $c) {
|
||||
$sheet3->getColumnDimension(Coordinate::stringFromColumnIndex($c))->setAutoSize(true);
|
||||
}
|
||||
|
||||
/* =========================================================
|
||||
* OUTPUT
|
||||
* ========================================================= */
|
||||
$writer = new Xlsx($spreadsheet);
|
||||
|
||||
if (ob_get_length()) ob_end_clean();
|
||||
|
||||
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||
header('Content-Disposition: attachment; filename="' . $filename . '"');
|
||||
header('Cache-Control: max-age=0');
|
||||
|
||||
$writer->save('php://output');
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -351,6 +351,7 @@ class MediAssistApiController extends BaseController
|
||||
|
||||
|
||||
// now update DB
|
||||
$batch_file_success = 'success';
|
||||
$updated = 0;
|
||||
$employee_policy_ids = [];
|
||||
foreach ($employeePolicyData as $policy_data) {
|
||||
@ -401,6 +402,7 @@ class MediAssistApiController extends BaseController
|
||||
'gender' => $policy_data['gender'] ?? null,
|
||||
'dob' => $policy_data['dob'] ?? null,
|
||||
];
|
||||
$batch_file_success = 'partially success';
|
||||
|
||||
log_message(
|
||||
'error',
|
||||
@ -421,7 +423,8 @@ class MediAssistApiController extends BaseController
|
||||
// update file table status after the tpa id successfully updated
|
||||
if (isset($requestData['file_id']) && !empty($requestData['file_id'])) {
|
||||
$file_model = new BatchFileModel();
|
||||
$file_model->where('id', $requestData['file_id'])->set('status', 'success')->update();
|
||||
|
||||
$file_model->where('id', $requestData['file_id'])->set('status', $batch_file_success)->update();
|
||||
log_message('error', "Files table status updated for the file id : {$requestData['file_id']}");
|
||||
} else {
|
||||
log_message('error', "Failed to update file table status.");
|
||||
|
||||
@ -2139,5 +2139,60 @@ class EmployeePolicyModel extends Model
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getTPADataVariationReport($client_id, $client_policy_id, $file_id,$emp_codes = [],$all = false)
|
||||
{
|
||||
$result = $this->select([
|
||||
'employee_polices.*',
|
||||
'tpam.name as tpa_name',
|
||||
'tpam.short_name as tpa_short_name',
|
||||
'emp.relationship',
|
||||
'emp.relationship_code',
|
||||
'emp.change_event',
|
||||
'emp.emp_code',
|
||||
'emp.name',
|
||||
'emp.email_corporate',
|
||||
'emp.dob',
|
||||
'emp.gender',
|
||||
'emp.emp_status',
|
||||
'emp.is_active as emp_is_active',
|
||||
'emp.mobile as mobile',
|
||||
'emp.doj',
|
||||
'emp.basic_pay',
|
||||
'emp.band as grade',
|
||||
'cp.policy_no',
|
||||
'cp.policy_type_id',
|
||||
|
||||
])
|
||||
->join('employees emp', 'employee_polices.employee_id = emp.id')
|
||||
->join('client_policy cp', 'employee_polices.client_policy_id = cp.id')
|
||||
->join('tpa tpam', 'cp.tpa_id = tpam.id', 'left') //tpam - tpa master
|
||||
// ->orderBy('emp.emp_code', 'ASC')
|
||||
// ->orderBy('employee_polices.employee_id', 'ASC');
|
||||
->where('employee_polices.status', 'active')
|
||||
->where('employee_polices.is_active', 1)
|
||||
->where('emp.is_active', 1)
|
||||
->where('employee_polices.status !=', 'inactive')
|
||||
->where('cp.id', $client_policy_id)
|
||||
->where('employee_polices.client_policy_id', $client_policy_id)
|
||||
->where('emp.client_id', $client_id);
|
||||
|
||||
if(count($emp_codes) == 0 && $all == false)
|
||||
{
|
||||
$result->where('employee_polices.tpa_id IS NULL');
|
||||
}
|
||||
else if(count($emp_codes) > 0 && $all == false)
|
||||
{
|
||||
$result->whereNotIn('emp.emp_code',$emp_codes);
|
||||
}
|
||||
else if(count($emp_codes) == 0 && $all == true)
|
||||
{
|
||||
$result->groupBy('emp.emp_code');
|
||||
}
|
||||
|
||||
return $result->findAll();
|
||||
// print_r($result);
|
||||
// return $result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -176,6 +176,12 @@
|
||||
<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 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 } ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@ -813,6 +813,11 @@
|
||||
}
|
||||
|
||||
function fetchTpaIdFromTpa(){
|
||||
let user_confirm = confirm('Are you sure you want to initiate the TPA fetch? This may take a while.');
|
||||
if(!user_confirm)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
let event = $('#event_type').val();
|
||||
let client_id = $('#client').val();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user