7430 lines
322 KiB
PHP
Executable File
7430 lines
322 KiB
PHP
Executable File
<?php
|
||
|
||
namespace App\Controllers;
|
||
|
||
use CodeIgniter\HTTP\IncomingRequest;
|
||
use CodeIgniter\HTTP\RequestInterface;
|
||
use CodeIgniter\HTTP\ResponseInterface;
|
||
use Psr\Log\LoggerInterface;
|
||
|
||
use App\Helpers\DepositHelper;
|
||
use App\Helpers\MailHelper;
|
||
|
||
|
||
use App\Models\EmployeeModel;
|
||
use App\Models\EmployeePolicyModel;
|
||
use App\Models\ClientModel;
|
||
use App\Models\ClientBranchModel;
|
||
use App\Models\PolicesModel;
|
||
use App\Models\FileModel;
|
||
use App\Models\BatchListModel;
|
||
use App\Models\BatchFileModel;
|
||
use App\Models\EmpEndorsementModel;
|
||
use App\Models\ClientPolicyModel;
|
||
use App\Models\TPAModel;
|
||
use App\Models\InsurerExcelExportTemplateModel;
|
||
use App\Models\InsurerModel;
|
||
use App\Models\ClientDepositModel;
|
||
use App\Models\PolicyPremium2Model;
|
||
use App\Models\AuditHistoryModel;
|
||
use App\Models\UserModel;
|
||
use App\Models\PartnerEndorsementRequestModel;
|
||
use App\Models\TpaApiDataModel;
|
||
use App\Models\LevelContactModel;
|
||
use App\Models\NotificationModel;
|
||
|
||
|
||
use App\Controllers\Jobs;
|
||
use App\Controllers\JobWorker;
|
||
use App\Controllers\Jobs\SubJob;
|
||
use App\Controllers\EmployeeServiceController;
|
||
use App\Controllers\EmpDataServiceController;
|
||
use App\Models\LeadsModel;
|
||
use App\Models\ThzMasterModel;
|
||
use App\Models\UserActivityHistoryModel;
|
||
use CodeIgniter\API\ResponseTrait;
|
||
|
||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||
use PhpOffice\PhpSpreadsheet\Writer\Xls;
|
||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||
|
||
use Dompdf\Dompdf;
|
||
use Dompdf\Options;
|
||
use Kint;
|
||
|
||
use Firebase\JWT\JWT;
|
||
|
||
class EmployeeController extends AdminController
|
||
{
|
||
|
||
use ResponseTrait;
|
||
|
||
protected $myLogger;
|
||
protected $employeeModel;
|
||
protected $employeePolicyModel;
|
||
protected $clientModel;
|
||
protected $clientBranchModel;
|
||
protected $fileModel;
|
||
protected $batchListModel;
|
||
protected $batchFileModel;
|
||
protected $empEndorsementModel;
|
||
protected $clientPolicyModel;
|
||
protected $TPAModel;
|
||
protected $policiesModel;
|
||
protected $excelExportTemplateModel;
|
||
protected $insurerModel;
|
||
protected $cashDepositModel;
|
||
protected $PolicyPremium2Model;
|
||
protected $auditHistory;
|
||
protected $userModel;
|
||
protected $partnerEndorsementRequestModel;
|
||
protected $LevelContactModel;
|
||
protected $UserActivityHistoryModel;
|
||
|
||
public function __construct()
|
||
{
|
||
// helper('utility');
|
||
set_session_context('Employee');
|
||
$this->myLogger = \Config\Services::mylogger();
|
||
$this->employeeModel = new EmployeeModel();
|
||
$this->employeePolicyModel = new EmployeePolicyModel();
|
||
$this->clientModel = new ClientModel();
|
||
$this->clientBranchModel = new ClientBranchModel();
|
||
$this->fileModel = new FileModel();
|
||
$this->batchListModel = new BatchListModel();
|
||
$this->batchFileModel = new BatchFileModel();
|
||
$this->empEndorsementModel = new EmpEndorsementModel();
|
||
$this->clientPolicyModel = new ClientPolicyModel();
|
||
$this->TPAModel = new TPAModel();
|
||
$this->policiesModel = new PolicesModel();
|
||
$this->insurerModel = new InsurerModel();
|
||
$this->cashDepositModel = new ClientDepositModel();
|
||
$this->PolicyPremium2Model = new PolicyPremium2Model();
|
||
$this->auditHistory = new AuditHistoryModel();
|
||
$this->userModel = new userModel();
|
||
$this->partnerEndorsementRequestModel = new PartnerEndorsementRequestModel();
|
||
$this->LevelContactModel = new LevelContactModel();
|
||
$this->UserActivityHistoryModel = new UserActivityHistoryModel();
|
||
}
|
||
|
||
public function list()
|
||
{
|
||
|
||
// $s3 = \Config\Services::getS3Service();
|
||
// $file = WRITEPATH.'uploads/excel/inception.ods';
|
||
// print_rr($s3->exists('inception_1766475604.ods'));
|
||
// print_rr($s3->getPresignedUrl('inception_1766.ods'));
|
||
// print_rr($s3->upload($file));
|
||
// print_rr($s3->download('inception_1766475604.ods',__DIR__));
|
||
// die();
|
||
// $model = new UserModel();
|
||
$data = [];
|
||
$data['status'] = ['draft' => 'Draft', 'enrolled' => 'Enrolled', 'active' => 'Active', 'inactive' => 'In-Active', 'pending' => 'Pending'];
|
||
|
||
if (count($this->request->getGet())) {
|
||
$filterData = $this->request->getGet();
|
||
|
||
// Convert the status field to an array if it exists in the request data
|
||
if (isset($filterData['status']) && !empty($filterData['status'])) {
|
||
// $filterData['status'] = explode(",", $filterData['status']);
|
||
}else{
|
||
$filterData['status'] = [];
|
||
}
|
||
|
||
// Fetch employees with the modified $filterData array
|
||
$data['employees'] = $this->employeePolicyModel->getEmployeePolicy(
|
||
client_id: $filterData['client_id'] ?? null,
|
||
policy_id: $filterData['policy_id'] ?? null,
|
||
branch_id: $filterData['branch_id'] ?? null,
|
||
emp_code : $filterData['emp_code'] ?? null,
|
||
emp_name : $filterData['emp_name'] ?? null,
|
||
status : $filterData['status'] ?? [],
|
||
);
|
||
// log_message('error',json_encode($data['employees']));
|
||
// Set getData in $data array with the processed $filterData
|
||
$data['getData'] = $filterData;
|
||
|
||
// return view('employee_list',$data);
|
||
$html = view('employee_data_list', $data);
|
||
return $this->respond(['status' => true, 'html' => $html], 200);
|
||
|
||
}
|
||
|
||
// dd($this->employeeModel->getLastQuery());
|
||
// dd( $data['getData']);
|
||
|
||
// dd($this->request->getGet());
|
||
$this->myLogger->logme('error', 'list called');
|
||
$data['tab_name'] = 'Members';
|
||
$data['page_name'] = "Members";
|
||
|
||
$this->loadLayout('employee_list', $data);
|
||
}
|
||
|
||
public function getClientWithPolicies()
|
||
{
|
||
try {
|
||
//echo $this->request->isAJAX();die();
|
||
$result = $this->clientModel->clientsWithPolicies();
|
||
|
||
// dd($result);
|
||
|
||
// print_r($result);die();
|
||
if (!count($result)) {
|
||
return $this->respond(['dataStatus' => false, 'code' => 404, 'message' => 'no data found'], 200);
|
||
} else {
|
||
|
||
return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => $result], 200);
|
||
}
|
||
} catch (\Throwable $th) {
|
||
return $this->respond(['dataStatus' => false, 'code' => 500, 'message' => $th->getMessage()], 500);
|
||
}
|
||
}
|
||
|
||
|
||
public function getUploadedFileError()
|
||
{
|
||
$file_id = $this->request->uri->getSegment(3);
|
||
// dd($segments[2]);
|
||
// die();
|
||
// $file_id = $this->request->getGet();
|
||
// echo $file_id;die();
|
||
$file = $this->fileModel->find((int)$file_id);
|
||
// print_r($result);die();
|
||
if (!isset($file)) {
|
||
return $this->respond(['dataStatus' => false, 'code' => 404, 'message' => 'no data found'], 200);
|
||
} else {
|
||
|
||
return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => $file['reason'], 'is_comparison_skipped' => $file['is_comparison_skipped'], 'policy_id' => $file['policy_id']], 200);
|
||
}
|
||
}
|
||
|
||
//handles employee & dependent bulk upload with events like inception,addition,deletion, correction and SI enhancements
|
||
public function employeesUplodWithEvents($post_data = null)
|
||
{
|
||
|
||
// $empDataServiceController = new EmpDataServiceController();
|
||
// !dd($empDataServiceController->importInceptionUpdateTPAandUHID(['file_id' => 79]));
|
||
|
||
|
||
// $job_details = new Jobs();
|
||
// $r = Jobs::addJob(['job_name' => 'add','payload' => ['a' => 10, 'b' => 35]]);
|
||
// print_r($r);//die();
|
||
// // $jobWorker = new JobWorker();
|
||
// JobWorker::processJob($r);
|
||
// die();
|
||
// echo $this->request->getMethod();die();
|
||
// print_r($this->request->getFiles('emplist'));print_r($this->request->getPost('emplist'));
|
||
// print_r($this->request->getPost('clients'));
|
||
// print_r($this->request->getPost('policies'));
|
||
// print_r($this->request->getPost('upload-action-type'));
|
||
// die();
|
||
// $empServiceController = new EmployeeServiceController();
|
||
// $res = $empServiceController->excelFileDataValidation(['file_id' => '933']);
|
||
// dd($res);
|
||
|
||
// $empServiceController = new EmployeeServiceController();
|
||
// $res = $empServiceController->employeeDisembark(['file_id' => '586']);
|
||
// dd($res);
|
||
// $existing_famility_details = $this->employeeModel->getEmpFamilybyEmpCode(client_policy_id: '2');
|
||
// dd($existing_famility_details);
|
||
// $empServiceController = new EmployeeServiceController();
|
||
// $res = $empServiceController->employeesSIEnhanceProcess(['file_id' => '38']);
|
||
// dd($res);
|
||
|
||
// $empServiceController = new EmployeeServiceController();
|
||
// $res = $empServiceController->employeesCorrectionProcess(['file_id' => '37']);
|
||
// // dd($res);
|
||
// $empServiceController = new EmployeeServiceController();
|
||
// $res = $empServiceController->employeesOnboardPreprocess(['client_policy_id' => '3']);
|
||
// dd($res);
|
||
|
||
// $empServiceController = new EmployeeServiceController();
|
||
// $res = $empServiceController->employeeDisembark(['file_id' => '36']);
|
||
// dd($res);
|
||
|
||
// if(isset($res['error_summary']) && count($res['error_summary']))
|
||
// {
|
||
// $res['error_summary'] = (array_count_values($res['error_summary']));
|
||
// $failure_reason = ((json_encode($res)));
|
||
// // dd($failure_reason);
|
||
// $this->fileModel->where('id', '12')->set(['status' => 'failed','reason' => $failure_reason])->update();
|
||
// dd($failure_reason);
|
||
// }
|
||
// $this->truncateFileData(747, 5) ;
|
||
// print_rr($this->cloneWorksheet());
|
||
// die();
|
||
|
||
if (!empty($post_data) || $this->request->is('post') == 'post') {
|
||
|
||
//validate uploaded file
|
||
$filename = '';
|
||
$fileSize = '';
|
||
|
||
if (empty($post_data)) {
|
||
$validated = $this->validate([
|
||
'emplist' => [
|
||
'uploaded[emplist]',
|
||
'mime_in[emplist,application/vnd.ms-excel,application/vnd,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.oasis.opendocument.spreadsheet]',
|
||
'max_size[emplist,16384]',
|
||
],
|
||
]);
|
||
} else {
|
||
$validated = validateExcelFile($post_data['file_name']);
|
||
}
|
||
|
||
if ($validated) {
|
||
|
||
$avatar = isset($post_data['file_name']) ? $post_data['file_name'] : $this->request->getFile('emplist');
|
||
if (!$avatar) {
|
||
$this->myLogger->logme("error", 'File not found');
|
||
if (!empty($post_data)) {
|
||
return ['status' => false, 'message' => 'File not found'];
|
||
} else {
|
||
return $this->respond(['dataStatus' => false, 'code' => 400, 'message' => 'File not found'], 400);
|
||
}
|
||
}
|
||
|
||
$fileSizeBytes = (is_object($avatar) && method_exists($avatar, 'getSize')) ? (int) $avatar->getSize() : 0;
|
||
$filename = storage_file_Upload($avatar, WRITEPATH . 'uploads/excel/', UPLOAD_EXT_EXCEL);
|
||
if ($filename !== '') {
|
||
$fileSize = $fileSizeBytes / (1024 * 1024); // Convert to MB
|
||
$this->myLogger->logme("error", 'File move successful');
|
||
} else {
|
||
$this->myLogger->logme("error", 'File move failed');
|
||
if (!empty($post_data)) {
|
||
return ['status' => false, 'message' => 'File move failed'];
|
||
} else {
|
||
return $this->respond(['dataStatus' => false, 'code' => 500, 'message' => 'File move failed'], 500);
|
||
}
|
||
}
|
||
} else {
|
||
$this->myLogger->logme("error", 'Upload failed Invalid file');
|
||
if (!empty($post_data)) {
|
||
return ['status' => false, 'message' => 'Invalid file'];
|
||
} else {
|
||
return $this->respond(['dataStatus' => false, 'code' => 404, 'message' => 'Invalid file'], 404);
|
||
}
|
||
}
|
||
|
||
//process post variable entry in file table
|
||
$loggedInUserID = $post_data['created_by'] ?? get_session_userid();
|
||
|
||
$client_id = isset($post_data['client_id']) ? $post_data['client_id'] : $this->request->getPost('client_id');
|
||
$policy_id = isset($post_data['policy_id']) ? $post_data['policy_id'] : $this->request->getPost('policy_id');
|
||
$branch_id = isset($post_data['client_branch_id']) ? $post_data['client_branch_id'] : $this->request->getPost('branch_id');
|
||
$action = isset($post_data['file_action']) ? $post_data['file_action'] : $this->request->getPost('upload-action-type');
|
||
|
||
if (empty($post_data)) {
|
||
$hr_file_id = $this->request->getPost('hr_file_id') ?? null;
|
||
} else {
|
||
$hr_file_id = $post_data['hr_file_id'] ?? null;
|
||
}
|
||
|
||
$hr_id = $post_data['created_by'] ?? null;
|
||
$status = 'inprogress';
|
||
|
||
$file_id = $this->fileModel->insert(['file_name' => $filename, 'client_id' => $client_id, 'policy_id' => $policy_id, 'created_by' => $loggedInUserID, 'status' => $status, 'action' => $action, 'client_branch_id' => $branch_id, 'uploaded_by' => 1, 'hr_file_id' => $hr_file_id, 'hr_id' => $hr_id]); //here field policy_id have client_policy_id and not policy id from policy master
|
||
$this->myLogger->logme("error", '{file_id} uploaded success', ['file_id' => $file_id]);
|
||
|
||
if ($action == "all") {
|
||
|
||
$r = Jobs::addJob(['job_name' => 'excelMultieventFileFormateValidation', 'payload' => ['file_id' => $file_id]]);
|
||
$this->myLogger->logme("error", '{file_id} is greather than 1MB, validating with job queue', ['file_id' => $file_id]);
|
||
} else {
|
||
//start validation process
|
||
if ($fileSize < 1) // if file size less than 1
|
||
{
|
||
$empServiceController = new EmployeeServiceController();
|
||
$result = $empServiceController->excelFileFormatValidation(['file_id' => $file_id]);
|
||
$this->myLogger->logme("error", '{file_id} is less than 1MB, validating on the fly', ['file_id' => $file_id]);
|
||
//endof validation process
|
||
if (isset($result['error_summary']) && count($result['error_summary'])) {
|
||
if (!empty($post_data)) {
|
||
return ['status' => false, 'message' => 'File rejected with errors', 'file_id' => $file_id];
|
||
} else {
|
||
return $this->respond(['dataStatus' => false, 'code' => 404, 'message' => 'File rejected with errors'], 200);
|
||
}
|
||
}
|
||
} else //if file size greater than 1 add the file as job
|
||
{
|
||
$job_details = new Jobs();
|
||
$r = Jobs::addJob(['job_name' => 'excelFileFormatValidation', 'payload' => ['file_id' => $file_id]]);
|
||
$this->myLogger->logme("error", '{file_id} is greather than 1MB, validating with job queue', ['file_id' => $file_id]);
|
||
}
|
||
}
|
||
|
||
if (!empty($post_data)) {
|
||
return ['status' => true, 'message' => 'File upload successs, Data validation is in-progress', 'file_id' => $file_id];
|
||
} else {
|
||
return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => 'file upload success'], 200);
|
||
}
|
||
}
|
||
|
||
$get_data = $this->request->getGet();
|
||
// dd($get_data);
|
||
|
||
$data['tab_name'] = 'View Inception';
|
||
$data['page_name'] = 'View Inception';
|
||
|
||
//for TPA/insurer upload
|
||
$data['events'] = ['inception' => 'Inception (Employee + Dependents)', 'missed_inception' => 'Missed Inception (Employee + Dependents)', 'addition' => 'Addition (Employee + Dependents)', 'dependent_addition' => 'Dependent Addition (Only Dependents)', 'deletion' => 'Deletion', 'correction' => 'Correction', 'si_enhancement' => 'SI Enhancement'];
|
||
//for inception upload
|
||
$data['actions'] = ['all' => 'All', 'inception' => 'Inception (Employee + Dependents)', 'missed_inception' => 'Missed Inception (Employee + Dependents)', 'addition' => 'Addition (Employee + Dependents)', 'dependent_addition' => 'Dependent Addition (Only Dependents)', 'deletion' => 'Deletion', 'correction' => 'Correction', 'si_enhancement' => 'SI Enhancement'];
|
||
// $data['actions'] = ['inception' => 'Inception (Employee + Dependents)', 'missed_inception' => 'Missed Inception (Employee + Dependents)', 'addition' => 'Addition (Employee + Dependents)', 'dependent_addition' => 'Dependent Addition (Only Dependents)', 'deletion' => 'Deletion', 'correction' => 'Correction', 'si_enhancement' => 'SI Enhancement','enrollment' => 'Enrolment'];
|
||
|
||
// $data['import_or_export'] = ['import' => 'Import', 'export' => 'Export'];
|
||
$data['import_or_export'] = ['import' => 'Upload', 'export' => 'Download'];
|
||
$data['insurer_or_tpa'] = ['insurer' => 'Insurer', 'tpa' => 'TPA'];
|
||
|
||
// $data['fileList'] = $this->fileModel
|
||
// ->select(['files.*', 'up.emp_code', 'up.first_name', 'pm.name as policy_name', 'c.short_name', 'cp.id as client_policy_id'])
|
||
// ->join('user_profiles up', 'files.created_by = up.id')
|
||
// ->join('client_policy cp', 'files.policy_id = cp.id', 'left')
|
||
// ->join('policies pm', 'cp.policy_id = pm.id', 'left')
|
||
// ->join('clients c', 'files.client_id = c.id and files.client_id = cp.client_id', 'left')
|
||
// ->where('files.created_by', get_session_userid())->orderBy('files.created_at', 'desc')->findAll();
|
||
// dd($this->fileModel->getLastQuery());
|
||
$role_id = get_role_id();
|
||
$user_id = get_session_userid();
|
||
|
||
$query = $this->fileModel
|
||
->select([
|
||
'files.id',
|
||
'files.file_name',
|
||
'files.created_by',
|
||
'files.created_at',
|
||
'files.is_active',
|
||
'files.status',
|
||
'files.client_id',
|
||
'files.policy_id',
|
||
'files.client_branch_id',
|
||
'files.action',
|
||
'files.uploaded_by',
|
||
'up.emp_code',
|
||
// 'up.first_name',
|
||
'c.short_name',
|
||
'cb.branch_name',
|
||
'cp.id as client_policy_id',
|
||
'"0" as employee_count',
|
||
'"0" as total',
|
||
'policy_type.policy_type',
|
||
'cp.policy_no',
|
||
"CASE
|
||
WHEN files.hr_id IS NOT NULL THEN
|
||
CONCAT(
|
||
(
|
||
SELECT lc.name
|
||
FROM level_contacts lc
|
||
WHERE lc.id = files.hr_id
|
||
LIMIT 1
|
||
),
|
||
' (HR)'
|
||
)
|
||
ELSE up.first_name
|
||
END AS first_name
|
||
"
|
||
])
|
||
->join('user_profiles up', 'files.created_by = up.id', 'left')
|
||
->join('client_policy cp', 'files.policy_id = cp.id', 'left')
|
||
->join('client_branch cb', 'files.client_branch_id = cb.id', 'left')
|
||
->join('policy_type', 'policy_type.id = cp.policy_type_id')
|
||
->join('clients c', 'files.client_id = c.id and files.client_id = cp.client_id', 'left')
|
||
->join("client_rm cr", "cr.client_id = c.id and cr.is_active = 1", 'left')
|
||
->where('files.is_active', 1);
|
||
|
||
if (!empty($get_data['start_date'] ?? null) && !empty($get_data['end_date'] ?? null)) {
|
||
// 1. If dates are provided, use the user's filter
|
||
$start = change_date_format($get_data['start_date'], 'd/m/Y', 'Y-m-d') . ' 00:00:00';
|
||
$end = change_date_format($get_data['end_date'], 'd/m/Y', 'Y-m-d') . ' 23:59:59';
|
||
|
||
$query->where('files.created_at >=', $start)
|
||
->where('files.created_at <=', $end);
|
||
} else {
|
||
if(empty($get_data['tab_type'] ?? null)){
|
||
// 2. Default: If no dates are selected, show last 90 days (or all data)
|
||
$query->where('files.created_at >=', date('Y-m-d 00:00:00', strtotime('-90 days')))
|
||
->where('files.created_at <=', date('Y-m-d 23:59:59'));
|
||
}
|
||
}
|
||
|
||
if(!empty($get_data['client_id'] ?? null)){
|
||
$query->where('files.client_id', $get_data['client_id']);
|
||
}
|
||
|
||
if(!empty($get_data['client_branch_id'] ?? null)){
|
||
$query->where('files.client_branch_id', $get_data['client_branch_id']);
|
||
}
|
||
|
||
if(!empty($get_data['policy_id'] ?? null)){
|
||
$query->where('files.policy_id', $get_data['policy_id']);
|
||
}
|
||
|
||
if(!empty($get_data['event_type'] ?? null)){
|
||
$query->where('files.action', $get_data['event_type']);
|
||
}
|
||
|
||
if (in_array($role_id, [2, 3])) {
|
||
// If the user is a Account Manager or Manager, filter by user_id
|
||
$query->where('cr.user_id', (int)$user_id);
|
||
}
|
||
|
||
$data['fileList'] = $query->groupBy("files.id")
|
||
->orderBy('files.created_at', 'desc')
|
||
->find();
|
||
|
||
// dd($this->fileModel->getLastQuery());
|
||
// dd($data['fileList']);
|
||
|
||
$query2 = $this->batchFileModel->select("
|
||
|
||
batch_files.id,
|
||
batch_files.client_id,
|
||
batch_files.client_policy_id,
|
||
batch_files.batch_code,
|
||
batch_files.file_name,
|
||
batch_files.insurer_or_tpa,
|
||
batch_files.event_type,
|
||
batch_files.actions,
|
||
batch_files.count,
|
||
batch_files.created_by,
|
||
batch_files.created_at,
|
||
batch_files.updated_by,
|
||
batch_files.updated_at,
|
||
batch_files.is_active,
|
||
batch_files.amount,
|
||
batch_files.status,
|
||
batch_files.icici_status_flag,
|
||
batch_files.client_branch_id,
|
||
insurers.short_name as insurer_short_name,
|
||
tpa.short_name as tpa_short_name,
|
||
DATE_FORMAT(batch_files.policy_issue_date, '%d/%m/%Y') AS policy_issue_date,
|
||
|
||
CASE
|
||
WHEN batch_files.status IN ('partially success', 'in-progress-partially', 'failed-7')
|
||
THEN batch_files.error_data
|
||
ELSE NULL
|
||
END AS error_data,
|
||
|
||
clients.short_name as client_short_name,
|
||
client_branch.branch_name,
|
||
client_policy.policy_no,
|
||
policy_type.policy_type
|
||
|
||
")
|
||
->join('client_policy', 'client_policy.id = batch_files.client_policy_id')
|
||
->join('insurers', 'client_policy.insurer_id = insurers.id')
|
||
->join('tpa', 'client_policy.tpa_id = tpa.id', 'left')
|
||
->join('client_branch', 'client_branch.id = batch_files.client_branch_id')
|
||
->join('policy_type', 'policy_type.id = client_policy.policy_type_id')
|
||
->join('clients', 'clients.id = client_policy.client_id')
|
||
->join("client_rm cr", "cr.client_id = clients.id and cr.is_active = 1", 'left')
|
||
->where('batch_files.is_active', 1);
|
||
|
||
if (!empty($get_data['start_date'] ?? null) && !empty($get_data['end_date'] ?? null)) {
|
||
// 1. If dates are provided, use the user's filter
|
||
$start = change_date_format($get_data['start_date'], 'd/m/Y', 'Y-m-d') . ' 00:00:00';
|
||
$end = change_date_format($get_data['end_date'], 'd/m/Y', 'Y-m-d') . ' 23:59:59';
|
||
|
||
$query2->where('batch_files.created_at >=', $start)
|
||
->where('batch_files.created_at <=', $end);
|
||
|
||
} else {
|
||
if(empty($get_data['tab_type'] ?? null)){
|
||
// 2. Default: If no dates are selected, show last 90 days (or all data)
|
||
$query2->where('batch_files.created_at >=', date('Y-m-d 00:00:00', strtotime('-90 days')))
|
||
->where('batch_files.created_at <=', date('Y-m-d 23:59:59'));
|
||
}
|
||
}
|
||
|
||
if(!empty($get_data['client_id'] ?? null)){
|
||
$query2->where('batch_files.client_id', $get_data['client_id']);
|
||
}
|
||
|
||
if(!empty($get_data['client_branch_id'] ?? null)){
|
||
$query2->where('batch_files.client_branch_id', $get_data['client_branch_id']);
|
||
}
|
||
|
||
if(!empty($get_data['policy_id'] ?? null)){
|
||
$query2->where('batch_files.client_policy_id', $get_data['policy_id']);
|
||
}
|
||
|
||
if(!empty($get_data['event_type'] ?? null)){
|
||
$query2->where('batch_files.event_type', $get_data['event_type']);
|
||
}
|
||
|
||
if(!empty($get_data['insurer_or_tpa'] ?? null)){
|
||
$query2->where('batch_files.insurer_or_tpa', $get_data['insurer_or_tpa']);
|
||
}
|
||
|
||
if(!empty($get_data['action_type'] ?? null)){
|
||
$query2->where('batch_files.actions', $get_data['action_type']);
|
||
}
|
||
|
||
if (in_array($role_id, [2, 3])) {
|
||
|
||
// If the user is a Account Manager or Manager, filter by user_id
|
||
$query2->where('cr.user_id', (int)$user_id);
|
||
}
|
||
|
||
$data['batch_list'] = $query2->groupBy("batch_files.id")
|
||
->orderBy('batch_files.id', 'desc')
|
||
->find();
|
||
|
||
// dd($data['fileList']);die();
|
||
if ($this->request->getMethod() == "get") {
|
||
$this->loadLayout('import_export', $data);
|
||
}
|
||
}
|
||
|
||
public function getExcelFileErrors($file_id, $retun_type = null)
|
||
{
|
||
|
||
$file_data = $this->fileModel->where('id', $file_id)->first();
|
||
$error = json_decode($file_data['reason'] ?? '{}', true);
|
||
if(!empty($error) && $retun_type == 'api'){
|
||
$send = isset($error['error_summary'][5]) || isset($error['error_summary'][6]) ? true : false;
|
||
if($send){
|
||
|
||
|
||
$string = $error['error_data'] ?? 'System error';
|
||
|
||
$errorMap = [
|
||
"Column order conflict" => "Invalid file format. Please use the sample file.",
|
||
];
|
||
|
||
$message = $string; // Default to the original error
|
||
|
||
foreach ($errorMap as $keyword => $friendlyMessage) {
|
||
if (strpos($string, $keyword) !== false) {
|
||
$message = $friendlyMessage;
|
||
break; // Stop looking once we find a match
|
||
}
|
||
}
|
||
|
||
|
||
return $this->respond(['status' => false, 'code' => 404, 'message' => $message, 'data' => []], 200);
|
||
}
|
||
}
|
||
|
||
// $file_id = $this->request->uri->getSegment(3);
|
||
$empServiceController = new EmployeeServiceController();
|
||
|
||
// Render views and capture output
|
||
$result = $empServiceController->getExcelErrorData($file_id);
|
||
|
||
if($retun_type == 'api'){
|
||
if(!empty($result)){
|
||
return $this->respond(['status' => true, 'code' => 200, 'message' => 'Error data feteched successfully', 'data' => $result], 200);
|
||
}else{
|
||
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Failed to fetch error data', 'data' => []], 200);
|
||
}
|
||
}
|
||
|
||
if ($result != 0) {
|
||
|
||
$result['file_id'] = $file_id;
|
||
echo view('excel_errors', $result);
|
||
} else if ($result == 0) {
|
||
|
||
$data['message'] = 'File Not Found Physically';
|
||
return view('errors/404', $data);
|
||
} else {
|
||
|
||
echo view('errors/html/production');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* The below function Downloads a sample Excel file based on the provided action type.
|
||
*
|
||
* @param string|null $actionType The type of action :
|
||
*
|
||
* - inception
|
||
* - correction
|
||
* - si_enhancement for selecting the appropriate sample Excel file.
|
||
*
|
||
* @return redirect back with an error message if the file is not found, otherwise sends the file to the user for download.
|
||
*/
|
||
|
||
public function downloadSampleExcelFile($actionType = null)
|
||
{
|
||
// $actionType = $this->request->getGet();
|
||
$filePath = '';
|
||
// Path to your file
|
||
if ($actionType == 'inception') {
|
||
$filePath = ROOTPATH . 'public/sample_excel/sample_inception.xls';
|
||
} else if ($actionType == 'correction') {
|
||
$filePath = ROOTPATH . 'public/sample_excel/sample_correction.xls';
|
||
} else if ($actionType == 'si_enhancement') {
|
||
$filePath = ROOTPATH . 'public/sample_excel/sample_si_enhancement.xls';
|
||
} else if ($actionType == 'dependent_addition') {
|
||
$filePath = ROOTPATH . 'public/sample_excel/sample_dependent_addition.xls';
|
||
} else if ($actionType == 'addition') {
|
||
$filePath = ROOTPATH . 'public/sample_excel/sample_addition.xls';
|
||
} else if ($actionType == 'deletion') {
|
||
$filePath = ROOTPATH . 'public/sample_excel/sample_deletion.xls';
|
||
} else if ($actionType == 'enrollment') {
|
||
$filePath = ROOTPATH . 'public/sample_excel/enrollment.xlsx';
|
||
}else if ($actionType == 'missed_inception') {
|
||
$filePath = ROOTPATH . 'public/sample_excel/sample_inception.xls';
|
||
}else if ($actionType == 'member_data') {
|
||
$filePath = ROOTPATH . 'public/sample_excel/Sample_Member_Data.xlsx';
|
||
}else if ($actionType == 'all') {
|
||
$filePath = ROOTPATH . 'public/sample_excel/sample_multievent_file.xlsx';
|
||
}else if ($actionType == 'bds_upload') {
|
||
$filePath = ROOTPATH . 'public/sample_excel/sample_bds_bulk_upload_excel.xlsx';
|
||
}else if ($actionType == 'claim_dump_upload') {
|
||
$filePath = ROOTPATH . 'public/sample_excel/sample_claim_dump_upload_excel.xlsx';
|
||
}
|
||
|
||
// Check if the file exists
|
||
if (file_exists($filePath)) {
|
||
|
||
// Set the appropriate MIME type
|
||
$mimeType = mime_content_type($filePath);
|
||
|
||
// Send the file to the client for download
|
||
return $this->response->download($filePath, null, $mimeType);
|
||
} else {
|
||
// File not found, show an error message or redirect
|
||
echo view('errors/404.php', ['message' => 'Sample file not found']);
|
||
// return redirect()->back()->with('error', 'Sample file not found');
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* The below function are Handles import and export operations based on the provided parameters.
|
||
*
|
||
* This function logs the call, retrieves necessary data, generates a filename,
|
||
* and then either exports data to an Excel file or imports data from an Excel file
|
||
* depending on the provided action type and event type.
|
||
*
|
||
* @return void Redirects the user to the appropriate page with flash messages indicating success or failure.
|
||
*/
|
||
|
||
public function importExport()
|
||
{
|
||
|
||
$array = $this->request->getPost('event_type');
|
||
|
||
if (is_array($array)) {
|
||
$event_type = 'MultipleEvents';
|
||
} else {
|
||
$event_type = $this->request->getPost('event_type');
|
||
}
|
||
|
||
$this->myLogger->logme('error', 'Import Export -- Function called');
|
||
$empDataServiceController = new EmpDataServiceController();
|
||
|
||
$client_id = $this->request->getPost('client_id');
|
||
$client_policy_id = $this->request->getPost('client_policy_id');
|
||
$client_branch_id = $this->request->getPost('client_branch_id');
|
||
$insurer_or_tpa = $this->request->getPost('insurer_or_tpa');
|
||
$actions = $this->request->getPost('action_type');
|
||
$policy_issue_date = $this->request->getPost('policy_issue_date') ?? null;
|
||
|
||
$client_data = $this->clientPolicyModel->getCliendDataForExcelFileName($client_policy_id);
|
||
$file_name = generate_filename($client_data['short_name'], $event_type, $actions, $insurer_or_tpa, $client_data['policy_type'], $client_data['branch_code']);
|
||
|
||
// dd($client_data, $file_name);
|
||
|
||
$batch_data = [
|
||
'client_id' => $client_id,
|
||
'client_policy_id' => $client_policy_id,
|
||
'client_branch_id' => $client_branch_id,
|
||
'insurer_or_tpa' => $insurer_or_tpa,
|
||
'event_type' => $event_type,
|
||
'actions' => $actions,
|
||
'file_name' => $file_name,
|
||
];
|
||
|
||
$batch_data['policy_issue_date'] = !empty($policy_issue_date) ? change_date_format($policy_issue_date, 'd/m/Y', 'Y-m-d') : null;
|
||
|
||
if ($actions == 'export') {
|
||
|
||
if ($event_type == 'inception' || $event_type == 'addition' || $event_type == 'dependent_addition' || $event_type == 'missed_inception' || ($event_type == 'MultipleEvents' && $insurer_or_tpa == 'tpa')) {
|
||
|
||
$return = $empDataServiceController->generateExcelForAdditionandInception($batch_data);
|
||
if ($return === 0) {
|
||
session()->setFlashdata('error', "Insufficient deposit amount.");
|
||
return redirect()->to(base_url('employee/upload'));
|
||
|
||
}else if($return === 5){
|
||
|
||
session()->setFlashdata('error', "The policy does not have a CD account number.");
|
||
return redirect()->to(base_url('employee/upload'));
|
||
}
|
||
else if($return === 6){
|
||
|
||
session()->setFlashdata('error', "The Insurer does not have an Excel export template format.");
|
||
return redirect()->to(base_url('employee/upload'));
|
||
}
|
||
|
||
if (!$return) {
|
||
|
||
if ($insurer_or_tpa == 'tpa') {
|
||
session()->setFlashdata('error', "No data was found for this action.");
|
||
return redirect()->to(base_url('employee/upload'));
|
||
} else if ($insurer_or_tpa == 'insurer') {
|
||
session()->setFlashdata('error', "No data was found for this action.");
|
||
return redirect()->to(base_url('employee/upload'));
|
||
}
|
||
} else {
|
||
$this->myLogger->logme('error', 'Successfully exported Excel file in {data}.', ['data' => $event_type]);
|
||
}
|
||
} else if ($event_type == 'correction') {
|
||
|
||
$return = $empDataServiceController->generateExcelForCorrection($batch_data);
|
||
|
||
if($return === 6){
|
||
session()->setFlashdata('error', "The Insurer does not have an Excel export template format.");
|
||
return redirect()->to(base_url('employee/upload'));
|
||
}
|
||
|
||
if (!$return) {
|
||
session()->setFlashdata('error', 'No data found about this action');
|
||
return redirect()->to(base_url('employee/upload'));
|
||
} else {
|
||
$this->myLogger->logme('error', 'Successfully exported Excel file in Correction.');
|
||
}
|
||
} else if ($event_type == 'si_enhancement') {
|
||
|
||
$return = $empDataServiceController->generateExcelForSIEnhancement($batch_data);
|
||
|
||
if ($return === 0) {
|
||
|
||
session()->setFlashdata('error', "Insufficient deposit amount.");
|
||
return redirect()->to(base_url('employee/upload'));
|
||
}else if($return === 5){
|
||
|
||
session()->setFlashdata('error', "The policy does not have a CD account number.");
|
||
return redirect()->to(base_url('employee/upload'));
|
||
}else if($return === 6){
|
||
|
||
session()->setFlashdata('error', "The Insurer does not have an Excel export template format.");
|
||
return redirect()->to(base_url('employee/upload'));
|
||
}
|
||
|
||
if (!$return) {
|
||
session()->setFlashdata('error', 'No data found about this action');
|
||
return redirect()->to(base_url('employee/upload'));
|
||
} else {
|
||
$this->myLogger->logme('error', 'Successfully exported Excel file in SI_Enhancement.');
|
||
}
|
||
} else if ($event_type == 'deletion') {
|
||
|
||
$return = $empDataServiceController->generateExcelForDeletion($batch_data);
|
||
|
||
if($return === 6){
|
||
|
||
session()->setFlashdata('error', "The Insurer does not have an Excel export template format.");
|
||
return redirect()->to(base_url('employee/upload'));
|
||
}
|
||
|
||
if (!$return) {
|
||
session()->setFlashdata('error', 'No data found about this action');
|
||
return redirect()->to(base_url('employee/upload'));
|
||
} else {
|
||
$this->myLogger->logme('error', 'Successfully exported Excel file in Deletion.');
|
||
}
|
||
} else if($event_type == 'MultipleEvents'){
|
||
|
||
$batch_data['event_type'] = $array;
|
||
$return = $empDataServiceController->generateExcelForAllEventType($batch_data);
|
||
|
||
if ($return === 0) {
|
||
session()->setFlashdata('error', "Insufficient deposit amount.");
|
||
return redirect()->to(base_url('employee/upload'));
|
||
|
||
}else if($return === 5){
|
||
|
||
session()->setFlashdata('error', "The policy does not have a CD account number.");
|
||
return redirect()->to(base_url('employee/upload'));
|
||
}
|
||
else if($return === 6){
|
||
|
||
session()->setFlashdata('error', "The Insurer does not have an Excel export template format.");
|
||
return redirect()->to(base_url('employee/upload'));
|
||
}
|
||
|
||
if (!$return) {
|
||
session()->setFlashdata('error', 'No data found about this action');
|
||
return redirect()->to(base_url('employee/upload'));
|
||
} else {
|
||
$this->myLogger->logme('error', 'Excel exported successfully.');
|
||
}
|
||
|
||
}
|
||
|
||
} else if ($actions == 'import') {
|
||
|
||
if($insurer_or_tpa == "tpa" && in_array($event_type, ['correction', 'deletion', 'si_enhancement'])){
|
||
session()->setFlashdata('error', "TPA upload is not applicable for this event.");
|
||
return redirect()->to(base_url('employee/upload'));
|
||
}
|
||
|
||
$batch_data['file'] = $this->request->getFile('import_file_data');
|
||
$file = $this->request->getFile('import_file_data');
|
||
|
||
$filename = storage_file_Upload($file, WRITEPATH . 'uploads/import_excel/', UPLOAD_EXT_EXCEL);
|
||
if ($filename === '') {
|
||
session()->setFlashdata('error', 'File upload failed');
|
||
return redirect()->to(base_url('employee/upload'));
|
||
}
|
||
$this->myLogger->logme('error', 'Inception Import file name : {data}', ['data' => $filename]);
|
||
|
||
$random_number_count = 4;
|
||
$batch_data['batch_code'] = generate_random_string($random_number_count);
|
||
$batch_data['created_by'] = get_session_userid();
|
||
$batch_data['status'] = 'pending';
|
||
$batch_data['file_name'] = $filename;
|
||
|
||
if ($event_type == 'inception' || $event_type == 'addition' || $event_type == 'dependent_addition' || $event_type == 'missed_inception') {
|
||
|
||
$file_id = $this->batchFileModel->insert($batch_data);
|
||
|
||
$job_details = new Jobs();
|
||
$r = Jobs::addJob(['job_name' => 'importInceptionFileValidation', 'payload' => ['file_id' => $file_id]]);
|
||
|
||
$return = 1;
|
||
|
||
// $return = $empDataServiceController->importInceptionFileValidation(['file_id' => $file_id]);
|
||
|
||
if ($return == 1) {
|
||
session()->setFlashdata('success', 'File Uploaded Successfully File is being validated.');
|
||
return redirect()->to(base_url('employee/upload'));
|
||
} else {
|
||
session()->setFlashdata($return['status'] ?? 'error', $return['message'] ?? 'Something went wrong! Try Later');
|
||
return redirect()->to(base_url('employee/upload'));
|
||
}
|
||
} else if ($event_type == 'correction') {
|
||
|
||
$file_id = $this->batchFileModel->insert($batch_data);
|
||
|
||
$job_details = new Jobs();
|
||
$r = Jobs::addJob(['job_name' => 'importCorrectionValidation', 'payload' => ['file_id' => $file_id]]);
|
||
|
||
$return = 1;
|
||
|
||
// $return = $empDataServiceController->importCorrectionValidation(['file_id' => $file_id]);
|
||
|
||
if ($return == 1) {
|
||
session()->setFlashdata('success', 'File Uploaded Successfully File is being validated.');
|
||
return redirect()->to(base_url('employee/upload'));
|
||
} else {
|
||
session()->setFlashdata('error', $return);
|
||
return redirect()->to(base_url('employee/upload'));
|
||
}
|
||
|
||
} else if ($event_type == 'si_enhancement') {
|
||
|
||
|
||
$file_id = $this->batchFileModel->insert($batch_data);
|
||
|
||
$job_details = new Jobs();
|
||
$r = Jobs::addJob(['job_name' => 'importSIEnhancementValidation', 'payload' => ['file_id' => $file_id]]);
|
||
|
||
$return = 1;
|
||
|
||
// $return = $empDataServiceController->importSIEnhancementValidation(['file_id' => $file_id]);
|
||
|
||
if ($return == 1) {
|
||
session()->setFlashdata('success', 'File Uploaded Successfully File is being validated.');
|
||
return redirect()->to(base_url('employee/upload'));
|
||
} else {
|
||
session()->setFlashdata('error', $return);
|
||
return redirect()->to(base_url('employee/upload'));
|
||
}
|
||
} else if ($event_type == 'deletion') {
|
||
|
||
$file_id = $this->batchFileModel->insert($batch_data);
|
||
|
||
$job_details = new Jobs();
|
||
$r = Jobs::addJob(['job_name' => 'importDeletionValidation', 'payload' => ['file_id' => $file_id]]);
|
||
|
||
$return = 1;
|
||
|
||
// $return = $empDataServiceController->importDeletionValidation(['file_id' => $file_id]);
|
||
|
||
|
||
if ($return == 1) {
|
||
session()->setFlashdata('success', 'File Uploaded Successfully File is being validated.');
|
||
return redirect()->to(base_url('employee/upload'));
|
||
} else {
|
||
session()->setFlashdata('error', $return);
|
||
return redirect()->to(base_url('employee/upload'));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// -------------------------------------------------------------------------------------------
|
||
|
||
|
||
/**
|
||
* Below function displays the endorsement list page.
|
||
*
|
||
* This method retrieves filter data from the request and fetches the endorsement list
|
||
* based on the provided filters such as client ID, policy ID, and status.
|
||
*/
|
||
|
||
public function endorsementList()
|
||
{
|
||
|
||
$data = [];
|
||
|
||
$data['status'] = ['pending' => 'Pending', 'inprogress' => 'In-Progress', 'complete' => 'Complete'];
|
||
if (count($this->request->getGet())) {
|
||
$filterData = $this->request->getGet();
|
||
$data['employees'] = $this->employeePolicyModel->getEmployeeEndorsementList(
|
||
client_id: $filterData['client_id'],
|
||
policy_id: $filterData['policy_id'],
|
||
status: $filterData['status'],
|
||
branch_id: $filterData['branch_id']
|
||
);
|
||
$data['getData'] = $filterData;
|
||
// echo "<pre>";
|
||
|
||
}
|
||
|
||
$this->myLogger->logme('error', 'list called');
|
||
|
||
$data['tab_name'] = "Endorsements";
|
||
$data['page_name'] = "Endorsements";
|
||
|
||
$this->loadLayout('endorsement_list', $data);
|
||
}
|
||
|
||
|
||
/**
|
||
* Below function displays the Enrollment list page.
|
||
*
|
||
* This method retrieves filter data from the request and fetches the Enrollment list
|
||
* based on the provided filters such as client , client_branch , employee - ( Log-in-or-not , ENrolled-or-not).
|
||
*/
|
||
|
||
public function enrollmentClientList()
|
||
{
|
||
$role_id = get_role_id();
|
||
$user_id = get_session_userid();
|
||
|
||
$data = [];
|
||
$client_list = $this->clientModel->join("client_rm","client_rm.client_id = clients.id",'left')->where('clients.is_active', 1);
|
||
if (in_array($role_id, [2, 3])) {
|
||
|
||
// If the user is a Account Manager or Manager, filter by user_id
|
||
$client_list->where('client_rm.user_id', $user_id);
|
||
}
|
||
|
||
$client_list = $client_list->groupBy("clients.id")->findAll();
|
||
$branch_list = $this->clientBranchModel->where('client_branch.is_active', 1)->findAll();
|
||
$policy_list = $this->clientPolicyModel
|
||
->select('client_policy.*, policy_type.policy_type')
|
||
->join('policy_type', 'client_policy.policy_type_id = policy_type.id')
|
||
->where('client_policy.is_active', 1)
|
||
->findAll();
|
||
|
||
$data['client_list'] = $client_list;
|
||
$data['branch_list'] = $branch_list;
|
||
$data['policy_list'] = $policy_list;
|
||
|
||
// Get session data if available
|
||
$data['selected_client_id'] = session()->get('client_id');
|
||
$data['selected_branch_id'] = session()->get('branch_id');
|
||
$data['selected_type'] = session()->get('type');
|
||
|
||
// dd($data);
|
||
|
||
$this->myLogger->logme('error', 'list called');
|
||
|
||
$data['page_name'] = "Enrollment";
|
||
|
||
return $this->loadLayout('enrollment_list', $data);
|
||
|
||
}
|
||
|
||
public function empby_client_clientbranch($client_id, $branch_id)
|
||
{
|
||
|
||
$results = $this->clientModel->select('employees.id as employee_id, employees.name as employee_name,
|
||
employees.relationship, employees.emp_code,
|
||
employees.emp_status, auth_history.user_type')
|
||
->join('employees', $client_id .'= employees.client_id AND ' . $branch_id . '= employees.client_branch_id', 'left')
|
||
->join('auth_history', 'employees.id = auth_history.user_id AND "employee" = auth_history.user_type', 'left')
|
||
->where('employees.is_active', 1)
|
||
->where('employees.emp_status !=', 'truncated')
|
||
->groupBy('employees.id')
|
||
->findAll();
|
||
|
||
$groupedData = [];
|
||
$employeeId = '';
|
||
|
||
foreach ($results as $row) {
|
||
|
||
if($employeeId != $row['employee_id']){
|
||
$employeeId = $row['employee_id'];
|
||
}else{
|
||
$employeeId = null;
|
||
}
|
||
$employeeName = $row['employee_name'] ;
|
||
$employeeRelationship = $row['relationship'] ;
|
||
$employeeEmpCode = $row['emp_code'] ;
|
||
$employeeEmpStatus = $row['emp_status'];
|
||
$employeeUserType = $row['user_type'];
|
||
|
||
|
||
// if ($employeeId !== null && $employeeRelationship == 'Self') {
|
||
if ($employeeId !== null) {
|
||
// Append employee info to the branch's employees list
|
||
$groupedData[] = [
|
||
'employee_id' => $employeeId,
|
||
'employee_name' => $employeeName,
|
||
'relationship' => $employeeRelationship,
|
||
'emp_code' => $employeeEmpCode,
|
||
'emp_status' => $employeeEmpStatus,
|
||
'user_type' => $employeeUserType
|
||
];
|
||
|
||
}
|
||
$employeeId = $row['employee_id'];
|
||
}
|
||
|
||
|
||
return json_encode($groupedData);
|
||
}
|
||
|
||
|
||
|
||
|
||
/**
|
||
* Beleo function retrieves employee endorsement (emp_endorsement table) data.
|
||
*
|
||
* This method fetches endorsement data based on the provided ID.
|
||
* It determines the type of endorsement action (SI enhancement, deletion, or other),
|
||
* formats the data accordingly, and returns it as a response.
|
||
*
|
||
* @param int|null $id The ID of the endorsement entry to retrieve.
|
||
* @return \CodeIgniter\HTTP\Response Returns a JSON response containing the endorsement entry data.
|
||
*/
|
||
public function getEmpEndoresmentEntry($id = null)
|
||
{
|
||
// Create instance of EmpDataServiceController
|
||
$empDataServiceController = new EmpDataServiceController();
|
||
|
||
// Check if $id is provided
|
||
if ($id) {
|
||
// Retrieve group key and actions based on $id
|
||
$group_key_actions = $this->empEndorsementModel->select('group_key, actions')->where('id', $id)->first();
|
||
$groupedData = $this->empEndorsementModel->where('group_key', $group_key_actions['group_key'])->findAll();
|
||
|
||
// If group key and actions are found
|
||
if ($group_key_actions) {
|
||
// Retrieve endorsement data based on actions
|
||
switch ($group_key_actions['actions']) {
|
||
case 'si':
|
||
$data = $this->empEndorsementModel->getDataForEnodrsementListinSIEnhancement($group_key_actions['group_key']);
|
||
$formatedData = $empDataServiceController->convertRowTColumnForSIEnhancement($data);
|
||
break;
|
||
case 'd':
|
||
$data = $this->empEndorsementModel->getDataForEnodrsementListinDeletion($group_key_actions['group_key']);
|
||
$formatedData = $empDataServiceController->convertRowTColumnForDeletion($data);
|
||
break;
|
||
default:
|
||
$formatedData = $groupedData;
|
||
$formatedData[0]['field_name'] = remove_underscore_capitalize_first_letter($formatedData[0]['field_name']);
|
||
$formatedData[0]['old_value'] = formatDateOrReturn($formatedData[0]['old_value']);
|
||
$formatedData[0]['new_value'] = formatDateOrReturn($formatedData[0]['new_value']);
|
||
break;
|
||
}
|
||
|
||
// Return response with data
|
||
return $this->respond([
|
||
'dataStatus' => true,
|
||
'code' => 200,
|
||
'data' => $formatedData,
|
||
'data2' => $groupedData
|
||
], 200);
|
||
} else {
|
||
// Return response if group key and actions are not found
|
||
return $this->respond(['dataStatus' => false, 'code' => 404, 'message' => 'no data found'], 200);
|
||
}
|
||
} else {
|
||
// Return response if $id is not provided
|
||
return $this->respond(['dataStatus' => false, 'code' => 404, 'message' => 'no data found'], 200);
|
||
}
|
||
}
|
||
|
||
|
||
// @param int $client_policy_id
|
||
// this funciton initiate Inception/adition/DA of employees data only form enrollment app when passing
|
||
// client_policy_id pull draft and enrolled status employees and proceed to calculatin and make entry in DB
|
||
public function initiateManualEmployeesOnboardProcess($client_policy_id)
|
||
{
|
||
$client_data = $this->clientPolicyModel->select('clients.client_name as client_name,client_branch_id')
|
||
->join('clients', 'clients.id = client_policy.client_id')
|
||
// ->join('policies', 'policies.id = client_policy.policy_id')
|
||
->where('client_policy.id', $client_policy_id)
|
||
->first();
|
||
// dd($client_data);
|
||
$empServiceController = new EmployeeServiceController();
|
||
$res = $empServiceController->employeesOnboardPreprocess(['client_policy_id' => $client_policy_id,'client_branch_id' => $client_data['client_branch_id']]);
|
||
// dd($res);
|
||
|
||
$count = ($res);
|
||
$message = $count . ' Employees are Initiate Onboard Process againts Client ' . $client_data['client_name'] . ' and the Policy is ' .$client_policy_id;
|
||
session()->setFlashdata('success1', $message);
|
||
return redirect()->to(base_url('/employee/upload'));
|
||
}
|
||
|
||
public function downloadFileList($file_id = null)
|
||
{
|
||
$file_data = $this->fileModel->where('id', $file_id)->first();
|
||
if (empty($file_data) || empty($file_data['file_name'])) {
|
||
$data['message'] = 'File record not found';
|
||
return view('errors/404', $data);
|
||
}
|
||
|
||
$fileName = basename((string) $file_data['file_name']);
|
||
$storage = \Config\Services::getFileStorageService();
|
||
$result = $storage->download(WRITEPATH . 'uploads/excel', $fileName);
|
||
|
||
try {
|
||
if ($result['success'] ?? false) {
|
||
$downloadAs = storage_upload_display_name($fileName);
|
||
if (! empty($result['path']) && is_file($result['path'])) {
|
||
return $this->response->download($result['path'], null)->setFileName($downloadAs);
|
||
}
|
||
if (! empty($result['content'])) {
|
||
return $this->response->download($downloadAs, $result['content'])->setFileName($downloadAs);
|
||
}
|
||
}
|
||
|
||
$data['message'] = 'The Physical File Not Found';
|
||
return view('errors/404', $data);
|
||
} catch (\Exception $e) {
|
||
$this->myLogger->logme('error', $e->getMessage());
|
||
echo $e->getMessage();
|
||
}
|
||
}
|
||
|
||
public function featchEmpList()
|
||
{
|
||
$client_id = $this->request->getGet('client_id');
|
||
$policy_id = $this->request->getGet('policy_id');
|
||
|
||
$emp_data['employees'] = $this->employeePolicyModel->getEmployeePolicyForFileList($client_id, $policy_id);
|
||
$html = view('employee_data_list', $emp_data);
|
||
|
||
return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => $html], 200);
|
||
}
|
||
|
||
public function viewUploadedEmployeeList()
|
||
{
|
||
|
||
$empDataServiceController = new EmpDataServiceController();
|
||
|
||
$file_id = $this->request->getGet('file_id');
|
||
// $emp_data['employees'] = $this->employeePolicyModel->getViewEmpSuccessList($file_id);
|
||
// $html = view('view_file_upload_emp_list', $emp_data);
|
||
$file_name = $this->fileModel
|
||
->select(['files.*', 'up.emp_code', 'up.first_name', 'pm.name as policy_name', 'c.short_name', 'cp.id as client_policy_id'])
|
||
->join('user_profiles up', 'files.created_by = up.id')
|
||
->join('client_policy cp', 'files.policy_id = cp.id', 'left')
|
||
->join('policies pm', 'cp.policy_id = pm.id', 'left')
|
||
->join('clients c', 'files.client_id = c.id and files.client_id = cp.client_id', 'left')
|
||
->where('files.id', $file_id)->first();
|
||
|
||
// dd($file_name);
|
||
|
||
try {
|
||
|
||
if (!$file_name) {
|
||
return $this->respond([
|
||
'dataStatus' => false,
|
||
'code' => 200,
|
||
'data' => '<div class="text-center">No Data Found</div>',
|
||
'file_data' => null
|
||
], 200);
|
||
}
|
||
|
||
$filePath = storage_ensure_local_file(WRITEPATH . 'uploads/excel', $file_name['file_name']);
|
||
|
||
// ✅ File not exists on disk
|
||
if (empty($filePath) || !file_exists($filePath)) {
|
||
return $this->respond([
|
||
'dataStatus' => false,
|
||
'code' => 200,
|
||
'data' => '<div class="text-center">No Data Found</div>',
|
||
'file_data' => $file_name
|
||
], 200);
|
||
}
|
||
|
||
|
||
$excel_data = $empDataServiceController->readExcelFileToArray($filePath);
|
||
|
||
// ✅ Excel empty or header only
|
||
if (empty($excel_data) || count($excel_data) <= 1) {
|
||
return $this->respond([
|
||
'dataStatus' => false,
|
||
'code' => 200,
|
||
'data' => '<div class="text-center">No Data Found</div>',
|
||
'file_data' => $file_name
|
||
], 200);
|
||
}
|
||
|
||
if (file_exists($filePath)) {
|
||
|
||
$excel_data = $empDataServiceController->readExcelFileToArray($filePath);
|
||
$emp_data['thead'] = $excel_data[0];
|
||
unset($excel_data[0]);
|
||
$emp_data['tbody'] = $excel_data;
|
||
$emp_data['count'] = count($excel_data);
|
||
|
||
// dd($emp_data);
|
||
|
||
$html = view('view_file_upload_emp_list', $emp_data);
|
||
} else {
|
||
|
||
$html = '<div class="text-center">No Data Found</div>';
|
||
}
|
||
|
||
return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => $html, 'file_data' => $file_name, 'excel_data' => $excel_data], 200);
|
||
} catch (\Throwable $th) {
|
||
|
||
$errorData = [
|
||
'message' => $th->getMessage(),
|
||
'file' => $th->getFile(),
|
||
'line' => $th->getLine(),
|
||
'code' => $th->getCode(),
|
||
'trace' => $th->getTraceAsString(),
|
||
'trace_array' => $th->getTrace(), // full array version (optional)
|
||
'function' => $th->getTrace()[0]['function'] ?? null,
|
||
'class' => $th->getTrace()[0]['class'] ?? null,
|
||
];
|
||
|
||
// Handle exception
|
||
$errorMessage = 'Error occurred:' . PHP_EOL . json_encode($errorData, JSON_PRETTY_PRINT);
|
||
$this->myLogger->logme('error', $errorMessage);
|
||
|
||
return $this->respond(['dataStatus' => false, 'code' => 500, 'data' => '<div class="text-center">Something went wrong</div>', 'file_data' => $file_name ?? null], 500);
|
||
}
|
||
}
|
||
|
||
public function getEmpCount($id = null)
|
||
{
|
||
|
||
$data = $this->employeePolicyModel->select('employee_polices.id')
|
||
->where('employee_polices.is_active', 1)
|
||
->where('employee_polices.status', 'active')
|
||
->where('employee_polices.client_policy_id', $id)
|
||
->findAll();
|
||
|
||
$emp_count = count($data);
|
||
$events = ['inception' => 'Inception (Employee + Dependents)', 'addition' => 'Addition (Employee + Dependents)', 'dependent_addition' => 'Dependent Addition (Only Dependents)', 'deletion' => 'Deletion', 'correction' => 'Correction', 'si_enhancement' => 'SI Enhancement'];
|
||
return $this->respond(['dataStatus' => true, 'code' => 200, 'emp_count' => $emp_count, 'events' => $events, 'client_policy_id' => $id], 200);
|
||
|
||
}
|
||
|
||
public function downloadFullExcelErrorFile($file_id, $rowIndex = 1, $colIndex = 1)
|
||
{
|
||
// Get file data from the database
|
||
$file_data = $this->fileModel->find((int)$file_id);
|
||
|
||
$error = json_decode($file_data['reason']);
|
||
// echo '<pre>';
|
||
// print_r($error); die;
|
||
// dd($error);
|
||
|
||
// Check if the file exists
|
||
if (!$file_data) {
|
||
$error_message = "File not found";
|
||
$this->myLogger->logme('error', $error_message . ' for file id ' . $file_id);
|
||
return $error_message;
|
||
}
|
||
|
||
$fileName = $file_data['file_name'];
|
||
$filePath = storage_ensure_local_file(WRITEPATH . 'uploads/excel', $fileName);
|
||
|
||
// Check if the file exists
|
||
if (empty($filePath) || !file_exists($filePath)) {
|
||
$error_message = "File not found";
|
||
$this->myLogger->logme('error', $error_message . ' for file id ' . $file_id);
|
||
$data['message'] = 'Physical File Not Found';
|
||
return view('errors/404', $data);
|
||
}
|
||
|
||
// Load the Excel file
|
||
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($filePath);
|
||
$sheet = $spreadsheet->getActiveSheet();
|
||
|
||
// echo '<pre>';
|
||
|
||
foreach ($error->error_data as $index => $error_data) {
|
||
|
||
$rowIndex = $index + 1;
|
||
|
||
if ($error->error_type == 1) {
|
||
|
||
foreach ($error_data as $key => $value) {
|
||
|
||
$colIndex = $value->col_idx + 1;
|
||
|
||
$originalValue = $sheet->getCell([$colIndex, $rowIndex])->getValue();
|
||
|
||
$newValue = implode(', ', $value->error);
|
||
$val = $originalValue . ' ( ' . $newValue . ' )';
|
||
$sheet->setCellValue([$colIndex, $rowIndex], $val);
|
||
|
||
$style = [
|
||
'fill' => [
|
||
'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
|
||
'startColor' => ['rgb' => 'ffad99'] // Red color
|
||
]
|
||
];
|
||
|
||
$sheet->getStyle([$colIndex, $rowIndex])->applyFromArray($style);
|
||
}
|
||
} else if ($error->error_type == 2) {
|
||
|
||
|
||
foreach ($error_data as $key => $value) {
|
||
|
||
|
||
$originalValue = $sheet->getCell([1, $rowIndex])->getValue();
|
||
|
||
$newValue = implode(', ', $value->error);
|
||
$val = $originalValue . ' ( ' . $newValue . ' )';
|
||
$sheet->setCellValue([$colIndex, $rowIndex], $val);
|
||
|
||
$style = [
|
||
'fill' => [
|
||
'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
|
||
'startColor' => ['rgb' => 'ffad99'] // Red color
|
||
]
|
||
];
|
||
$sheet->getStyle([$colIndex, $rowIndex])->applyFromArray($style);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
// Create a new filename for the modified Excel file
|
||
$newFileName = 'error_with_highlight_' . $fileName;
|
||
|
||
// Save the modified Excel file to a new location
|
||
$newFilePath = WRITEPATH . '/uploads/excel/' . $newFileName;
|
||
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
|
||
$writer->save($newFilePath);
|
||
|
||
// Set headers to force download
|
||
$response = service('response');
|
||
$response->setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||
$response->setHeader('Content-Disposition', 'attachment;filename="' . $newFileName . '"');
|
||
$response->setHeader('Cache-Control', 'max-age=0');
|
||
$response->setHeader('Content-Length', filesize($newFilePath));
|
||
$response->setBody(file_get_contents($newFilePath));
|
||
|
||
// Delete the temporary file
|
||
unlink($newFilePath);
|
||
|
||
// Return the response
|
||
return $response;
|
||
}
|
||
|
||
// --------------- For E-Card Download -----------------------------------------------------------------------------------------------------
|
||
|
||
//E-CARD DOWNLOAD FUNCTION USING HTML PRINT ( Not in use ) do not delete
|
||
public function generateIDCardForEmployeeUsingHtml($rand_string, $people = 0)
|
||
{
|
||
// dd($rand_string, $people);
|
||
try {
|
||
$this->myLogger->logme('error', 'generateIDCardForEmployee function started.');
|
||
|
||
// Step 1: Attempt to fetch employee code and client policy ID
|
||
$this->myLogger->logme('error', 'Fetching employee code and client policy ID.');
|
||
|
||
$get_emp_code_and_client_policy_id = $this->employeePolicyModel
|
||
->select('employee_polices.client_policy_id, employees.emp_code, tpa.short_name,employees.client_id')
|
||
->join('client_policy', 'client_policy.id = employee_polices.client_policy_id')
|
||
->join('employees', 'employees.id = employee_polices.employee_id')
|
||
->join('tpa', 'tpa.id = client_policy.tpa_id')
|
||
->where('employees.emp_status', 'active')
|
||
->where('employees.is_active', '1')
|
||
->where("employee_polices.tpa_id IS NOT NULL AND employee_polices.tpa_id <> ''")
|
||
->where('employee_polices.status', 'active')
|
||
->where('employee_polices.is_active', '1')
|
||
->where('employee_polices.rand_string', $rand_string)
|
||
->first();
|
||
|
||
// dd($this->employeePolicyModel->getLastQuery());
|
||
|
||
// dd($rand_string, $get_emp_code_and_client_policy_id);
|
||
|
||
if ($get_emp_code_and_client_policy_id == null || $get_emp_code_and_client_policy_id == "") {
|
||
$this->myLogger->logme('error', 'Member not found in this rand_string: ' . $rand_string);
|
||
$data['message'] = 'Record Not Found';
|
||
return view('errors/404', $data);
|
||
}
|
||
|
||
$this->myLogger->logme('error', 'Member found. Client policy ID: ' . $get_emp_code_and_client_policy_id['client_policy_id']);
|
||
|
||
$client_policy_id = $get_emp_code_and_client_policy_id['client_policy_id'];
|
||
$emp_code = $get_emp_code_and_client_policy_id['emp_code'];
|
||
$client_id = $get_emp_code_and_client_policy_id['client_id'];
|
||
|
||
// Step 2: Fetch ECard data
|
||
$this->myLogger->logme('error', 'Fetching ECard data using client_policy_id: ' . $client_policy_id . ' and emp_code: ' . $emp_code);
|
||
$data = $this->employeePolicyModel->getECardDataUsingMd5($client_policy_id, $emp_code,$client_id);
|
||
|
||
if ($people == 0) {
|
||
$this->myLogger->logme('error', 'Fetching single ECard data using rand_string: ' . $rand_string . ' and emp_code: ' . $emp_code);
|
||
$data = $this->employeePolicyModel->getECardSingleData($rand_string, $emp_code,$client_id);
|
||
}
|
||
|
||
// Step 3: Prepare template path
|
||
$template_data_path = WRITEPATH . 'e_card_template/';
|
||
// $tpa_short_name = strtolower(str_replace(' ', '_', $get_emp_code_and_client_policy_id['short_name'])) . '.html';
|
||
$tpa_short_name = 'common.html';
|
||
$final_path = $template_data_path . $tpa_short_name;
|
||
|
||
$this->myLogger->logme('error', 'Checking if template file exists at: ' . $final_path);
|
||
|
||
if (!file_exists($final_path)) {
|
||
$this->myLogger->logme('error', 'Template file not found: ' . $final_path);
|
||
$data['message'] = 'Template File Not Found';
|
||
return view('errors/404', $data);
|
||
}
|
||
|
||
$this->myLogger->logme('error', 'Template file found. Reading template data.');
|
||
$tmplt_data = file_get_contents($final_path);
|
||
|
||
// Step 4: Generate HTML content
|
||
$this->myLogger->logme('error', 'Generating HTML content from template.');
|
||
$html = "";
|
||
foreach ($data as $key => $value) {
|
||
$htmlContent = $tmplt_data;
|
||
|
||
$value['front_card'] = "Nhance_Ecard_working_1_front.png";
|
||
$value['back_card'] = "Nhance_Ecard_working_1_Back.png";
|
||
|
||
$placeholders = [
|
||
'{CLIENT_NAME}' => $value['client_name'],
|
||
'{TPA_ID}' => $value['tpa_id'],
|
||
'{NAME}' => $value['name'],
|
||
'{UHID}' => $value['uhid'],
|
||
'{GENDER}' => $value['gender'],
|
||
'{DOB}' => date('d-M-Y', strtotime($value['dob'])),
|
||
'{SELF_NAME}' => $value['self'] ?? $value['name'],
|
||
'{POLICY_DATE}' => date('d-M-Y', strtotime($value['policy_end_date'])),
|
||
'{POLICY_START_DATE}' => date('d-M-Y', strtotime($value['policy_start_date'])),
|
||
'{POLICY_NO}' => $value['policy_no'],
|
||
'{INSURER_NAME}' => strtoupper($value['insurer_name']),
|
||
'{INSURER_LOGO}' => base_url() . 'public/uploads/logo/' . $value['insurer_logo'],
|
||
'{FRONT_CARD}' => base_url() . 'public/uploads/template_bg/' . $value['front_card'],
|
||
'{BACK_CARD}' => base_url() . 'public/uploads/template_bg/' . $value['back_card'],
|
||
'{EMP_ID}' => $value['emp_code'],
|
||
'{SI_AMT}' => $value['basic_cover_si'],
|
||
'{CORPORATE_NAME}' => $value['client_name'],
|
||
'{AGE}' => $value['emp_age'],
|
||
'{TPA_NAME}' => $value['tpa_name'],
|
||
'{INSURER_BRANCH}' => $value['insurer_branch_city'],
|
||
'{RELATION}' => $value['relationship'],
|
||
'{TPA_LOGO}' => base_url() . 'public/uploads/logo/' . $value['tpa_logo'],
|
||
'{MEDI_USER}' => base_url() . 'public/e_card_imgs/medi_uesr.jpg',
|
||
'{MEDI_INSURER}' => base_url() . 'public/e_card_imgs/Magma.png',
|
||
'{MEDI_BARCODE}' => base_url() . 'public/e_card_imgs/borcode.jpeg',
|
||
'{QR_ANDROID}' => base_url() . 'public/e_card_imgs/android.png',
|
||
'{QR_IOS}' => base_url() . 'public/e_card_imgs/ios.png',
|
||
'{QR_ANDROID_2}' => base_url() . 'public/e_card_imgs/play_store.png',
|
||
'{QR_IOS_2}' => base_url() . 'public/e_card_imgs/appstore.png',
|
||
];
|
||
|
||
$placeholders['{LEVELS}'] = $this->generateAcmAndMForEcard($client_id);
|
||
|
||
foreach ($placeholders as $placeholder => $replaceValue) {
|
||
$htmlContent = str_replace($placeholder, $replaceValue, $htmlContent);
|
||
}
|
||
|
||
$html .= $htmlContent;
|
||
}
|
||
|
||
// Step 5: Output HTML and script for printing
|
||
$this->myLogger->logme('error', 'Generating HTML output with print button.');
|
||
echo '<button id="downloadBtn" style="display: block;margin: 30px;position: relative;left: 220px;">Print</button>' . $html . '</button>
|
||
<script>
|
||
document.getElementById("downloadBtn").addEventListener("click", function() {
|
||
this.style.display = "none";
|
||
window.print();
|
||
this.style.display = "block";
|
||
});
|
||
</script>';
|
||
|
||
$this->myLogger->logme('error', 'generateIDCardForEmployee function completed successfully.');
|
||
|
||
} catch (\Exception $e) {
|
||
$this->myLogger->logme('error', 'Exception occurred: ' . $e->getMessage());
|
||
$data['message'] = 'Record Not Found';
|
||
return view('errors/404', $data);
|
||
}
|
||
|
||
}
|
||
|
||
// Preview E-Card Template function
|
||
public function previewTemplate($id = null)
|
||
{
|
||
$value = [
|
||
'tpa_id' => 'TPA12345',
|
||
'name' => 'John Doe',
|
||
'uhid' => 'UHID67890',
|
||
'gender' => 'Male',
|
||
'dob' => '1985-05-15',
|
||
'self' => 'John Doe',
|
||
'policy_end_date' => '2024-12-31',
|
||
'policy_start_date' => '2023-01-01',
|
||
'policy_no' => 'POL1234567890',
|
||
'insurer_name' => 'Example Insurance Company',
|
||
'emp_code' => 'EMP001122',
|
||
'client_name' => 'Corporate Client Inc.',
|
||
'emp_age' => 39,
|
||
'tpa_name' => 'Example TPA',
|
||
'insurer_branch_city' => 'New York',
|
||
'relationship' => 'Self',
|
||
'basic_cover_si' => '5,00,000',
|
||
];
|
||
|
||
$tpa_id = $this->TPAModel->where('id', $id)->first();
|
||
|
||
$template_data_path = WRITEPATH . 'e_card_template/';
|
||
$tpa_short_name = strtolower(str_replace(' ', '_', $tpa_id['short_name'])) . '.html';
|
||
$final_path = $template_data_path . $tpa_short_name;
|
||
|
||
if (!file_exists($final_path)) {
|
||
|
||
$data['message'] = 'Record Not Found';
|
||
return view('errors/404', $data);
|
||
}
|
||
|
||
$tmplt_data = file_get_contents($final_path);
|
||
|
||
$placeholders = [
|
||
'{TPA_ID}' => $value['tpa_id'],
|
||
'{NAME}' => $value['name'],
|
||
'{UHID}' => $value['uhid'],
|
||
'{GENDER}' => $value['gender'],
|
||
'{DOB}' => date('d-M-Y', strtotime($value['dob'])),
|
||
'{SELF_NAME}' => $value['self'] ?? $value['name'],
|
||
'{POLICY_DATE}' => date('d-M-Y', strtotime($value['policy_end_date'])),
|
||
'{POLICY_START_DATE}' => date('d-M-Y', strtotime($value['policy_start_date'])),
|
||
'{POLICY_NO}' => $value['policy_no'],
|
||
'{INSURER_NAME}' => strtoupper($value['insurer_name']),
|
||
'{EMP_ID}' => $value['emp_code'],
|
||
'{SI_AMT}' => $value['basic_cover_si'],
|
||
'{CORPORATE_NAME}' => $value['client_name'],
|
||
'{AGE}' => $value['emp_age'],
|
||
'{TPA_NAME}' => $value['tpa_name'],
|
||
'{INSURER_BRANCH}' => $value['insurer_branch_city'],
|
||
'{RELATION}' => $value['relationship'],
|
||
'{FRONT_CARD}' => base_url() . 'public/uploads/template_bg/' . $tpa_id['front_card'],
|
||
'{BACK_CARD}' => base_url() . 'public/uploads/template_bg/' . $tpa_id['back_card'],
|
||
'{TPA_LOGO}' => base_url() . 'public/uploads/logo/' . $tpa_id['tpa_logo'],
|
||
'{INSURER_LOGO}' => base_url() . 'public/assets/images/sample_logo_3.png',
|
||
'{MEDI_USER}' => base_url() . 'public/e_card_imgs/medi_uesr.jpg',
|
||
'{MEDI_INSURER}' => base_url() . 'public/e_card_imgs/Magma.png',
|
||
'{MEDI_BARCODE}' => base_url() . 'public/e_card_imgs/borcode.jpeg',
|
||
'{QR_ANDROID}' => base_url() . 'public/e_card_imgs/android.png',
|
||
'{QR_IOS}' => base_url() . 'public/e_card_imgs/ios.png',
|
||
'{QR_ANDROID_2}' => base_url() . 'public/e_card_imgs/play_store.png',
|
||
'{QR_IOS_2}' => base_url() . 'public/e_card_imgs/appstore.png',
|
||
|
||
];
|
||
|
||
$placeholders['{LEVELS}'] = '
|
||
<span style="font-family: sans-serif;">Level 1</span><br><br>
|
||
<span style="font-family: sans-serif;">1. Gowtham / 8754081806 / gowtham@gmail.com</span><br>
|
||
<span style="font-family: sans-serif;">2. Gowtham / 8754081806 / gowtham@gmail.com</span><br><br>';
|
||
|
||
// dd($placeholders);
|
||
|
||
// Get the values to replace the placeholders
|
||
$replaceValues = array_values($placeholders);
|
||
|
||
// Get the placeholders to search for
|
||
$searchPlaceholders = array_keys($placeholders);
|
||
|
||
// Replace placeholders with values in HTML content
|
||
$htmlContent = str_replace($searchPlaceholders, $replaceValues, $tmplt_data);
|
||
|
||
|
||
echo $htmlContent;
|
||
}
|
||
|
||
//E-CARD DOWNLOAD FUNCTION USING DOM PDF ( CURRENTLY USING THIS ) Dompdf
|
||
public function generateIDCardForEmployee($rand_string, $people = 0, $mode = 0)
|
||
{
|
||
$mode = (int)$mode;
|
||
|
||
|
||
// dd($rand_string, $people,$mode);
|
||
$this->myLogger->logme('error', 'generateIDCardForEmployee params .' . json_encode(["rand_string" => $rand_string, "people" => $people, "mode" => $mode]));
|
||
try {
|
||
$this->myLogger->logme('error', 'generateIDCardForEmployee function started.');
|
||
|
||
// Step 1: Attempt to fetch employee code and client policy ID
|
||
$this->myLogger->logme('error', 'Fetching employee code and client policy ID.');
|
||
|
||
$get_emp_code_and_client_policy_id = $this->employeePolicyModel
|
||
->select('employee_polices.client_policy_id, employees.emp_code,employees.name, employee_polices.tpa_id,tpa.short_name,employees.client_id')
|
||
->join('client_policy', 'client_policy.id = employee_polices.client_policy_id')
|
||
->join('employees', 'employees.id = employee_polices.employee_id')
|
||
->join('tpa', 'tpa.id = client_policy.tpa_id')
|
||
->where('employees.is_active', '1')
|
||
->where("employee_polices.tpa_id IS NOT NULL AND employee_polices.tpa_id <> ''")
|
||
->whereIn('employee_polices.status', ['active', 'expired'])
|
||
->whereIn('employees.emp_status', ['active', 'expired'])
|
||
->where('employee_polices.is_active', '1')
|
||
->where('employee_polices.rand_string', $rand_string)
|
||
->first();
|
||
|
||
// dd($this->employeePolicyModel->getLastQuery());
|
||
|
||
// dd($rand_string, $get_emp_code_and_client_policy_id);
|
||
|
||
if ($get_emp_code_and_client_policy_id == null || $get_emp_code_and_client_policy_id == "") {
|
||
$this->myLogger->logme('error', 'Member not found in this rand_string: ' . $rand_string);
|
||
$data['message'] = 'Record Not Found';
|
||
return view('errors/404', $data);
|
||
}
|
||
|
||
$this->myLogger->logme('error', 'Member found. Client policy ID: ' . $get_emp_code_and_client_policy_id['client_policy_id']);
|
||
|
||
$client_policy_id = $get_emp_code_and_client_policy_id['client_policy_id'];
|
||
$emp_code = $get_emp_code_and_client_policy_id['emp_code'];
|
||
$client_id = $get_emp_code_and_client_policy_id['client_id'];
|
||
|
||
//new step check in S3 if yes then fetch from S3 bucket
|
||
$s3_key = 'ecard_'.$get_emp_code_and_client_policy_id['name'].'('.$get_emp_code_and_client_policy_id['emp_code'].')'.'_'.$get_emp_code_and_client_policy_id['tpa_id'].'.pdf';
|
||
$s3_key = $this->sanitizeFilePart($s3_key);
|
||
// echo $s3_key;die();
|
||
$s3 = \Config\Services::getS3Service();
|
||
if($s3->exists($s3_key) && $mode != 2) //2 => for bulk generate so skip s3 check and generate PDF
|
||
{
|
||
//get pre signed url & make it download
|
||
$s3_url = $s3->getPresignedUrl($s3_key );
|
||
|
||
$pdf = file_get_contents($s3_url['url']);
|
||
if ($mode == 1) {
|
||
// Inline view
|
||
return $this->response
|
||
->setHeader('Content-Type', 'application/pdf')
|
||
->setHeader('Content-Disposition', 'inline; filename="' . $s3_key . '"')
|
||
->setBody($pdf);
|
||
} else if($mode == 0){
|
||
// echo 'Force download';//die();
|
||
return $this->response
|
||
->setHeader('Content-Type', 'application/pdf')
|
||
->setHeader('Content-Disposition', 'attachment; filename="' . $s3_key . '"')
|
||
->setBody($pdf);
|
||
}
|
||
// exit();
|
||
}
|
||
// else
|
||
// {
|
||
// if($mode !== 2)
|
||
// {
|
||
// $data['message'] = 'Inprogress... Comeback later! or Contact support';
|
||
// return view('errors/404', $data);
|
||
// }
|
||
// }
|
||
|
||
//in else generate PDF and upload it in s3
|
||
// echo 'else';
|
||
// exit();
|
||
// Step 2: Fetch ECard data
|
||
$this->myLogger->logme('error', 'Fetching ECard data using client_policy_id: ' . $client_policy_id . ' and emp_code: ' . $emp_code);
|
||
$data = $this->employeePolicyModel->getECardDataUsingMd5($client_policy_id, $emp_code,$client_id);
|
||
|
||
if ($people == 0) {
|
||
$this->myLogger->logme('error', 'Fetching single ECard data using rand_string: ' . $rand_string . ' and emp_code: ' . $emp_code);
|
||
$data = $this->employeePolicyModel->getECardSingleData($rand_string, $emp_code,$client_id);
|
||
}
|
||
|
||
// Step 3: Prepare template path
|
||
$template_data_path = WRITEPATH . 'e_card_template/';
|
||
// $tpa_short_name = strtolower(str_replace(' ', '_', $get_emp_code_and_client_policy_id['short_name'])) . '.html';
|
||
// $tpa_short_name = 'common.html';
|
||
$tpa_short_name = 'new_ecard.html';
|
||
$final_path = $template_data_path . $tpa_short_name;
|
||
|
||
$this->myLogger->logme('error', 'Checking if template file exists at: ' . $final_path);
|
||
|
||
if (!file_exists($final_path)) {
|
||
$this->myLogger->logme('error', 'Template file not found: ' . $final_path);
|
||
$data['message'] = 'Template File Not Found';
|
||
return view('errors/404', $data);
|
||
}
|
||
|
||
$this->myLogger->logme('error', 'Template file found. Reading template data.');
|
||
$tmplt_data = file_get_contents($final_path);
|
||
|
||
// Step 4: Generate HTML content
|
||
$this->myLogger->logme('error', 'Generating HTML content from template.');
|
||
$html = "";
|
||
foreach ($data as $key => $value) {
|
||
$htmlContent = $tmplt_data;
|
||
|
||
$value['front_card'] = "Nhance_Ecard_working_1_front.png";
|
||
$value['back_card'] = "Nhance_Ecard_working_1_Back.png";
|
||
|
||
$placeholders = [
|
||
|
||
'{CLIENT_NAME}' => $value['client_name'],
|
||
'{TPA_ID}' => $value['tpa_id'],
|
||
'{NAME}' => $value['name'],
|
||
'{UHID}' => $value['uhid'],
|
||
'{GENDER}' => $value['gender'],
|
||
'{DOB}' => date('d-M-Y', strtotime($value['dob'])),
|
||
'{SELF_NAME}' => $value['self'] ?? $value['name'],
|
||
'{POLICY_DATE}' => date('d-M-Y', strtotime($value['policy_end_date'])),
|
||
'{POLICY_START_DATE}' => date('d-M-Y', strtotime($value['policy_start_date'])),
|
||
'{POLICY_NO}' => $value['policy_no'],
|
||
'{INSURER_NAME}' => strtoupper($value['insurer_name']),
|
||
'{EMP_ID}' => $value['emp_code'],
|
||
'{SI_AMT}' => $value['basic_cover_si'],
|
||
'{CORPORATE_NAME}' => $value['client_name'],
|
||
'{AGE}' => $value['emp_age'],
|
||
'{TPA_NAME}' => $value['tpa_name'],
|
||
'{INSURER_BRANCH}' => $value['insurer_branch_city'],
|
||
'{RELATION}' => $value['relationship'],
|
||
|
||
'{TPA_LOGO}' => getFileIfExists('uploads/logo/' . $value['tpa_logo']),
|
||
'{MEDI_USER}' => getFileIfExists('e_card_imgs/medi_uesr.jpg'),
|
||
'{MEDI_INSURER}' => getFileIfExists('e_card_imgs/Magma.png'),
|
||
'{MEDI_BARCODE}' => getFileIfExists('e_card_imgs/borcode.jpeg'),
|
||
'{QR_ANDROID}' => getFileIfExists('e_card_imgs/android.png'),
|
||
'{QR_IOS}' => getFileIfExists('e_card_imgs/ios.png'),
|
||
'{QR_ANDROID_2}' => getFileIfExists('e_card_imgs/play_store.png'),
|
||
'{QR_IOS_2}' => getFileIfExists('e_card_imgs/appstore.png'),
|
||
'{NHANCE_N_LOGO}' => getFileIfExists('assets/images/Nhance_Favi.png'),
|
||
'{INSURER_LOGO}' => getFileIfExists('uploads/logo/' . $value['insurer_logo']),
|
||
'{FRONT_CARD}' => getFileIfExists('uploads/template_bg/' . $value['front_card']),
|
||
'{BACK_CARD}' => getFileIfExists('uploads/template_bg/' . $value['back_card']),
|
||
|
||
// '{TPA_LOGO}' => base_url() . 'public/uploads/logo/' . $value['tpa_logo'],
|
||
// '{MEDI_USER}' => base_url() . 'public/e_card_imgs/medi_uesr.jpg',
|
||
// '{MEDI_INSURER}' => base_url() . 'public/e_card_imgs/Magma.png',
|
||
// '{MEDI_BARCODE}' => base_url() . 'public/e_card_imgs/borcode.jpeg',
|
||
// '{QR_ANDROID}' => base_url() . 'public/e_card_imgs/android.png',
|
||
// '{QR_IOS}' => base_url() . 'public/e_card_imgs/ios.png',
|
||
// '{QR_ANDROID_2}' => base_url() . 'public/e_card_imgs/play_store.png',
|
||
// '{QR_IOS_2}' => base_url() . 'public/e_card_imgs/appstore.png',
|
||
// '{NHANCE_N_LOGO}' => base_url() . 'public/assets/images/Nhance_Favi.png',
|
||
// '{INSURER_LOGO}' => base_url() . 'public/uploads/logo/' . $value['insurer_logo'],
|
||
// '{FRONT_CARD}' => base_url() . 'public/uploads/template_bg/' . $value['front_card'],
|
||
// '{BACK_CARD}' => base_url() . 'public/uploads/template_bg/' . $value['back_card'],
|
||
|
||
];
|
||
|
||
$placeholders['{LEVELS}'] = $this->generateAcmAndMForEcard($client_id);
|
||
$placeholders['{NETWORK_HOSPITAL}'] = $this->generateNetworkHospitalsForEcard($value['network_hospitals']);
|
||
|
||
foreach ($placeholders as $placeholder => $replaceValue) {
|
||
$htmlContent = str_replace($placeholder, $replaceValue, $htmlContent);
|
||
}
|
||
|
||
$html .= $htmlContent;
|
||
}
|
||
|
||
// return $html;
|
||
// echo $html;die();
|
||
// DomPdf
|
||
$options = new Options();
|
||
$options->set('isRemoteEnabled', true);
|
||
$options->set('isHtml5ParserEnabled', true);
|
||
|
||
$dompdf = new Dompdf($options);
|
||
// $dompdf->loadHtml('<style>@page { margin: 0; }</style>' . $html); // remove the margin
|
||
$dompdf->loadHtml('
|
||
<style>
|
||
@page { margin: 0; }
|
||
@import url("https://fonts.googleapis.com/css2?family=Lato:wght@400;700&display=swap");
|
||
body { font-family: "Lato", sans-serif !important; }
|
||
</style>
|
||
' . $html
|
||
);
|
||
|
||
$dompdf->setPaper('A4', 'portrait');
|
||
$dompdf->render();
|
||
|
||
// Set document title
|
||
$dompdf->addInfo("Title", "E-Card");
|
||
|
||
$filename = 'ecard_' . date('Y-m-d_H-i-s') . '.pdf';
|
||
$temp_local_path = WRITEPATH.'/tmp/'.$s3_key;
|
||
file_put_contents(($temp_local_path),$dompdf->output());
|
||
// if($mode == 1){
|
||
// $dompdf->stream($filename, ['Attachment' => false]); // Inline view
|
||
// }else{
|
||
// $dompdf->stream($filename, ['Attachment' => true]); // Force download
|
||
// }
|
||
$aws_upload_res = $s3->upload(($temp_local_path));
|
||
// print_rr($aws_upload_res);
|
||
// echo '<br>PDF generated and uploaded to S3 successfully.<br>';
|
||
unlink($temp_local_path);
|
||
|
||
if($s3->exists($s3_key)) //2 => for bulk generate so skip s3 check and generate PDF
|
||
{
|
||
//get pre signed url & make it download
|
||
$s3_url = $s3->getPresignedUrl($s3_key );
|
||
|
||
$pdf = file_get_contents($s3_url['url']);
|
||
if ($mode == 1) {
|
||
// Inline view
|
||
return $this->response
|
||
->setHeader('Content-Type', 'application/pdf')
|
||
->setHeader('Content-Disposition', 'inline; filename="' . $s3_key . '"')
|
||
->setBody($pdf);
|
||
} else if($mode == 0){
|
||
// echo 'Force download';//die();
|
||
return $this->response
|
||
->setHeader('Content-Type', 'application/pdf')
|
||
->setHeader('Content-Disposition', 'attachment; filename="' . $s3_key . '"')
|
||
->setBody($pdf);
|
||
}
|
||
// exit();
|
||
}
|
||
|
||
// $this->myLogger->logme('error', 'generateIDCardForEmployee function completed successfully.');
|
||
|
||
} catch (\Exception $e) {
|
||
$this->myLogger->logme('error', 'Exception occurred: ' . $e->getMessage());
|
||
$data['message'] = 'Record Not Found';
|
||
return view('errors/404', $data);
|
||
}
|
||
|
||
}
|
||
|
||
public function sanitizeFilePart(string $value): string
|
||
{
|
||
// Trim spaces
|
||
$value = trim($value);
|
||
|
||
// Replace ANY unsafe character (including /) with underscore
|
||
$value = preg_replace('/[^A-Za-z0-9._()-]/', '_', $value);
|
||
|
||
// Collapse multiple underscores
|
||
$value = preg_replace('/_+/', '_', $value);
|
||
|
||
return $value;
|
||
}
|
||
|
||
// --------------------------------------------------------------------------------------------------------------------
|
||
|
||
public function viewECard()
|
||
{
|
||
|
||
// $this->loadLayout('ecard_template/default_ecard');
|
||
|
||
$empDataServiceController = new EmpDataServiceController();
|
||
$return = $empDataServiceController->importDeletionValidation(['file_id' => 130]);
|
||
|
||
}
|
||
|
||
//truncateFileDataIn DB (de activate rows) NEW FUNCTION
|
||
public function truncateFileData($file_id, $role_id = null)
|
||
{
|
||
$this->myLogger->logme('error', '---- truncateFileData Function called ----');
|
||
$file_id = $this->request->uri->getSegment(3);
|
||
// $file_id = 747;
|
||
|
||
$this->myLogger->logme('error', 'File id for truncate : -- FILE ID : {data} --', ['data' => $file_id]);
|
||
|
||
//get the files data
|
||
$file = $this->fileModel->find((int)$file_id);
|
||
|
||
$client_id = $file['client_id'];
|
||
$client_policy_id = $file['policy_id'];
|
||
$loggedInUserID = get_session_userid();
|
||
|
||
//get the client policy data
|
||
$policy_data = $this->clientPolicyModel->where('id', $client_policy_id)->first();
|
||
|
||
//get the cd transaction data based on the insurer and client
|
||
$cd_tranction = $this->cashDepositModel
|
||
->where('client_id', $client_id) //client
|
||
->where('insurer_id', $policy_data['insurer_id']) //insurer
|
||
->where('event_name',$file['action']) //event
|
||
->where('client_policy_id', $client_policy_id)//policy
|
||
->orderBy('id', 'desc')
|
||
->first();
|
||
|
||
// dd($cd_tranction, db_connect()->getLastQuery());
|
||
if ($file['action'] == 'inception' || $file['action'] == 'dependent_addition' || $file['action'] == 'addition' || $file['action'] == 'enrollment' || $file['action'] == 'missed_inception') {
|
||
|
||
|
||
if($file['action'] == 'enrollment'){
|
||
$result = $this->employeeModel->getEmpListByFileId(file_id: $file_id, emp_status: ['draft','enrolled'], policy_status: ['draft','enrolled']);
|
||
}else{
|
||
$result = $this->employeeModel->getEmpListByFileId(file_id: $file_id, emp_status: ['active'], policy_status: ['active']);
|
||
}
|
||
|
||
// print_r($result); die;
|
||
if (count($result) && $role_id == null) {
|
||
|
||
if(get_role_id() == 1 || get_role_id() == 5){
|
||
return $this->respond(['role' => get_role_id(), 'dataStatus' => false, 'code' => 404, 'message' => 'File data already processed. Do you want to truncate data from uploaded file?'], 200);
|
||
}else{
|
||
return $this->respond(['role' => get_role_id(), 'dataStatus' => false, 'code' => 404, 'message' => 'File data already processed'], 200);
|
||
}
|
||
|
||
} else {
|
||
|
||
$this->myLogger->logme('error', '---- TRUNCATED STARTED WITH ADMIN OR HEAD PERMISSION ----');
|
||
$this->myLogger->logme('error', '---- Event Type : -- {data} ----', ['data' => $file['action']]);
|
||
|
||
if($file['action'] != 'enrollment')
|
||
{
|
||
$employee_policy_data_with_file_id = $this->employeePolicyModel->where('file_id', $file_id)->findAll();
|
||
|
||
if(!empty($employee_policy_data_with_file_id) && count($employee_policy_data_with_file_id) > 0){
|
||
|
||
// GET THE CD TRANSACTION AMOUNT
|
||
$cd_amount_total = $this->employeePolicyModel->calculateCdTranctionAmount($file_id);
|
||
$cd_amount = $cd_amount_total['total'] ?? 0;
|
||
$this->myLogger->logme('error', '---- CD Amount : {data} ----', ['data' => $cd_amount]);
|
||
|
||
//STEP: 1 - Update employee policy table
|
||
$db = db_connect();
|
||
$query = "
|
||
UPDATE employee_polices
|
||
SET employee_polices.status = 'truncated', employee_polices.is_active = 0
|
||
WHERE employee_polices.file_id = :file_id:
|
||
";
|
||
|
||
$binds = ["file_id" => $file_id];
|
||
$db->query($query,$binds);
|
||
$affectedRows = $db->affectedRows();
|
||
$this->myLogger->logme('error', '---- employee_polices table update query : {data} ----', ['data' => $query]);
|
||
$this->myLogger->logme('error', '---- employee_polices table updated - Affected Rows : {data} ----', ['data' => $affectedRows]);
|
||
// print_r($db->getLastQuery()); die;
|
||
|
||
//STEP:2 - Update emp_endorsement Table
|
||
if(in_array($file['action'], ['addition', 'dependent_addition'])){
|
||
$this->empEndorsementModel->where('file_id', $file_id)->set(['status' => 'truncated','is_active' => 0])->update();
|
||
$this->myLogger->logme('error', '---- emp_endorsement table updated ----');
|
||
}
|
||
|
||
//STEP:3 - Update files table status
|
||
$this->fileModel->where('id', $file_id)->set(['status' => 'truncated','updated_by' => $loggedInUserID])->update();
|
||
$this->myLogger->logme('error', '---- files table updated ----');
|
||
|
||
//FINAL STEP - Update reverse entry in cash_deposite table
|
||
if(!empty($cd_amount)){
|
||
|
||
$cd_data = [
|
||
'amount' => $cd_amount,
|
||
'sub_type_id' => 8,
|
||
'endorsement_no' => null,
|
||
'insurer_id' =>$policy_data['insurer_id'],
|
||
'description' => 'The policy Truncated by Admin or Head',
|
||
'transaction_type' => 'Credit',
|
||
'updated_by' => 1,
|
||
'client_id' => $client_id,
|
||
'client_policy_id' => $client_policy_id,
|
||
'cd_ac_no' => $policy_data['cd_ac_no'] ?? null,
|
||
'cd_ac_pk' => $policy_data['cd_ac_pk'] ?? null,
|
||
'event_name' => $file['action'],
|
||
];
|
||
|
||
$response = DepositHelper::saveDeposit($cd_data, $loggedInUserID);
|
||
$this->myLogger->logme('error', 'cash_deposite table updated -- cd transaction');
|
||
}
|
||
|
||
//this job for deactive policy transaction and pt co share table entry for BDS Sync
|
||
$r = Jobs::addJob(['job_name' => 'removeBDSPolicyTransactionEntryFromTruncate', 'payload' => [
|
||
'client_policy_id' => $client_policy_id ?? null,
|
||
'file_id' => $file_id ?? null,
|
||
'action_type' => $file['action'] ?? null,
|
||
]]);
|
||
|
||
}else{
|
||
|
||
$this->myLogger->logme('error', '---- There is no data to truncate ----');
|
||
return $this->respond(['role' => get_role_id(), 'dataStatus' => false, 'code' => 404, 'message' => 'There is no data to truncate'], 200);
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
// echo 'came here...1';
|
||
//check all dependents added by self and other dependent policies
|
||
$emp_codes = $this->employeeModel->select('emp_code')
|
||
->where('file_id', $file_id)
|
||
->findAll();
|
||
$emp_codes = array_column($emp_codes,'emp_code');
|
||
// Kint::dump($emp_codes);//die;
|
||
|
||
$dependent_policies = $this->clientPolicyModel->select('id')
|
||
->where('base_policy', $client_policy_id)
|
||
->findAll();
|
||
// $dependent_policies = [ [10],[25],[35] ];
|
||
// Kint::dump($dependent_policies);
|
||
// Kint::dump(array_column($dependent_policies,'id'));
|
||
if(count($dependent_policies))
|
||
{
|
||
$dependent_policies = array_column($dependent_policies,'id');
|
||
// Kint::dump($dependent_policies);
|
||
$second_level_dependent_policies = $this->clientPolicyModel->select('id')
|
||
->whereIn('base_policy', $dependent_policies)
|
||
->findAll();
|
||
// dd($second_level_dependent_policies);
|
||
if(count($second_level_dependent_policies))
|
||
{
|
||
$second_level_dependent_policies = array_column($second_level_dependent_policies,'id');
|
||
}
|
||
|
||
$dependent_policies = array_merge($dependent_policies,$second_level_dependent_policies);
|
||
}
|
||
$dependent_policies = array_merge($dependent_policies,[$client_policy_id]);
|
||
// Kint::dump($dependent_policies);
|
||
|
||
//update emp and emp plocies
|
||
$db = db_connect();
|
||
$emp_codes = '(' . implode(',', array_map(fn($code) => "'$code'", $emp_codes)) . ')';
|
||
$dependent_policies = '(' . implode(',', $dependent_policies) . ')';
|
||
$query = "
|
||
UPDATE employee_polices
|
||
JOIN employees ON employees.id = employee_polices.employee_id and employees.emp_code in :emp_codes:
|
||
SET employee_polices.status = 'truncated', employee_polices.is_active = 0
|
||
WHERE employee_polices.client_policy_id in :dependent_policies:
|
||
";
|
||
// print_r($query); die;
|
||
$binds = ["emp_codes" => $emp_codes , "dependent_policies" => $dependent_policies];
|
||
$db->query($query,$binds);
|
||
$affectedRows = $db->affectedRows();
|
||
|
||
// dd($affectedRows);
|
||
$affectedRows = $affectedRows * 2;
|
||
$this->fileModel->where('id', $file_id)->set(['status' => 'truncated','updated_by' => $loggedInUserID])->update();
|
||
|
||
}
|
||
|
||
$this->myLogger->logme('error', 'SUCCESSFULLY TRUNCATED');
|
||
|
||
return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => round($affectedRows / 2)], 200);
|
||
}
|
||
|
||
} else if ($file['action'] == 'si_enhancement' || $file['action'] == 'correction' || $file['action'] == 'deletion') {
|
||
|
||
$res = $this->empEndorsementModel->select(['count(id) as count'])
|
||
->where('emp_endorsement.file_id', $file_id)
|
||
->groupStart()
|
||
->where('emp_endorsement.endorsement_id is not null')
|
||
->orwhereIn('emp_endorsement.status', ['complete'])
|
||
->groupEnd()
|
||
->get()
|
||
->getResult();
|
||
|
||
// dd($res);
|
||
// print_r($this->empEndorsementModel->getLastQuery());
|
||
// echo $res[0]->count;die();
|
||
|
||
if ($res[0]->count == 0 || $role_id == 5 || $role_id == 1) {
|
||
|
||
$this->myLogger->logme('error', 'TRUNCATED STARTED WITH ADMIN OR HEAD PERMISSION');
|
||
$this->myLogger->logme('error', 'Event Type : -- {data} --', ['data' => $file['action']]);
|
||
|
||
$transaction_type = 'Credit';
|
||
$cd_amount = 0;
|
||
|
||
if($file['action'] == 'deletion' && $res[0]->count > 0){
|
||
|
||
$transaction_type = 'Debit';
|
||
//get cd amount for the particular file id to reverse entry to the cash deposite for only deletion
|
||
$cd_amount_total = $this->employeePolicyModel->getDeletionDataForTruncated($file['id']);
|
||
$totalSum = array_sum(array_column($cd_amount_total, 'total'));
|
||
$cd_amount = $totalSum ?? 0;
|
||
|
||
$this->myLogger->logme('error', 'Deletion CD Amount : {data}', ['data' => $cd_amount]);
|
||
}
|
||
|
||
$this->myLogger->logme('error', 'Endorsemnt CD Amount : {data}', ['data' => $cd_amount]);
|
||
|
||
|
||
//STEP 1:
|
||
//update truncated status to the Emp_endorsement table
|
||
$this->empEndorsementModel->where('file_id', $file_id)
|
||
->set(['status' => 'truncated','is_active' => 0])
|
||
->update();
|
||
|
||
$this->myLogger->logme('error', 'emp_endorsement table updated');
|
||
|
||
//STEP 2:
|
||
if($file['action'] == 'deletion' && $res[0]->count > 0) {
|
||
//update the employee policy table reverse the data
|
||
$this->employeePolicyModel->updateEmployeePolicyTruncateReverse($file_id);
|
||
$this->myLogger->logme('error', 'employee_polices table updated for deletion');
|
||
}
|
||
|
||
if($file['action'] == 'correction'){
|
||
|
||
}
|
||
|
||
// STEP 3:
|
||
//update files table status to "truncated"
|
||
$this->fileModel->where('id', $file_id)->set(['status' => 'truncated','updated_by' => $loggedInUserID])->update();
|
||
$this->myLogger->logme('error', 'files table updated');
|
||
|
||
|
||
if(!empty($cd_amount) && $file['action'] != 'correction'){
|
||
|
||
$cd_data = [
|
||
'amount' => $cd_amount,
|
||
'sub_type_id' => 8,
|
||
'endorsement_no' => null,
|
||
'insurer_id' =>$policy_data['insurer_id'],
|
||
'description' => 'The policy Truncated by Admin or Head',
|
||
'transaction_type' => $transaction_type,
|
||
'updated_by' => 1,
|
||
'client_id' => $client_id,
|
||
'client_policy_id' => $client_policy_id,
|
||
'cd_ac_no' => $policy_data['cd_ac_no'] ?? null,
|
||
'cd_ac_pk' => $policy_data['cd_ac_pk'] ?? null,
|
||
'event_name' => $file['action'],
|
||
];
|
||
|
||
$response = DepositHelper::saveDeposit($cd_data, $loggedInUserID);
|
||
$this->myLogger->logme('error', 'cash_deposite table updated -- cd transaction');
|
||
|
||
}
|
||
|
||
//this job for deactive policy transaction and pt co share table entry for BDS Sync
|
||
$r = Jobs::addJob(['job_name' => 'removeBDSPolicyTransactionEntryFromTruncate', 'payload' => [
|
||
'client_policy_id' => $client_policy_id ?? null,
|
||
'file_id' => $file_id ?? null,
|
||
'action_type' => $file['action'] ?? null,
|
||
]]);
|
||
|
||
$this->myLogger->logme('error', 'SUCCESSFULLY TRUNCATED');
|
||
|
||
return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => 'success'], 200);
|
||
|
||
} else {
|
||
if(get_role_id() == 1 || get_role_id() == 5){
|
||
return $this->respond(['role' => get_role_id(), 'dataStatus' => false, 'code' => 404, 'message' => 'File data already processed. Do you want to truncate data from uploaded file?'], 200);
|
||
}else{
|
||
return $this->respond(['dataStatus' => false, 'code' => 404, 'message' => 'File data already processed'], 200);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//truncateFileData OLD FUNCTION
|
||
public function truncateFileDataOld($file_id, $role_id = null)
|
||
{
|
||
$file_id = $this->request->uri->getSegment(3);
|
||
// $file_id = 747;
|
||
$file = $this->fileModel->find((int)$file_id);
|
||
$client_id = $file['client_id'];
|
||
$client_policy_id = $file['policy_id'];
|
||
$loggedInUserID = get_session_userid();
|
||
|
||
$policy_data = $this->clientPolicyModel->where('id', $client_policy_id)->first();
|
||
|
||
$cd_tranction = $this->cashDepositModel
|
||
->where('client_id', $client_id) //client
|
||
->where('insurer_id', $policy_data['insurer_id']) //insurer
|
||
->where('event_name',$file['action']) //event
|
||
->where('client_policy_id', $client_policy_id)//policy
|
||
->orderBy('id', 'desc')
|
||
->first();
|
||
|
||
|
||
// $file['action'] = 'si_enhancement';
|
||
// $result = [];
|
||
// dd($file);
|
||
if ($file['action'] == 'inception' || $file['action'] == 'dependent_addition' || $file['action'] == 'addition' || $file['action'] == 'enrollment' || $file['action'] == 'missed_inception') {
|
||
|
||
|
||
if($file['action'] == 'enrollment'){
|
||
$result = $this->employeeModel->getEmpListByFileId(file_id: $file_id, emp_status: ['draft','enrolled'], policy_status: ['draft','enrolled']);
|
||
}else{
|
||
$result = $this->employeeModel->getEmpListByFileId(file_id: $file_id, emp_status: ['active'], policy_status: ['active']);
|
||
}
|
||
|
||
$result = [];
|
||
// ~dd($result);
|
||
if (count($result) && $role_id == null) {
|
||
if(get_role_id() == 1 || get_role_id() == 5){
|
||
return $this->respond(['role' => get_role_id(), 'dataStatus' => false, 'code' => 404, 'message' => 'File data already processed. Do you want to truncate data from uploaded file?'], 200);
|
||
}else{
|
||
return $this->respond(['role' => get_role_id(), 'dataStatus' => false, 'code' => 404, 'message' => 'File data already processed'], 200);
|
||
}
|
||
} else {
|
||
|
||
$this->myLogger->logme('error', 'TRUNCATED STARTED WITH ADMIN OR HEAD PERMISSION');
|
||
$this->myLogger->logme('error', 'Event Type : -- {data} --', ['data' => $file['action']]);
|
||
|
||
|
||
// GET THE CD AMOUND
|
||
//get cd amount for the particular file id to reverse entry to the cash deposite
|
||
$cd_amount = $cd_tranction['amount'];
|
||
if(in_array($file['action'], ['addition', 'dependent_addition'])){
|
||
$cd_amount_total = $this->employeePolicyModel->getAdditionDataForTruncated($file_id, $file['action']);
|
||
// dd($cd_amount_total);
|
||
$cd_amount = $cd_amount_total['total'];
|
||
|
||
$this->myLogger->logme('error', 'Addition or Dependent Addition CD Amount : {data}', ['data' => $cd_amount]);
|
||
}
|
||
|
||
$this->myLogger->logme('error', 'CD Amount : {data}', ['data' => $cd_amount]);
|
||
|
||
|
||
if($file['action'] != 'enrollment')
|
||
{
|
||
//STEP: 1 - Update employee policy table
|
||
//update emp and emp plocies
|
||
$db = db_connect();
|
||
$query = "
|
||
UPDATE employee_polices
|
||
SET employee_polices.status = 'truncated', employee_polices.is_active = 0
|
||
WHERE employee_polices.file_id = :file_id:
|
||
";
|
||
|
||
$binds = ["file_id" => $file_id];
|
||
$db->query($query,$binds);
|
||
$affectedRows = $db->affectedRows();
|
||
$this->myLogger->logme('error', 'employee_polices table update query : {data}', ['data' => $query]);
|
||
$this->myLogger->logme('error', 'employee_polices table updated - Affected Rows : {data}', ['data' => $affectedRows]);
|
||
// print_r($db->getLastQuery()); die;
|
||
// $affectedRows = 10;
|
||
|
||
//STEP:2 - Update emp_endorsement Table
|
||
//update truncated status and is_active 0 to the Emp_endorsement table
|
||
if(in_array($file['action'], ['addition', 'dependent_addition'])){
|
||
$this->empEndorsementModel->where('file_id', $file_id)
|
||
->set(['status' => 'truncated','is_active' => 0])
|
||
->update();
|
||
|
||
$this->myLogger->logme('error', 'emp_endorsement table updated');
|
||
}
|
||
|
||
//STEP:3 - Update files table
|
||
//update file status
|
||
$this->fileModel->where('id', $file_id)->set(['status' => 'truncated'])->update();
|
||
$this->myLogger->logme('error', 'files table updated');
|
||
}
|
||
else
|
||
{
|
||
// echo 'came here...1';
|
||
//check all dependents added by self and other dependent policies
|
||
$emp_codes = $this->employeeModel->select('emp_code')
|
||
->where('file_id', $file_id)
|
||
->findAll();
|
||
$emp_codes = array_column($emp_codes,'emp_code');
|
||
// Kint::dump($emp_codes);//die;
|
||
|
||
$dependent_policies = $this->clientPolicyModel->select('id')
|
||
->where('base_policy', $client_policy_id)
|
||
->findAll();
|
||
// $dependent_policies = [ [10],[25],[35] ];
|
||
// Kint::dump($dependent_policies);
|
||
// Kint::dump(array_column($dependent_policies,'id'));
|
||
if(count($dependent_policies))
|
||
{
|
||
$dependent_policies = array_column($dependent_policies,'id');
|
||
// Kint::dump($dependent_policies);
|
||
$second_level_dependent_policies = $this->clientPolicyModel->select('id')
|
||
->whereIn('base_policy', $dependent_policies)
|
||
->findAll();
|
||
// dd($second_level_dependent_policies);
|
||
if(count($second_level_dependent_policies))
|
||
{
|
||
$second_level_dependent_policies = array_column($second_level_dependent_policies,'id');
|
||
}
|
||
|
||
$dependent_policies = array_merge($dependent_policies,$second_level_dependent_policies);
|
||
}
|
||
$dependent_policies = array_merge($dependent_policies,[$client_policy_id]);
|
||
// Kint::dump($dependent_policies);
|
||
|
||
//update emp and emp plocies
|
||
$db = db_connect();
|
||
$emp_codes = '(' . implode(',', array_map(fn($code) => "'$code'", $emp_codes)) . ')';
|
||
$dependent_policies = '(' . implode(',', $dependent_policies) . ')';
|
||
$query = "
|
||
UPDATE employee_polices
|
||
JOIN employees ON employees.id = employee_polices.employee_id and employees.emp_code in :emp_codes:
|
||
SET employee_polices.status = 'truncated', employee_polices.is_active = 0
|
||
WHERE employee_polices.client_policy_id in :dependent_policies:
|
||
";
|
||
$binds = ["emp_codes" => $emp_codes , "dependent_policies" => $dependent_policies];
|
||
$db->query($query,$binds);
|
||
$affectedRows = $db->affectedRows();
|
||
|
||
// dd($affectedRows);
|
||
$affectedRows = $affectedRows * 2;
|
||
$this->fileModel->where('id', $file_id)->set(['status' => 'truncated'])->update();
|
||
|
||
}
|
||
|
||
//FINAL STEP - Update reverse entry in cash_deposite table
|
||
if($cd_tranction){
|
||
|
||
$cd_data = [
|
||
'amount' => $cd_amount,
|
||
'sub_type_id' => 8,
|
||
'endorsement_no' => null,
|
||
'insurer_id' =>$policy_data['insurer_id'],
|
||
'description' => 'The policy Truncated by Admin or Head',
|
||
'transaction_type' => 'Credit',
|
||
'updated_by' => 1,
|
||
'client_id' => $client_id,
|
||
'client_policy_id' => $client_policy_id,
|
||
'cd_ac_no' => $policy_data['cd_ac_no'] ?? null,
|
||
'cd_ac_pk' => $policy_data['cd_ac_pk'] ?? null,
|
||
'event_name' => $file['action'],
|
||
];
|
||
|
||
$response = DepositHelper::saveDeposit($cd_data, $loggedInUserID);
|
||
$this->myLogger->logme('error', 'cash_deposite table updated -- cd transaction');
|
||
|
||
}
|
||
|
||
$this->myLogger->logme('error', 'SUCCESSFULLY TRUNCATED');
|
||
|
||
return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => round($affectedRows / 2)], 200);
|
||
}
|
||
|
||
} else if ($file['action'] == 'si_enhancement' || $file['action'] == 'correction' || $file['action'] == 'deletion') {
|
||
|
||
$res = $this->empEndorsementModel->select(['count(id) as count'])
|
||
->where('emp_endorsement.file_id', $file_id)
|
||
->groupStart()
|
||
->where('emp_endorsement.endorsement_id is not null')
|
||
->orwhereIn('emp_endorsement.status', ['complete'])
|
||
->groupEnd()
|
||
->get()
|
||
->getResult();
|
||
|
||
// print_r($this->empEndorsementModel->getLastQuery());
|
||
// echo $res[0]->count;die();
|
||
|
||
if ($res[0]->count == 0 || $role_id == 5 || $role_id == 1) {
|
||
|
||
$this->myLogger->logme('error', 'TRUNCATED STARTED WITH ADMIN OR HEAD PERMISSION');
|
||
$this->myLogger->logme('error', 'Event Type : -- {data} --', ['data' => $file['action']]);
|
||
|
||
$transaction_type = 'Credit';
|
||
$cd_amount = $cd_tranction['amount'];
|
||
|
||
if($file['action'] == 'deletion'){
|
||
$transaction_type = 'Debit';
|
||
//get cd amount for the particular file id to reverse entry to the cash deposite for only deletion
|
||
$cd_amount_total = $this->employeePolicyModel->getDeletionDataForTruncated($file['id']);
|
||
$totalSum = array_sum(array_column($cd_amount_total, 'total'));
|
||
$cd_amount = $totalSum;
|
||
|
||
$this->myLogger->logme('error', 'Deletion CD Amount : {data}', ['data' => $cd_amount]);
|
||
}
|
||
|
||
$this->myLogger->logme('error', 'Endorsemnt CD Amount : {data}', ['data' => $cd_amount]);
|
||
|
||
|
||
//STEP 1:
|
||
//update truncated status to the Emp_endorsement table
|
||
$this->empEndorsementModel->where('file_id', $file_id)
|
||
->set(['status' => 'truncated','is_active' => 0])
|
||
->update();
|
||
|
||
$this->myLogger->logme('error', 'emp_endorsement table updated');
|
||
|
||
//STEP 2:
|
||
if($file['action'] == 'deletion') {
|
||
//update the employee policy table reverse the data
|
||
$this->employeePolicyModel->updateEmployeePolicyTruncateReverse($file_id);
|
||
$this->myLogger->logme('error', 'employee_polices table updated for deletion');
|
||
}
|
||
|
||
if($file['action'] == 'correction'){
|
||
|
||
}
|
||
|
||
// STEP 3:
|
||
//update files table status to "truncated"
|
||
$this->fileModel->where('id', $file_id)->set(['status' => 'truncated'])->update();
|
||
$this->myLogger->logme('error', 'files table updated');
|
||
|
||
|
||
if($cd_tranction && $file['action'] != 'correction'){
|
||
|
||
$cd_data = [
|
||
'amount' => $cd_amount,
|
||
'sub_type_id' => 8,
|
||
'endorsement_no' => null,
|
||
'insurer_id' =>$policy_data['insurer_id'],
|
||
'description' => 'The policy Truncated by Admin or Head',
|
||
'transaction_type' => $transaction_type,
|
||
'updated_by' => 1,
|
||
'client_id' => $client_id,
|
||
'client_policy_id' => $client_policy_id,
|
||
'cd_ac_no' => $policy_data['cd_ac_no'] ?? null,
|
||
'cd_ac_pk' => $policy_data['cd_ac_pk'] ?? null,
|
||
'event_name' => $file['action'],
|
||
];
|
||
|
||
$response = DepositHelper::saveDeposit($cd_data, $loggedInUserID);
|
||
$this->myLogger->logme('error', 'cash_deposite table updated -- cd transaction');
|
||
|
||
}
|
||
|
||
$this->myLogger->logme('error', 'SUCCESSFULLY TRUNCATED');
|
||
|
||
return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => 'success'], 200);
|
||
|
||
} else {
|
||
if(get_role_id() == 1 || get_role_id() == 5){
|
||
return $this->respond(['role' => get_role_id(), 'dataStatus' => false, 'code' => 404, 'message' => 'File data already processed. Do you want to truncate data from uploaded file?'], 200);
|
||
}else{
|
||
return $this->respond(['dataStatus' => false, 'code' => 404, 'message' => 'File data already processed'], 200);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
public function errorListExportImport($file_id)
|
||
{
|
||
|
||
$empDataServiceController = new EmpDataServiceController();
|
||
|
||
$file = $this->batchFileModel->where('id', $file_id)->first();
|
||
$client_id = $file['client_id'];
|
||
$client_policy_id = $file['client_policy_id'];
|
||
$insurer_or_tpa = $file['insurer_or_tpa'];
|
||
$event_type = $file['event_type'];
|
||
|
||
$error_data = json_decode($file['error_data']);
|
||
|
||
// dd($error_data);
|
||
|
||
$file_name_with_path = storage_ensure_local_file(WRITEPATH . 'uploads/import_excel', $file['file_name']);
|
||
|
||
if (!file_exists($file_name_with_path)) {
|
||
$error_message = "File not found";
|
||
$this->myLogger->logme('error', ($error_message . ' for file id ' . $file_id));
|
||
$data['message'] = 'Physical File Not Found';
|
||
return view('errors/404', $data);
|
||
}
|
||
|
||
$excel_data = $empDataServiceController->readExcelFileToArray($file_name_with_path);
|
||
// dd($excel_data);
|
||
$excelErrorData['excel_header'] = $excel_data[0];
|
||
unset($excel_data[0]);
|
||
|
||
// if($event_type == 'inception' || $event_type == 'deletion'){
|
||
// array_pop($excel_data);
|
||
// }
|
||
|
||
// if($event_type == 'deletion'){
|
||
// array_pop($excel_data);
|
||
// }
|
||
|
||
$finalArray = [];
|
||
foreach ($error_data as $key => $values) {
|
||
|
||
foreach ($values as $key2 => $value) {
|
||
|
||
$row = $value->row;
|
||
$column = $value->column;
|
||
|
||
if(property_exists($value, 'db_data')){
|
||
|
||
$error = 'Expected value: ' . ($value->db_data == null || $value->db_data == "" ? 'NULL' : $value->db_data);
|
||
|
||
}else{
|
||
|
||
if($event_type == 'inception'){
|
||
|
||
if ($insurer_or_tpa == 'tpa') {
|
||
|
||
$error = 'Expected value : TPA ID';
|
||
|
||
} else if ($insurer_or_tpa == 'insurer') {
|
||
|
||
$error = 'Expected value : UHID';
|
||
}
|
||
|
||
}else{
|
||
$error = 'Expected value : ENDORSEMENT ID';
|
||
}
|
||
|
||
|
||
}
|
||
$data = ['value' => $excel_data[$row][$column], 'error' => $error,];
|
||
$excel_data[$row][$column] = $data;
|
||
}
|
||
|
||
array_push($finalArray, $excel_data[$key]);
|
||
}
|
||
|
||
|
||
foreach ($finalArray as $fkey => $value) {
|
||
foreach ($value as $vkey => $arrayData) {
|
||
if (!is_array($arrayData)) {
|
||
$data = ['value' => $arrayData];
|
||
$finalArray[$fkey][$vkey] = $data;
|
||
}
|
||
}
|
||
}
|
||
|
||
$excelErrorData['excel_data'] = $finalArray;
|
||
$excelErrorData['file_id'] = $file_id;
|
||
|
||
// dd($excelErrorData);
|
||
|
||
echo view('export_import_error_list', $excelErrorData);
|
||
}
|
||
|
||
public function hasPolicyConfigCompleted()
|
||
{
|
||
$client_policy_id = $this->request->uri->getSegment(3);
|
||
$policy_details = $this->clientPolicyModel->find((int)$client_policy_id);
|
||
$insurer_details = $this->insurerModel->where('id', $policy_details['insurer_id'])->first();
|
||
$policy_terms = isset($policy_details['policy_terms']) ? true : false;
|
||
|
||
$si_enhancement_true_or_false = 1;
|
||
if($policy_terms){
|
||
$policyTermsData = json_decode($policy_details['policy_terms']);
|
||
|
||
if (isset($policyTermsData->suminsuredenhancement) && $policyTermsData->suminsuredenhancement !== null) {
|
||
$si_enhancement_true_or_false = $policyTermsData->suminsuredenhancement;
|
||
}
|
||
}
|
||
|
||
$employeeRest = new EmployeeRestController();
|
||
$tpa_api_service_status = $employeeRest->checkTpaApiEnable($client_policy_id, 'getTPAID', 'internel');
|
||
$tpa_push_api_service_status = $employeeRest->checkTpaApiEnable($client_policy_id, 'sendDataToTPA', 'internel');
|
||
|
||
$slab_details = $this->policiesModel->getPolicySlabRatesForEmpOnboard($client_policy_id,$policy_details['client_id']);
|
||
|
||
$message = null;
|
||
|
||
if (!isset($policy_terms)) {
|
||
$message .= 'Policy terms';
|
||
}
|
||
|
||
if($slab_details['slab_rates'] == null && $slab_details['grid_master'] == null)
|
||
{
|
||
$message = isset($message) ? ($message . ' and rack rates ') : ($message . ' Rack rates');
|
||
}
|
||
$message = isset($message) ? ($message . ' not defined for choosed policy') : null;
|
||
|
||
if ($policy_details['cd_ac_pk'] == null) {
|
||
$message = isset($message) ? ($message . ' The policy does not have a CD account number.') : null;
|
||
}
|
||
|
||
return $this->respond(['dataStatus' => true, 'code' => 200, 'message' => $message, 'si_enhancement' => $si_enhancement_true_or_false, 'insurer_multi_event' => $insurer_details['is_multi_event'], 'tpa_api_service_status' => $tpa_api_service_status, 'tpa_push_api_service_status' => $tpa_push_api_service_status], 200);
|
||
|
||
}
|
||
|
||
public function testRackRate()
|
||
{
|
||
helper('excel_util_helper');
|
||
if ($this->request->getMethod() == 'get') {
|
||
$filterData = $this->request->getGet('client_policy_id');
|
||
//just load UI only
|
||
$this->loadLayout('rack_rate_test');
|
||
}
|
||
|
||
|
||
if ($this->request->getMethod() == 'post') {
|
||
$json = $this->request->getJSON();
|
||
// return $this->respond(['dataStatus' => false, 'code' => 200, 'data' => $data], 200);
|
||
// $data = (json_decode(json_encode($data),true));
|
||
$client_id = $json->client_id;
|
||
$policy_id = $json->policy_id;
|
||
$branch_id = $json->branch_id;
|
||
$unit_id = $json->unit_id;
|
||
$action = $json->action;
|
||
$family_code = $json->emp_code;
|
||
$tabledata = $json->data;
|
||
$existing_famility_details = [];
|
||
if(count($tabledata))
|
||
{
|
||
$family_details = [];
|
||
foreach($tabledata as $key => $row)
|
||
{
|
||
$row = (array)$row;
|
||
if(!$row['column12'])
|
||
{
|
||
|
||
$temp[0] = $row['column1'];//sno
|
||
$temp[1] = $family_code != "" ? $family_code : $row['column2'];//emp code
|
||
$temp[2] = $row['column3'];//name
|
||
$temp[3] = $row['column4'];//DOB
|
||
$temp[4] = strtoupper($row['column5']);//Gender
|
||
$temp[5] = $row['column6'];//relation
|
||
$temp[6] = $row['column7'];//SI
|
||
$temp[7] = $row['column8'];//DOC
|
||
$temp[8] = '';//DOJ
|
||
$temp[9] = $row['column9'];//BP
|
||
$temp[10] = $row['column10'];//band
|
||
$temp[11] = '';//designation
|
||
$temp[12] = '';//mobile
|
||
$temp[13] = '';//EMail
|
||
$temp[14] = '';//CE
|
||
$temp[15] = '';//RFE
|
||
$temp[16] = '';//DOE
|
||
$temp[17] = '';//Unit
|
||
$temp[18] = $unit_id;//unit
|
||
$family_details[] = $temp;
|
||
}
|
||
}
|
||
}
|
||
|
||
if($action == 'dependent_addition')
|
||
{
|
||
$existing_famility_details = $this->employeeModel->getEmpFamilybyEmpCode(emp_code: $family_code,client_id: $client_id,client_policy_id: $policy_id,emp_status: ['active'],policy_status:['active'],client_branch_id: [ $branch_id ]);
|
||
// ~dd($this->employeeModel->getLastQuery());
|
||
|
||
if(!count($existing_famility_details))
|
||
{
|
||
return $this->respond(['dataStatus' => false, 'code' => 404, 'data' => [],'messgae' => "No Data found for emp code $family_code"], 200);
|
||
}
|
||
//transsform familiy details from db columns to exxcel row with column indexs for checking remaining functionalitites
|
||
$existing_famility_details = transform_db_data_to_excel($existing_famility_details,[]);
|
||
// Kint::dump($existing_famility_details);
|
||
$family_details = array_merge($family_details,$existing_famility_details);
|
||
$family_details = data_group_by_family($family_details)[ $family_code ];// reason to call this again is bring self to first index of the array
|
||
// dd($family);
|
||
}
|
||
|
||
//get policy details
|
||
$policy_details = $this->clientPolicyModel->getPolicyDetails($client_id,$policy_id);
|
||
$policy_details = (array)$policy_details[0];
|
||
// ~dd($policy_details[0]->policy_start_date);
|
||
//get rack rates
|
||
$slab_details = $this->policiesModel->getPolicySlabRatesForEmpOnboard($policy_id,$client_id);
|
||
//get file array or construnct dummy file array here
|
||
$file = ['id' => null,'client_id' => $client_id,'policy_id' => $policy_id,'action' => 'inception','client_branch_id' => $branch_id,'created_by' => 1];
|
||
//get existing units in the current branch
|
||
$existing_units = $this->clientBranchModel->getExisitingUnits(client_id: $client_id,client_branch_id: $branch_id);
|
||
//get familiy details in inception file format array from post method
|
||
$data = calculate_premium_new(family_data: $family_details,policy_terms:$policy_details,slab_details:$slab_details,fileArr: $file,existing_units: $existing_units);
|
||
// print_rr($data);die();
|
||
foreach($data as $key => $member )
|
||
{
|
||
// ~dd($member);
|
||
if(is_array($member) && isset($member['policy_details']['date_coverage']) && isset($member['policy_details']['policy_end_date']) )
|
||
{
|
||
$data[$key]['policy_details']['no_of_days'] = $member['policy_details']['date_coverage'] ? (calculate_days_bw_dates($member['policy_details']['date_coverage'],$member['policy_details']['policy_end_date'])->days + 1) : '';
|
||
}
|
||
else
|
||
{
|
||
$data[$key]['policy_details']['no_of_days'] = '0';
|
||
}
|
||
}
|
||
|
||
return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => ['new' => $data,'old' => $existing_famility_details], 200]);
|
||
}
|
||
}
|
||
|
||
|
||
public function testCheckDependentConflict()
|
||
{
|
||
helper('excel_util_helper');
|
||
if ($this->request->getMethod() == 'get') {
|
||
$filterData = $this->request->getGet('client_policy_id');
|
||
//just load UI only
|
||
$this->loadLayout('rack_rate_test');
|
||
}
|
||
|
||
|
||
if ($this->request->getMethod() == 'post') {
|
||
$json = $this->request->getJSON();
|
||
// return $this->respond(['dataStatus' => false, 'code' => 200, 'data' => $data], 200);
|
||
// $data = (json_decode(json_encode($data),true));
|
||
$client_id = $json->client_id;
|
||
$policy_id = $json->policy_id;
|
||
$branch_id = $json->branch_id;
|
||
$tabledata = $json->data;
|
||
|
||
if(count($tabledata))
|
||
{
|
||
$family_details = [];
|
||
foreach($tabledata as $key => $row)
|
||
{
|
||
$row = (array)$row;
|
||
if(!$row['column12'])
|
||
{
|
||
|
||
$temp[0] = $row['column1'];//sno
|
||
$temp[1] = $row['column2'];//emp code
|
||
$temp[2] = $row['column3'];//name
|
||
$temp[3] = $row['column4'];//DOB
|
||
$temp[4] = strtoupper($row['column5']);//Gender
|
||
$temp[5] = $row['column6'];//relation
|
||
$temp[6] = $row['column7'];//SI
|
||
$temp[7] = $row['column8'];//DOC
|
||
$temp[8] = '';//DOJ
|
||
$temp[9] = $row['column9'];//BP
|
||
$temp[10] = $row['column10'];//band
|
||
$temp[11] = '';//designation
|
||
$temp[12] = '';//mobile
|
||
$temp[13] = '';//EMail
|
||
$temp[14] = '';//CE
|
||
$temp[15] = '';//RFE
|
||
$temp[16] = '';//DOE
|
||
$temp[17] = '';//Unit
|
||
$temp[18] = $row['column11'];//unit
|
||
$family_details[] = $temp;
|
||
}
|
||
}
|
||
}
|
||
|
||
// print_r($family_details);
|
||
// return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => $family_details], 200);
|
||
//get policy details
|
||
$policy_details = $this->clientPolicyModel->getPolicyDetails($client_id,$policy_id);
|
||
$policy_terms = (array)$policy_details[0];
|
||
$is_lgbtq = $policy_terms['is_lgbtq'];
|
||
|
||
|
||
// dd($policy_terms);
|
||
$policy_terms = json_decode($policy_terms['policy_terms']);
|
||
$policy_terms = (array) $policy_terms;// convert obj to array
|
||
|
||
//get file array or construnct dummy file array here
|
||
$file = ['id' => null,'client_id' => $client_id,'policy_id' => $policy_id,'action' => 'inception','client_branch_id' => $branch_id,'created_by' => 1];
|
||
//get familiy details in inception file format array from post method
|
||
$result = check_dependent_conflict($family_details, $policy_terms, $file['action'],$is_lgbtq);
|
||
|
||
|
||
return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => ['policy_terms' => $policy_terms['family_floaters'],'result' => $result] ], 200);
|
||
}
|
||
}
|
||
|
||
|
||
public function get_client_policy_list_for_remainder($client_id, $client_branch_id)
|
||
{
|
||
$policies = $this->clientPolicyModel
|
||
->select('client_policy.*, policy_type.policy_type as policy_name')
|
||
->join('policy_type', 'policy_type.id = client_policy.policy_type_id')
|
||
->where('client_policy.client_id', $client_id)
|
||
->where('client_policy.client_branch_id', $client_branch_id)
|
||
->where('client_policy.is_active', 1)
|
||
->where('client_policy.policy_status', 1)
|
||
->whereIn('client_policy.policy_type_id', [2, 3])
|
||
->findAll();
|
||
|
||
return $this->respond(['status' => true, 'code' => 200, 'data' => $policies], 200);
|
||
|
||
}
|
||
|
||
|
||
//-------- Edit individual employee and View & Send E-card -----------------------------------------------------------------------------------------
|
||
|
||
public function get_emp_master_data_for_update($id)
|
||
{
|
||
$employee_data = $this->employeeModel->select("employees.*, DATE_FORMAT(dob, '%d/%m/%Y') AS formatted_dob,")->where('id', $id)->first();
|
||
|
||
if ($employee_data) {
|
||
return $this->respond(['status' => true,'code' => 200,'data' => $employee_data,], 200);
|
||
} else {
|
||
return $this->respond(['status' => false, 'code' => 404, 'message' => 'No data found.'], 404);
|
||
}
|
||
}
|
||
|
||
//UPDATE EMPLOYEE
|
||
public function update_emp_data()
|
||
{
|
||
|
||
$rules = [
|
||
'email_corporate' => [
|
||
'rules' => 'required|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]',
|
||
'errors' => [
|
||
'required' => 'Email address is required.',
|
||
'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).'
|
||
]
|
||
],
|
||
'mobile' => [
|
||
'rules' => 'required|numeric|exact_length[10]',
|
||
'errors' => [
|
||
'required' => 'Mobile number is required',
|
||
'numeric' => 'Mobile number must contain digits only',
|
||
'exact_length' => 'Mobile number must be exactly 10 digits'
|
||
]
|
||
],
|
||
];
|
||
$request_post_data = $this->request->getPost();
|
||
$data = sanitizeInputArrayAdvanced($request_post_data);
|
||
if (isset($data['relationship'])) {
|
||
$rules['relationship'] = [
|
||
'rules' => 'required|in_list[Self,Spouse,Child,Father,Mother,Father-in-law,Mother-in-law]',
|
||
'errors' => [
|
||
'required' => 'Relationship is required',
|
||
'in_list' => 'The selected relationship is invalid.'
|
||
]
|
||
];
|
||
}
|
||
|
||
|
||
if (!$this->validate($rules)) {
|
||
return $this->response->setStatusCode(400)->setJSON([
|
||
'status' => false,
|
||
'message' => 'Input validation failed',
|
||
'code' => 400,
|
||
'errors' => $this->validator->getErrors()
|
||
]);
|
||
}
|
||
|
||
$employeeId = (int) ($data['employee_primary_id'] ?? 0);
|
||
if ($employeeId <= 0) {
|
||
return $this->respond(['status' => false, 'code' => 400, 'message' => 'Employee ID is required'], 400);
|
||
}
|
||
|
||
// Fetch current employee data
|
||
$employee_data = $this->employeeModel->where('id', $employeeId)->first();
|
||
if (!$employee_data) {
|
||
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Employee not found'], 404);
|
||
}
|
||
|
||
// Whitelist only editable fields from this form.
|
||
// name / gender / dob are disabled for active employees and may be absent from POST —
|
||
// only update them when the client actually sent a value (do not force null).
|
||
$updateData = [
|
||
'email_corporate' => $data['email_corporate'],
|
||
'mobile' => $data['mobile'],
|
||
];
|
||
|
||
if (!empty($data['name'])) {
|
||
$updateData['name'] = $data['name'];
|
||
}
|
||
if (isset($data['gender']) && $data['gender'] !== '') {
|
||
$updateData['gender'] = $data['gender'];
|
||
}
|
||
if (!empty($data['dob'])) {
|
||
$updateData['dob'] = change_date_format($data['dob'], null, 'Y-m-d');
|
||
}
|
||
if (isset($data['relationship'])) {
|
||
$updateData['relationship'] = $data['relationship'];
|
||
}
|
||
|
||
if ($employee_data['relationship'] == 'Self' && isset($updateData['gender'])) {
|
||
if ($employee_data['gender'] != $updateData['gender']) {
|
||
$spouse_gender = ($updateData['gender'] == 'M') ? 'F' : 'M';
|
||
$this->employeeModel
|
||
->where('emp_code', $employee_data['emp_code'])
|
||
->where('relationship', 'Spouse')
|
||
->set(['gender' => $spouse_gender])
|
||
->update();
|
||
}
|
||
}
|
||
|
||
// Update the employee data
|
||
$result = $this->employeeModel->where('id', $employeeId)->set($updateData)->update();
|
||
|
||
if ($result) {
|
||
return $this->respond(['status' => true, 'code' => 200, 'data' => $updateData, 'message' => 'Employee updated successfully'], 200);
|
||
} else {
|
||
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Failed to update employee.'], 404);
|
||
}
|
||
}
|
||
|
||
public function send_mail_for_individual_employee_ecard($id, $client_policy_id)
|
||
{
|
||
$ids[] = $id;
|
||
$empDataServiceController = new EmpDataServiceController();
|
||
$result = $empDataServiceController->sendMailForDownloadingECard(['ids' => $ids, 'client_policy_id' => $client_policy_id], 1);
|
||
|
||
if (isset($result['status']) && $result['status'] == true) {
|
||
return $this->respond(['status' => true,'code' => 200,'message' => 'Mail sent successfully', 'result' => $result], 200);
|
||
} else {
|
||
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Failed to sent mail.', 'result' => $result], 200);
|
||
}
|
||
}
|
||
|
||
public function checkDeletionGetDataFunction()
|
||
{
|
||
// $batch_data = [
|
||
// 'client_id' => 159,
|
||
// 'client_policy_id' => 336,
|
||
// 'client_branch_id' => 126,
|
||
// ];
|
||
|
||
// $batch_data['insurer_or_tpa'] = 'insurer';
|
||
// $batch_data['insurer_or_tpa'] = 'tpa';
|
||
|
||
//INCEPTION
|
||
// $result = $this->employeePolicyModel->getInceptionEmployeeDataForExportExcel($batch_data);
|
||
|
||
// CORRECTION
|
||
// $result = $this->employeePolicyModel->getCorrectionEmployeesDataForExportExcel($batch_data);
|
||
|
||
//SI-ENHANCEMENT
|
||
// $result = $this->employeePolicyModel->getSIEnhancementEmployeesDataForExportExcel($batch_data);
|
||
|
||
//DELETION
|
||
// $result = $this->employeePolicyModel->getDeletionEmployeeDataForExportExcel($batch_data);
|
||
|
||
// print_rr($result); die;
|
||
|
||
//-------------------------------------------------------------------------------------------------------------
|
||
|
||
// $ids = [
|
||
// 'employeeIds' => [20252, 20258, 20277, 20282, 20196, 20237, 20314, 20325, 20356],
|
||
// 'client_id' => 17,
|
||
// 'client_policy_id' => 30,
|
||
// 'client_branch_id' => 18,
|
||
// 'cd_ac_no' => $CD_Account_Number['cd_ac_no'] ?? null,
|
||
// 'endorsement_no' => $endorsement_id ?? null,
|
||
// 'count' => 9,
|
||
// // 'event_name' => $file['event_type'],
|
||
// // 'policy_name' => $policy_name['policy_name'],
|
||
// // 'user_id' => $user_id,
|
||
// ];
|
||
// $empDataServiceController = new EmpDataServiceController();
|
||
// $result = $empDataServiceController->cashDepositCalculationForDeletion($ids);
|
||
|
||
}
|
||
|
||
// ---------- DOWNLOAD IMPORT BATCH FILE AND SAMPLE FILE ------------------------------------------------------------------------------------------------
|
||
|
||
public function downloadSampleImportExcelFile($actionType = null)
|
||
{
|
||
// $actionType = $this->request->getGet();
|
||
$filePath = '';
|
||
// Path to your file
|
||
if ($actionType == 'inception') {
|
||
$filePath = ROOTPATH . 'public/sample_import_excel/sample_import_Inception.xlsx';
|
||
} else if ($actionType == 'correction') {
|
||
$filePath = ROOTPATH . 'public/sample_import_excel/sample_import_correction.xlsx';
|
||
} else if ($actionType == 'si_enhancement') {
|
||
$filePath = ROOTPATH . 'public/sample_import_excel/sample_import_SI_Enhancement.xlsx';
|
||
} else if ($actionType == 'dependent_addition') {
|
||
$filePath = ROOTPATH . 'public/sample_import_excel/sample_import_Dependent_Addition.xlsx';
|
||
} else if ($actionType == 'addition') {
|
||
$filePath = ROOTPATH . 'public/sample_import_excel/sample_import_Addition.xlsx';
|
||
} else if ($actionType == 'deletion') {
|
||
$filePath = ROOTPATH . 'public/sample_import_excel/sample_import_Deletion.xlsx';
|
||
}else if ($actionType == 'missed_inception') {
|
||
$filePath = ROOTPATH . 'public/sample_import_excel/sample_import_Addition.xlsx';
|
||
}
|
||
|
||
// Check if the file exists
|
||
if (file_exists($filePath)) {
|
||
|
||
// Set the appropriate MIME type
|
||
$mimeType = mime_content_type($filePath);
|
||
|
||
// Send the file to the client for download
|
||
return $this->response->download($filePath, null, $mimeType);
|
||
} else {
|
||
// File not found, show an error message or redirect
|
||
echo view('errors/html/production');
|
||
}
|
||
}
|
||
|
||
public function download_import_file($file_id)
|
||
{
|
||
$file_data = $this->batchFileModel->where('id', $file_id)->first();
|
||
if (empty($file_data) || empty($file_data['file_name'])) {
|
||
$data['message'] = 'File record not found';
|
||
return view('errors/404', $data);
|
||
}
|
||
|
||
$fileName = basename((string) $file_data['file_name']);
|
||
$storage = \Config\Services::getFileStorageService();
|
||
$result = $storage->download(WRITEPATH . 'uploads/import_excel', $fileName);
|
||
|
||
try {
|
||
if ($result['success'] ?? false) {
|
||
$downloadAs = storage_upload_display_name($fileName);
|
||
if (! empty($result['path']) && is_file($result['path'])) {
|
||
return $this->response->download($result['path'], null)->setFileName($downloadAs);
|
||
}
|
||
if (! empty($result['content'])) {
|
||
return $this->response->download($downloadAs, $result['content'])->setFileName($downloadAs);
|
||
}
|
||
}
|
||
|
||
$data['message'] = 'The Physical File Not Found';
|
||
return view('errors/404', $data);
|
||
} catch (\Exception $e) {
|
||
$this->myLogger->logme('error', $e->getMessage());
|
||
echo $e->getMessage();
|
||
}
|
||
}
|
||
|
||
//--------- LOG FILE VIEW AND DOWNLOAD ---------------------------------------------------------------------------------------------
|
||
|
||
public function listLogs()
|
||
{
|
||
$logPath = WRITEPATH . 'logs/';
|
||
$logs = [];
|
||
|
||
// Check if the log directory exists
|
||
if (is_dir($logPath)) {
|
||
$files = array_diff(scandir($logPath), ['.', '..']); // Exclude '.' and '..'
|
||
|
||
$files = array_reverse($files);
|
||
|
||
foreach ($files as $file) {
|
||
if (is_file($logPath . $file)) {
|
||
$logs[] = $file; // Add log files to the list
|
||
}
|
||
}
|
||
}
|
||
|
||
$data['logs'] = $logs;
|
||
$data['server_details'] = get_server_details();
|
||
|
||
// Pass log files to the view
|
||
return $this->loadLayout('log_view', $data);
|
||
}
|
||
|
||
public function downloadLog($fileName)
|
||
{
|
||
$logPath = WRITEPATH . 'logs/' . $fileName;
|
||
|
||
// Check if the requested file exists
|
||
if (file_exists($logPath)) {
|
||
return $this->response->download($logPath, null)->setFileName($fileName);
|
||
}
|
||
|
||
// Redirect back with an error if file doesn't exist
|
||
return redirect()->back()->with('error', 'Log file not found.');
|
||
}
|
||
|
||
public function viewLog($fileName)
|
||
{
|
||
$logPath = WRITEPATH . 'logs/' . $fileName;
|
||
|
||
if (file_exists($logPath)) {
|
||
$content = file_get_contents($logPath);
|
||
|
||
$data['fileName'] = $fileName;
|
||
$data['content'] = $content;
|
||
$data['server_details'] = get_server_details();
|
||
|
||
return $this->loadLayout('log_content_view', $data);
|
||
}
|
||
|
||
return redirect()->back()->with('error', 'Log file not found.');
|
||
}
|
||
|
||
public function exportToExceltpadata()
|
||
{
|
||
// Create a new Spreadsheet
|
||
$spreadsheet = new Spreadsheet();
|
||
$sheet = $spreadsheet->getActiveSheet();
|
||
|
||
// Header row
|
||
$headers = [
|
||
'TPA_NAME', 'SHORT_NAME', 'TPA_BRANCH_NAME', 'TPA_BRANCH_CODE',
|
||
'TPA_CONTACT_PERSON_NAME', 'TPA_CONTACT_PERSON_EMAIL', 'TPA_CONTACT_PERSON_MOBILE',
|
||
'TPA_CONTACT_PERSON_DESIGNATION', 'IS_DELETED'
|
||
];
|
||
$sheet->fromArray($headers, NULL, 'A1');
|
||
|
||
// Data rows
|
||
$data = [
|
||
["ICICI Lombard Health Care", "IL Health care", "Chennai", "997133", "Heena", "dharanisri@jubiliant.in", "9043955294", "General Manager", "YES"],
|
||
["ICICI Lombard Health Care", "IL Health care", "Chennai", "997133", "Mahammad shireen", "mahammad.shireen@icicilombard.com", "8655420732", "Claims head", "NO"],
|
||
["Medi Assist Insurance TPA Private Limited", "Medi Assist", "Chennai", "YA0000000348", "Ragavi", "dharanisri@jubiliant.in", "9043955294", "Senior Manager", "YES"],
|
||
["Medi Assist Insurance TPA Private Limited", "Medi Assist", "Chennai", "YA0000000348", "Vijayalakshmi", "vijayalakshmi.c@mediassist.in", "7795542162", "Senior Executive | Account Management", "NO"],
|
||
["Vidal Health Insurance TPA", "Vidal", "Chennai", "YA0000000349", "vijalakshmi", "vijayalakshmi.c@mediassist.in", "7795542162", "Senior Executive", "NO"],
|
||
["Vidal Health Insurance TPA", "Vidal", "Chennai", "YA0000000349", "M.Pushparaj", "pushparaj.moorthy@vidalhealth.com", "8939634456", "Executive", "NO"],
|
||
["Digit in-House", "Digit in-House", "Go Digit General Insurance Ltd", "1", "sathish", "sathish.n@vidalhealth.com", "7823913800", "Senior Executive", "NO"],
|
||
["Digit in-House", "Digit in-House", "Go Digit General Insurance Ltd", "1", "Mr. Pavan", "TK.Pavankumar@godigit.com", "8754490492", "Strategic Partnerships", "NO"],
|
||
["Aditya Birla Health Insurance Co. Limited", "ABHI", "Chennai", "O1", "sathish", "sathish.n@vidalhealth.com", "7823913800", "Senior Executive", "NO"],
|
||
["Aditya Birla Health Insurance Co. Limited", "ABHI", "Chennai", "O1", "Jhonson Kj", "jhonson.kj@adityabirlacapital.com", "9900729513", "Executive", "NO"],
|
||
["Aditya Birla Health Insurance Co. Limited", "ABHI", "Chennai", "01", "Jhonson Kj", "jhonson.kj@adityabirlacapital.com", "9900729513", "Executive", "NO"],
|
||
["R Care Health", "R Care", "Chennai", "01", "Jeevanadam", "Jeevanandam.Kumaran@relianceada.com", "8825982053", "Executive", "NO"],
|
||
["IFFCO-TOKIO GENERAL INSURANCE CO. LTD", "ITGI", "Chennai", "01", "Anjali", "Anjali.K@ext.iffcotokio.co.in", "6374270165", "Senior Executive", "NO"],
|
||
["Star Health and Allied Insurance", "STAR", "Chennai", "110000", "Mr. Vijay Baskar", "vijayabhaskar.m@starhealth.in", "9840905286", "Area Manager", "NO"],
|
||
];
|
||
$sheet->fromArray($data, NULL, 'A2');
|
||
|
||
// Save the file
|
||
$filename = 'TPA_Data.xlsx';
|
||
$writer = new Xlsx($spreadsheet);
|
||
|
||
// Set headers for download
|
||
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;
|
||
}
|
||
|
||
//------------------------------------------------------------------------------------------------------
|
||
|
||
|
||
public function test_members_list(){
|
||
// $model = new EmployeeModel();
|
||
// $list = [
|
||
// ['relationship' => 'spouse','emp_code' => 'TEST002', 'name' => 'Lakshmi','email_personal' => 'lakshmi@gmail.com','mobile'=>'6382156701','gender'=>'female','dob'=>'1996-05-19','doj'=>'2022-02-01','basic_pay'=>'100000','emp_status'=>'enrolled'],
|
||
// ['relationship' => 'Daughter','emp_code' => 'TEST002', 'name' => 'Jayalakshmi','email_personal' => 'jayalakshmi@gmail.com','mobile'=>'6382156701','gender'=>'female','dob'=>'2018-05-19','doj'=>'2022-02-01','basic_pay'=>'100000','emp_status'=>'enrolled'],
|
||
// ['relationship' => 'Son','emp_code' => 'TEST002', 'name' => 'Jayam Ravi','email_personal' => 'jayamravi@gmail.com','mobile'=>'6382156701','gender'=>'male','dob'=>'1994-05-19','doj'=>'2019-02-01','basic_pay'=>'100000','emp_status'=>'enrolled'],
|
||
// // ['relationship' => 'self','emp_code' => 'TEST003', 'name' => 'Ravi Shankar','email_personal' => 'srinivassaravanan2002@gmail.com','email_corporate'=>'srinivas.saravanan@venbainfotech.com','mobile'=>'6382156701','gender'=>'male','dob'=>'1994-05-19','doj'=>'2022-02-01','basic_pay'=>'100000','emp_status'=>'enrolled']
|
||
// ['relationship' => 'spouse','emp_code' => 'TEST001', 'name' => 'Lakshmi','email_personal' => 'lakshmi@gmail.com','mobile'=>'6382156701','gender'=>'female','dob'=>'1996-05-19','doj'=>'2022-02-01','basic_pay'=>'100000','emp_status'=>'enrolled'],
|
||
|
||
// ];
|
||
// foreach($list as $listitem){
|
||
|
||
|
||
// $model->insert($listitem);
|
||
// }
|
||
// die();
|
||
$employee_data = $this->employeeModel->getTestEmployeeData();
|
||
$data['employees'] = $employee_data;
|
||
$data['clients'] = $this->clientModel->findAll();
|
||
// dd($data);
|
||
$data['tab_name'] = "Employees";
|
||
$data['page_name'] = "Employees";
|
||
|
||
return $this->loadLayout('test_members_list',$data);
|
||
}
|
||
|
||
public function mapEmployees(){
|
||
$request_post_data = $this->request->getPost();
|
||
$sanitized_post_data = sanitizeInputArrayAdvanced($request_post_data);
|
||
|
||
$client_id = $sanitized_post_data['client_id'] ?? null;
|
||
$branch_id = $sanitized_post_data['branch_id'] ?? null;
|
||
$policy_id = $sanitized_post_data['client_policy_id'] ?? null;
|
||
$selected_employees = (array)$sanitized_post_data['selected'] ?? [];
|
||
$si_amt = $sanitized_post_data['si_amt'] ?? null;
|
||
$policy_start_date_unformatted = $sanitized_post_data['policy_start_date'] ?? null;
|
||
|
||
$policy_start_date = change_date_format($policy_start_date_unformatted, 'd/M/Y', 'Y-m-d');
|
||
|
||
$data1 = [
|
||
'client_id' => $client_id,
|
||
'client_branch_id' => $branch_id,
|
||
];
|
||
$data2 = [
|
||
'client_policy_id' => $policy_id,
|
||
'status' => 'draft',
|
||
'date_coverage' => $policy_start_date,
|
||
'basic_cover_si' => $si_amt,
|
||
|
||
];
|
||
|
||
for($i = 0; $i < count($selected_employees); $i++){
|
||
$data2['employee_id'] = $selected_employees[$i];
|
||
$result1 = $this->employeeModel->set($data1)->where('id',$selected_employees[$i])->update();
|
||
$result2 = $this->employeePolicyModel->insert($data2);
|
||
}
|
||
if ($result1 && $result2) {
|
||
return $this->respond(['status' => true, 'code' => 200, 'message' => 'Employees mapped successfully'], 200);
|
||
} else {
|
||
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Failed to map employees.'], 404);
|
||
}
|
||
}
|
||
|
||
public function getDataForMapping(){
|
||
$policy_id = $this->request->getPost('policy_id');log_message('error',$policy_id);
|
||
$data['policy_start_date'] = $this->clientPolicyModel->select('policy_start_date')->where('id',$policy_id)->first()['policy_start_date'];
|
||
$data['si_amt'] = $this->PolicyPremium2Model->select('si')->where('client_policy_id', $policy_id)->groupBy('si')->findAll();
|
||
log_message('error',json_encode($data).'policy id '.$policy_id);
|
||
return $this->respond(['status' => true, 'code' => 200, 'data' => $data], 200);
|
||
}
|
||
|
||
public function unmapEmployees($actionType){
|
||
$request_post_data = $this->request->getPost();
|
||
$sanitized_post_data = sanitizeInputArrayAdvanced($request_post_data);
|
||
$selected_employees = (array)$sanitized_post_data['selected'] ?? [];
|
||
if($actionType == 0){
|
||
for($i = 0;$i<count($selected_employees);$i++){log_message('error',$selected_employees[$i]);
|
||
$result1 = $this->employeeModel->set(['client_id' => null, 'client_branch_id' => null])->where('id',$selected_employees[$i])->update();log_message('error',$result1);
|
||
$result2 = $this->employeePolicyModel->where('employee_id',$selected_employees[$i])->delete();log_message('error',$result2);
|
||
}
|
||
}
|
||
else if ($actionType == 1){
|
||
for($i = 0;$i<count($selected_employees);$i++){
|
||
log_message('error','Emp id is '.$selected_employees[$i]);
|
||
$result1 = $this->employeeModel->set(['client_id' => null, 'client_branch_id' => null])->where('id',$selected_employees[$i])->update();log_message('error','result 1 is '.$result1);
|
||
$result2 = $this->employeePolicyModel->where('employee_id',$selected_employees[$i])->delete();log_message('error', 'result 2 is '.$result2);
|
||
$emp_code = $this->employeeModel->select('emp_code')->where('id',$selected_employees[$i])->first()['emp_code'];log_message('error','emp_code is '.$emp_code);
|
||
$result3 = $this->employeeModel->where('emp_code',$emp_code)->whereNotIn('relationship',['self'])->delete();log_message('error','result 3 is '.$result3);
|
||
}
|
||
}
|
||
else{
|
||
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Invalid action type.'], 404);
|
||
}
|
||
if($actionType == 1){
|
||
if($result1 && $result2 && $result3){
|
||
return $this->respond(['status' => true, 'code' => 200, 'message' => 'Employees unmapped successfully and Dependencies are Deleted'], 200);
|
||
}
|
||
else{
|
||
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Failed to unmap employees.'], 404);
|
||
}
|
||
}else{
|
||
if($result1 && $result2 ){
|
||
return $this->respond(['status' => true, 'code' => 200, 'message' => 'Employees unmapped successfully'], 200);
|
||
}
|
||
else{
|
||
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Failed to unmap employees.'], 404);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
public function cloneWorksheet()
|
||
{
|
||
// Define file paths
|
||
$inputFilePath = 'C:\Users\Venba\Downloads/merge1.xlsx'; // Path to the existing file
|
||
$outputFilePath = WRITEPATH . '/tmp/cloned_file.xlsx'; // Path to save the new file
|
||
|
||
try {
|
||
// Load the existing spreadsheet
|
||
$spreadsheet = IOFactory::load($inputFilePath);
|
||
|
||
// Get the first worksheet (or specify the index of the sheet to clone)
|
||
$originalWorksheet = $spreadsheet->getSheet(0);
|
||
|
||
// Clone the worksheet
|
||
$clonedWorksheet = clone $originalWorksheet;
|
||
|
||
// Generate a unique name for the cloned worksheet
|
||
$baseName = "Cloned Sheet";
|
||
$sheetIndex = 1;
|
||
$uniqueName = $baseName;
|
||
|
||
// Check for duplicate names and generate a unique one
|
||
while ($spreadsheet->sheetNameExists($uniqueName)) {
|
||
$uniqueName = $baseName . " " . $sheetIndex;
|
||
$sheetIndex++;
|
||
}
|
||
|
||
// Set the unique name for the cloned worksheet
|
||
$clonedWorksheet->setTitle($uniqueName);
|
||
|
||
// Add the cloned worksheet to the spreadsheet
|
||
$spreadsheet->addSheet($clonedWorksheet);
|
||
|
||
// Modify the cloned sheet (optional)
|
||
$clonedWorksheet->setCellValue('A1', 'Hello, Cloned Sheet!');
|
||
|
||
// Save the modified spreadsheet to a new file
|
||
$writer = new Xlsx($spreadsheet);
|
||
$writer->save($outputFilePath);
|
||
|
||
return $this->response->setJSON([
|
||
'status' => 'success',
|
||
'message' => 'Spreadsheet with cloned sheet created successfully!',
|
||
'file_path' => $outputFilePath,
|
||
]);
|
||
} catch (\Exception $e) {
|
||
// Handle exceptions
|
||
return $this->response->setJSON([
|
||
'status' => 'error',
|
||
'message' => $e->getMessage(),
|
||
]);
|
||
}
|
||
}
|
||
|
||
//------------------------------------------------------------------------------------------------------
|
||
|
||
|
||
public function generateAcmAndMForEcard($client_id)
|
||
{
|
||
$db = db_connect();
|
||
$builder = $db->table('client_rm');
|
||
$builder->select('user_profiles.first_name, user_profiles.mobile, user_profiles.email, client_rm.level');
|
||
$builder->join('user_profiles', 'client_rm.user_id = user_profiles.id');
|
||
$builder->where('client_rm.client_id', $client_id);
|
||
$builder->whereIn('client_rm.level', [2, 3]);
|
||
$builder->where('client_rm.is_active', 1);
|
||
$builder->orderBy('client_rm.level', 'desc');
|
||
$query = $builder->get();
|
||
$result = $query->getResultArray();
|
||
|
||
$levels = [
|
||
3 => [],
|
||
2 => []
|
||
];
|
||
|
||
foreach ($result as $value) {
|
||
$levels[$value['level']][] = $value;
|
||
}
|
||
|
||
// Generate the HTML content
|
||
$html = '';
|
||
|
||
$level_index = 1;
|
||
foreach ($levels as $level => $contacts) {
|
||
$displayLevel = $level == 3 ? 1 : 2; // Switch levels for display
|
||
if($level_index == 1){
|
||
$html .= 'Level ' . $displayLevel . '<br>';
|
||
}else{
|
||
$html .= '<br> Level ' . $displayLevel . '<br>';
|
||
}
|
||
foreach ($contacts as $index => $contact) {
|
||
$html .= ($index + 1) . '. ' . $contact['first_name'] . ' / ' . $contact['mobile'] . ' / ' . $contact['email'] . '<br>';
|
||
}
|
||
$level_index++;
|
||
}
|
||
|
||
$html .= '<br>';
|
||
|
||
return $html;
|
||
}
|
||
|
||
public function generateNetworkHospitalsForEcard($network_hospitals)
|
||
{
|
||
$html = "";
|
||
if (!empty($network_hospitals)) {
|
||
$html = '<div style="margin-top: 6px;">
|
||
<span style="font-weight: 500;">Network Hospital:</span>
|
||
<a href="' . $network_hospitals . '" target="_blank" style="color: #0066cc; text-decoration: none; display: inline-block; max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom;">' . $network_hospitals . '</a>
|
||
</div>';
|
||
}
|
||
|
||
// For debugging
|
||
// print_r($html); die;
|
||
|
||
return $html;
|
||
}
|
||
|
||
|
||
public function getBatchFileData()
|
||
{
|
||
$file_id = $this->request->getGet('file_id');
|
||
|
||
if(!empty($file_id)){
|
||
|
||
|
||
$batch_file_data = $this->batchFileModel
|
||
->where('id', $file_id)
|
||
->where('is_active', 1)
|
||
->first();
|
||
|
||
if(!empty($batch_file_data)){
|
||
return $this->respond(['status' => true, 'code' => 200, 'batch_file_data' => $batch_file_data], 200);
|
||
}else{
|
||
return $this->respond(['status' => false, 'code' => 200, 'message' => 'No data found.'], 200);
|
||
}
|
||
|
||
}else{
|
||
return $this->respond(['status' => false, 'code' => 404, 'message' => 'No data to found. File ID Not found'], 200);
|
||
}
|
||
}
|
||
|
||
public function getEmpHistory(){
|
||
|
||
$emp_id = $this->request->getPost('emp_id');
|
||
|
||
$data['emp_history'] = $this->auditHistory->select('field_name,old_value,new_value,created_by,created_at')->where('pk',$emp_id)->where('table_name','employees')->orderBy('created_at', 'DESC')->findAll();
|
||
|
||
foreach ($data['emp_history'] as &$emp_history) {
|
||
$emp_history['field_name'] = $this->formatFieldName($emp_history['field_name']);
|
||
$user = $emp_history['created_by'];
|
||
if ($user != null && $user != ''){
|
||
$userData = $this->userModel->select('first_name, last_name')->where('id', $user)->where('is_active', 1)->first();
|
||
$emp_history['created_by'] = ucwords($userData['first_name'] . ' ' . $userData['last_name']);
|
||
}else{
|
||
$emp_history['created_by'] = '-';
|
||
}
|
||
|
||
$emp_history['created_at'] = date("d-m-Y H:i:s", strtotime($emp_history['created_at']));
|
||
}
|
||
unset($emp_history);
|
||
|
||
$emp_pol_pk = $this->employeePolicyModel->select('id')->where('employee_id',$emp_id)->first()['id'];
|
||
$data['emp_pol_history'] = $this->auditHistory->select('field_name,old_value,new_value,created_by,created_at')->where('pk',$emp_pol_pk)->where('table_name','employee_polices')->findAll();
|
||
|
||
return $this->respond(['status' => true, 'data' => $data],200);
|
||
|
||
|
||
}
|
||
|
||
public function formatFieldName($unformattedString){
|
||
|
||
if (str_contains($unformattedString, '_')) {
|
||
$data = str_replace('_', ' ', $unformattedString);
|
||
}else{
|
||
$data = $unformattedString;
|
||
}
|
||
|
||
$format = ucwords($data);
|
||
|
||
return $format;
|
||
|
||
}
|
||
|
||
/**
|
||
* Below function displays the endorsement list page.
|
||
*
|
||
* This method retrieves filter data from the request and fetches the endorsement list
|
||
* based on the provided filters such as client ID, policy ID, and status.
|
||
*/
|
||
public function retailendorsementlist()
|
||
{
|
||
|
||
$data = [];
|
||
$data['status'] = ['open' => 'Open', 'inprogress' => 'In-Progress', 'complete' => 'Complete'];
|
||
$data['client'] = $this->clientModel->select('clients.id,client_name,short_name')
|
||
->where('clients.is_active',1)
|
||
->where('clients.client_type',2)
|
||
->findAll();
|
||
$data['insurer'] = $this->insurerModel->select('insurers.id,name,short_name')
|
||
->where('insurers.is_active',1)
|
||
->findAll();
|
||
// if (count($this->request->getGet())) {
|
||
$filterData = $this->request->getGet();
|
||
$data['employees'] = $this->partnerEndorsementRequestModel->getRetailEndorsementList(
|
||
client_id: $filterData['client_id'] ?? null,
|
||
insurers_id: $filterData['insurer_id'] ?? null,
|
||
status: $filterData['status'] ?? null
|
||
);
|
||
|
||
$data['getData'] = $filterData;
|
||
// echo "<pre>";
|
||
// print_r($data); die;
|
||
// }
|
||
|
||
$data['tab_name'] = "Retail Endorsement";
|
||
$data['page_name'] = "Retail Endorsement";
|
||
|
||
$this->loadLayout('retail_endorsement_list', $data);
|
||
}
|
||
|
||
public function retailendorsementsave()
|
||
{
|
||
try {
|
||
$rules = [
|
||
'endorsement_no' => [
|
||
'rules' => 'required|regex_match[/^[a-zA-Z0-9\/_\-]+$/]',
|
||
'errors' => [
|
||
'required' => 'Endorsement Number is missing.',
|
||
'regex_match' => 'Endorsement Number can only contain letters, numbers, slashes (/), underscores (_), and hyphens (-).'
|
||
]
|
||
],
|
||
'status' => [
|
||
'rules' => 'required',
|
||
'errors' => [
|
||
'required' => 'Status is required',
|
||
]
|
||
]
|
||
];
|
||
if (!$this->validate($rules)) {
|
||
return $this->response->setStatusCode(400)->setJSON([
|
||
'status' => false,
|
||
'message' => 'Input validation failed',
|
||
'code' => 400,
|
||
'errors' => $this->validator->getErrors()
|
||
]);
|
||
}
|
||
$request_post_data = $this->request->getPost();
|
||
$data = sanitizeInputArrayAdvanced($request_post_data);
|
||
|
||
if (!empty($data['id'])) {
|
||
$text = "update";
|
||
$updateID = $data['id'];
|
||
$result = $this->partnerEndorsementRequestModel->where('id', $updateID)->set($data)->update();
|
||
} else {
|
||
$text = "create";
|
||
$data['created_by'] = get_session_userid();
|
||
$thzMasterModel = new ThzMasterModel();
|
||
$thzMasterModel->insert($data);
|
||
$insertID = $this->partnerEndorsementRequestModel->insertID();
|
||
$result = true;
|
||
}
|
||
|
||
$id = isset($insertID) && !empty($insertID) ? $insertID : $updateID;
|
||
|
||
return $this->response->setJSON([
|
||
'status' => $result ? 'success' : 'error',
|
||
'message' => $result ? "Partner Endorsement Request {$text}d successfully " : "Unable to {$text} Partner Endorsement Request. Please try again.",
|
||
])->setStatusCode($result ? 200 : 400);
|
||
} catch (\Throwable $e) {
|
||
$code = ($e->getCode() && $e->getCode() >= 100 && $e->getCode() < 600) ? $e->getCode() : 500;
|
||
|
||
$isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|
||
|| $e instanceof \mysqli_sql_exception
|
||
|| $e instanceof \PDOException;
|
||
|
||
$context = ['title' => get_class($e), 'type' => get_class($e), 'code' => $code, 'message' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine()];
|
||
|
||
$this->myLogger->logme('error', "Exception: {message} in {file} on line {line}", $context, 0);
|
||
|
||
return $this->response->setJSON([
|
||
'status' => 'error',
|
||
'message' => $isDbError ? 'Data Access Error' : $e->getMessage(),
|
||
'ref' => $isDbError ? 'database - ' : 'application - ' . $code . ' - ' . $e->getLine()
|
||
])->setStatusCode($code);
|
||
}
|
||
}
|
||
|
||
// function for skip the Inception and Member data validation
|
||
public function proceedExcelFileDataValidation()
|
||
{
|
||
$file_id = $this->request->getGet('file_id');
|
||
$not_skiped = $this->request->getGet('not_skiped') ?? null;
|
||
$this->myLogger->logme('error', json_encode($this->request->getGet() ?? []));
|
||
|
||
|
||
if(!empty($not_skiped)){
|
||
$file_model = new FileModel();
|
||
$file_model->where('id', $file_id)->set(['is_comparison_skipped' => 0])->update();
|
||
$message = "Inception and Member data comparision continuted by the user id : " . get_session_userid();
|
||
$this->myLogger->logme('error', $message);
|
||
return $this->respond(['status' => true, 'code' => 200, 'message' => 'Inception and Member data comparision continued'], 200);
|
||
}
|
||
|
||
if(!empty($file_id)){
|
||
|
||
$r = Jobs::addJob(['job_name' => 'excelFileDataValidation','payload' => ['file_id' => $file_id]]);
|
||
$message = "Inception and Member data comparision skiped successfully by the user id : " . get_session_userid();
|
||
$this->myLogger->logme('error', $message);
|
||
|
||
$file_model = new FileModel();
|
||
$file_model->where('id', $file_id)->set(['is_comparison_skipped' => 1])->update();
|
||
|
||
$policy_id = $this->request->getGet('policy_id') ?? null;
|
||
|
||
if ($policy_id) {
|
||
|
||
$client_policy_data = $this->clientPolicyModel->where('id', $policy_id)->first();
|
||
|
||
if (!empty($client_policy_data) && isset($client_policy_data['is_from_lead'])) {
|
||
$lead_id = $client_policy_data['is_from_lead'];
|
||
|
||
if (!empty($lead_id)) {
|
||
$lead_model = new LeadsModel();
|
||
$lead_model->where('id', $lead_id)->set(['policy_with_correction' => 1])->update();
|
||
} else {
|
||
$this->myLogger->logme('error', 'Lead ID missing for policy ID: ' . $policy_id);
|
||
}
|
||
} else {
|
||
$this->myLogger->logme('error', 'No client policy data found for policy ID: ' . $policy_id);
|
||
}
|
||
} else {
|
||
$this->myLogger->logme('error', 'Policy ID not provided in GET request.');
|
||
}
|
||
|
||
return $this->respond(['status' => true, 'code' => 200, 'message' => 'Inception and Member data comparision skiped successfully!'], 200);
|
||
}else{
|
||
return $this->respond(['status' => false, 'code' => 500, 'message' => 'Failed to skip the comparison!'], 200);
|
||
}
|
||
}
|
||
|
||
|
||
public function checkWellnessOnboardStatus($client_policy_id)
|
||
{
|
||
|
||
|
||
$fetch_onboarded_employees = $this->request->getGet('fetch_onboarded_employees') ?? false;
|
||
|
||
if($fetch_onboarded_employees){
|
||
$data = $this->employeePolicyModel->select('employee_polices.*')
|
||
->where('employee_polices.is_active', 1)
|
||
->where('employee_polices.status', 'active')
|
||
->where('employee_polices.client_policy_id', $client_policy_id)
|
||
->where('employee_polices.wellness_onboard !=', '0')
|
||
->findAll();
|
||
return $this->respond(['status' => true, 'code' => 200, 'data' => count($data)], 200);
|
||
}
|
||
|
||
|
||
// echo $client_policy_id;die();
|
||
$data = $this->employeePolicyModel->select('employee_polices.*,emp.name,emp.relationship,emp.emp_code,emp.name,emp.email_corporate,emp.mobile,emp.dob,cp.policy_no,cp.wellness_plan_id,cp.wellness_vendor_id,cp.policy_start_date as cp_policy_start_date,cp.policy_end_date,cls.short_name')
|
||
->join('client_policy cp', 'cp.id = employee_polices.client_policy_id')
|
||
->join('clients cls', "cp.client_id = cls.id")
|
||
->join('employees emp', "emp.id = employee_polices.employee_id")
|
||
->where('employee_polices.is_active', 1)
|
||
->where('employee_polices.status', 'active')
|
||
->where('employee_polices.client_policy_id', $client_policy_id)
|
||
// ->where('employee_polices.tpa_id is not null')
|
||
->where('employee_polices.wellness_onboard', '0')
|
||
->where('emp.emp_status', 'active')
|
||
->where('emp.is_active', 1)
|
||
->groupStart()
|
||
->orwhere('cp.wellness_plan_id IS NOT NULL', null, false)
|
||
->orWhere('cp.wellness_plan_id !=', '')
|
||
->orWhere('cp.wellness_plan_id !=', 0)
|
||
->groupEnd()
|
||
->groupStart()
|
||
->orwhere('cp.wellness_vendor_id IS NULL', null, false)
|
||
->orWhere('cp.wellness_vendor_id =', '')
|
||
->orWhere('cp.wellness_vendor_id =', 0)
|
||
->groupEnd()
|
||
->where('cp.policy_status',1)
|
||
->where('cp.is_active',1)
|
||
->findAll();
|
||
// echo count($data);die();
|
||
// if(is_array($data) && count($data))
|
||
// {
|
||
return $this->respond(['status' => true, 'code' => 200, 'data' => count($data)], 200);
|
||
// }
|
||
// return $this->respond(['status' => true, 'code' => 200, 'message' => 'Inception and Member data comparision skiped successfully!'], 200);
|
||
}
|
||
|
||
public function initiateWellnessOnboard($client_policy_id, $emp_code = null)
|
||
{
|
||
$r = Jobs::addJob(['job_name' => 'initiateWellnessOnboardJob','payload' => ['client_policy_id' => $client_policy_id, 'emp_code' => $emp_code ?? null ]]);
|
||
// $this->initiateWellnessOnboardJob(['client_policy_id' => $client_policy_id]);
|
||
return $this->respond(['status' => true, 'code' => 200, 'message' => 'Process started'], 200);
|
||
}
|
||
|
||
public function initiateWellnessOnboardJobOLD($arr)
|
||
{
|
||
|
||
$client_policy_id = $arr['client_policy_id'];
|
||
|
||
$page = max(1, (int)($arr['page'] ?? 1));
|
||
$perPage = max(1, (int)($arr['per_page'] ?? 50));
|
||
$offset = ($page - 1) * $perPage;
|
||
$data = $this->employeePolicyModel->select('employee_polices.*,emp.name,emp.relationship,emp.emp_code,emp.name,emp.email_corporate,emp.mobile,emp.dob,cp.policy_no,cp.wellness_plan_id,cp.wellness_vendor_id,cp.policy_start_date as cp_policy_start_date,cp.policy_end_date,cls.short_name,emp.gender')
|
||
->join('client_policy cp', 'cp.id = employee_polices.client_policy_id')
|
||
->join('clients cls', "cp.client_id = cls.id")
|
||
->join('employees emp', "emp.id = employee_polices.employee_id")
|
||
->where('employee_polices.is_active', 1)
|
||
->where('employee_polices.status', 'active')
|
||
->where('employee_polices.client_policy_id', $client_policy_id)
|
||
// ->where('employee_polices.tpa_id is not null')
|
||
->where('employee_polices.wellness_onboard', '0')
|
||
->where('emp.emp_status', 'active')
|
||
->where('emp.is_active', 1)
|
||
->groupStart()
|
||
->where('cp.wellness_plan_id IS NOT NULL', null, false)
|
||
->orWhere('cp.wellness_plan_id !=', '')
|
||
->orWhere('cp.wellness_plan_id !=', 0)
|
||
->groupEnd()
|
||
->groupStart()
|
||
->where('cp.wellness_vendor_id IS NULL', null, false)
|
||
->orWhere('cp.wellness_vendor_id =', '')
|
||
->orWhere('cp.wellness_vendor_id =', 0)
|
||
->groupEnd()
|
||
->where('cp.policy_status',1)
|
||
->where('cp.is_active',1)
|
||
->findAll($perPage, $offset);
|
||
// $data = '[{"id":12847,"employee_id":"TEST_EMP_001","client_policy_id":null,"tpa_id":null,"uhid":null,"batch_code":null,"status":"active","pre_existing_alignments":null,"age_band":null,"basic_cover_si":"0","date_coverage":"2025-01-01","policy_end_date":"2025-12-31","days":"0","premium":"0","rata_premimum":"0","gst":"0","si_enhancement_date":null,"date_of_exit":null,"reason_for_exit":null,"claim_status":"0","created_by":null,"created_at":null,"updated_by":null,"updated_at":null,"is_active":"1","rand_string":null,"ecard_sent_status":"0","payable_employee":"0","file_id":null,"wellness_onboard":"0","name":"test name","relationship":"SELF","emp_code":"TEST_EMP_001","email_corporate":"test@gmail.com","mobile":"9797976565","dob":"1975-08-09"},{"id":12846,"employee_id":"TEST_EMP_001","client_policy_id":null,"tpa_id":null,"uhid":null,"batch_code":null,"status":"active","pre_existing_alignments":null,"age_band":null,"basic_cover_si":"0","date_coverage":"2025-01-01","policy_end_date":"2025-12-31","days":"0","premium":"0","rata_premimum":"0","gst":"0","si_enhancement_date":null,"date_of_exit":null,"reason_for_exit":null,"claim_status":"0","created_by":null,"created_at":null,"updated_by":null,"updated_at":null,"is_active":"1","rand_string":null,"ecard_sent_status":"0","payable_employee":"0","file_id":null,"wellness_onboard":"0","name":"dependent 1","relationship":"SON","emp_code":"TEST_EMP_001","email_corporate":"dependent1@gmail.com","mobile":"9898989898","dob":"2001-08-09"}]';
|
||
// $data = (array)json_decode($data,true);
|
||
// print_r(count($data));
|
||
// echo '==============================';die();
|
||
if(is_array($data) && count($data))
|
||
{
|
||
// $data = $input['data'] ?? [];
|
||
|
||
// ------------------ GROUP BY FAMILY (emp_code) ------------------
|
||
$families = []; // [emp_code => [rows...]]
|
||
|
||
foreach ($data as $row) {
|
||
if (empty($row['emp_code'])) {
|
||
// If emp_code is missing, you can skip or handle separately
|
||
continue;
|
||
}
|
||
|
||
$empCode = $row['emp_code'];
|
||
if (!isset($families[$empCode])) {
|
||
$families[$empCode] = [];
|
||
}
|
||
$families[$empCode][] = $row;
|
||
}
|
||
|
||
// print_rr($families);die();
|
||
|
||
// ------------------ BUILD PAYLOAD FOR ALL FAMILIES ------------------
|
||
$familiesPayload = [];
|
||
|
||
foreach ($families as $empCode => $members) {
|
||
$familiesPayload[$empCode] = $this->buildFamilyPayload($empCode, $members);
|
||
}
|
||
|
||
// print_rr($familiesPayload);die();
|
||
$apiResponse = $this->sendFamiliesToWellnessApi($familiesPayload);
|
||
// print_r($apiResponse);
|
||
$updatedData = $this->updateWellnessOnboardResponseToDB($apiResponse);
|
||
// print_r($updatedData);die();
|
||
|
||
if (count($data) > 0) {
|
||
$delaySeconds = max(1, (int)($arr['recursive_delay_seconds'] ?? 2));
|
||
sleep($delaySeconds);
|
||
|
||
$r = Jobs::addJob(['job_name' => 'initiateWellnessOnboardJob','payload' => [
|
||
'client_policy_id' => $client_policy_id,
|
||
'page' => $page + 1,
|
||
'per_page' => $perPage,
|
||
'recursive_delay_seconds' => $delaySeconds,
|
||
]]);
|
||
|
||
// $this->initiateWellnessOnboardJob([
|
||
// 'client_policy_id' => $client_policy_id,
|
||
// 'page' => $page + 1,
|
||
// 'per_page' => $perPage,
|
||
// 'recursive_delay_seconds' => $delaySeconds,
|
||
// ]);
|
||
}
|
||
|
||
return true;
|
||
|
||
|
||
|
||
|
||
}
|
||
else
|
||
{
|
||
if ($page > 1) {
|
||
return true;
|
||
}
|
||
return $this->respond(['status' => false, 'code' => 200, 'message' => 'No employees found for wellness onboard!'], 200);
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
public function initiateWellnessOnboardJob($arr)
|
||
{
|
||
$client_policy_id = $arr['client_policy_id'] ?? null;
|
||
$emp_code = $arr['emp_code'] ?? null;
|
||
|
||
if (!$client_policy_id) {
|
||
log_message('error', '[WellnessOnboard] Missing client_policy_id in payload');
|
||
return true;
|
||
}
|
||
|
||
$page = max(1, (int)($arr['page'] ?? 1));
|
||
$perPage = max(1, (int)($arr['per_page'] ?? 50));
|
||
$offset = ($page - 1) * $perPage;
|
||
|
||
log_message('error', "[WellnessOnboard] Processing page {$page} | perPage {$perPage} | offset {$offset} | client_policy_id {$client_policy_id}");
|
||
|
||
// ----------------------------------------------------------------
|
||
// 1. FETCH DATA
|
||
// ----------------------------------------------------------------
|
||
$query = $this->employeePolicyModel
|
||
->select('employee_polices.*,
|
||
emp.name, emp.relationship, emp.emp_code, emp.email_corporate,
|
||
emp.mobile, emp.dob, emp.gender,
|
||
cp.policy_no, cp.wellness_plan_id, cp.wellness_vendor_id,
|
||
cp.policy_start_date as cp_policy_start_date, cp.policy_end_date,
|
||
cls.short_name')
|
||
->join('client_policy cp', 'cp.id = employee_polices.client_policy_id')
|
||
->join('clients cls', 'cp.client_id = cls.id')
|
||
->join('employees emp', 'emp.id = employee_polices.employee_id')
|
||
->where('employee_polices.is_active', 1)
|
||
->where('employee_polices.status', 'active')
|
||
->where('employee_polices.client_policy_id', $client_policy_id)
|
||
// ->where('employee_polices.tpa_id is not null')
|
||
->where('employee_polices.wellness_onboard', '0')
|
||
->where('emp.emp_status', 'active')
|
||
->where('emp.is_active', 1)
|
||
->groupStart()
|
||
->where('cp.wellness_plan_id IS NOT NULL', null, false)
|
||
->orWhere('cp.wellness_plan_id !=', '')
|
||
->orWhere('cp.wellness_plan_id !=', 0)
|
||
->groupEnd()
|
||
->groupStart()
|
||
->where('cp.wellness_vendor_id IS NULL', null, false)
|
||
->orWhere('cp.wellness_vendor_id =', '')
|
||
->orWhere('cp.wellness_vendor_id =', 0)
|
||
->groupEnd()
|
||
->where('cp.policy_status', 1)
|
||
->where('cp.is_active', 1);
|
||
|
||
if(!empty($emp_code)){
|
||
$query->where('emp.emp_code', trim($emp_code));
|
||
}
|
||
|
||
$data = $query->findAll($perPage, $offset);
|
||
|
||
// ----------------------------------------------------------------
|
||
// 2. NO DATA FOUND
|
||
// ----------------------------------------------------------------
|
||
if (empty($data)) {
|
||
log_message('error', "[WellnessOnboard] No data found on page {$page}. Batch complete.");
|
||
return true; // always return true in job context, never $this->respond()
|
||
}
|
||
|
||
// ----------------------------------------------------------------
|
||
// 3. GROUP BY FAMILY (emp_code)
|
||
// ----------------------------------------------------------------
|
||
$families = [];
|
||
foreach ($data as $row) {
|
||
if (empty($row['emp_code'])) {
|
||
log_message('warning', '[WellnessOnboard] Skipping row with missing emp_code: ' . json_encode($row));
|
||
continue;
|
||
}
|
||
$families[$row['emp_code']][] = $row;
|
||
}
|
||
|
||
if (empty($families)) {
|
||
log_message('warning', "[WellnessOnboard] All rows on page {$page} had missing emp_code. Skipping.");
|
||
return true;
|
||
}
|
||
|
||
// ----------------------------------------------------------------
|
||
// 4. BUILD PAYLOAD
|
||
// ----------------------------------------------------------------
|
||
$familiesPayload = [];
|
||
foreach ($families as $empCode => $members) {
|
||
$familiesPayload[$empCode] = $this->buildFamilyPayload($empCode, $members);
|
||
}
|
||
log_message('error', "[WellnessOnboard] Page {$page} API calls done. Families processed: " . json_encode($familiesPayload));
|
||
// ----------------------------------------------------------------
|
||
// 5. SEND TO WELLNESS API
|
||
// ----------------------------------------------------------------
|
||
$apiResponse = $this->sendFamiliesToWellnessApi($familiesPayload);
|
||
log_message('error', "[WellnessOnboard] Page {$page} API calls done. Families processed: " . count($apiResponse));
|
||
|
||
// ----------------------------------------------------------------
|
||
// 6. PERSIST RESPONSE TO DB
|
||
// ----------------------------------------------------------------
|
||
$updatedData = $this->updateWellnessOnboardResponseToDB($apiResponse);
|
||
log_message('error', "[WellnessOnboard] Page {$page} DB update done.");
|
||
|
||
// ----------------------------------------------------------------
|
||
// 7. SPAWN NEXT PAGE JOB (only if this page was full)
|
||
// ----------------------------------------------------------------
|
||
if (count($data) === $perPage) {
|
||
log_message('error', "[WellnessOnboard] Full page detected. Spawning job for page " . ($page + 1));
|
||
Jobs::addJob([
|
||
'job_name' => 'initiateWellnessOnboardJob',
|
||
'payload' => [
|
||
'client_policy_id' => $client_policy_id,
|
||
'page' => $page + 1,
|
||
'per_page' => $perPage,
|
||
]
|
||
]);
|
||
} else {
|
||
log_message('error', "[WellnessOnboard] Partial page ({$page}). This is the last page. Batch complete.");
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
public function resetWellnessOnboard($client_policy_id, $emp_code = null)
|
||
{
|
||
if(!empty($emp_code)){
|
||
|
||
$employees = db_connect()->table('employees')
|
||
->select('id')
|
||
->where('emp_code', trim($emp_code))
|
||
->get()
|
||
->getResult();
|
||
|
||
if (!empty($employees)) {
|
||
$employeeIds = array_column($employees, 'id');
|
||
|
||
$this->employeePolicyModel
|
||
->where('client_policy_id', $client_policy_id)
|
||
->whereIn('employee_id', $employeeIds)
|
||
->set('wellness_onboard', '0')
|
||
->update();
|
||
}
|
||
|
||
} else {
|
||
$this->employeePolicyModel->where('client_policy_id', $client_policy_id)->set('wellness_onboard', '0')->update();
|
||
}
|
||
|
||
return $this->respond(['status' => true, 'code' => 200, 'message' => 'Wellness onboard resetted successfully'], 200);
|
||
}
|
||
|
||
|
||
|
||
# ------------------ FUNCTION TO BUILD FAMILY PAYLOAD ------------------
|
||
/**
|
||
* Build the required payload for a single family.
|
||
*
|
||
* @param string $empCode
|
||
* @param array $members Array of rows for this emp_code
|
||
* @return array
|
||
*/
|
||
private function buildFamilyPayload(string $empCode, array $members): array
|
||
{
|
||
// Use the first member as primary reference for policy level data
|
||
$primary = $members[0];
|
||
// print_rr($primary);die();
|
||
// Map DB fields to your required "policyDetails" structure
|
||
$policyStartDate = $primary['cp_policy_start_date'] ?? null;
|
||
// $policyStartDate = '2025-01-01';
|
||
$policyEndDate = $primary['policy_end_date'] ?? null;
|
||
// $policyEndDate = '2025-12-31';
|
||
|
||
$payload = [
|
||
"policyDetails" => [
|
||
"policyNumber" => $primary["policy_no"] ?? null,
|
||
"employeeId" => $empCode,
|
||
"policyName" => "GMC", // Static or from DB
|
||
"policyStartDate" => $policyStartDate,
|
||
"policyEndDate" => $policyEndDate,
|
||
"plan" => $primary["wellness_plan_id"] ?? null,
|
||
"source" => 'NHANCE',
|
||
"employer" => $primary['short_name'] ?? null,
|
||
"employeeCode" => $empCode,
|
||
"accountNumber" => "", // Fill from DB if available
|
||
"ifsc" => "", // Fill from DB if available
|
||
"accountType" => "" // Fill from DB if available
|
||
],
|
||
"memberDetails" => []
|
||
];
|
||
|
||
// Build "memberDetails" for each member in this family
|
||
foreach ($members as $index => $row) {
|
||
|
||
// You don't have gender in data, so put null or default
|
||
|
||
|
||
$payload["memberDetails"][] = [
|
||
"memberId" => $row["id"], // or custom ID (e.g. employee_id.'-'.$index)
|
||
"name" => $row["name"],
|
||
"phone" => $row["mobile"],
|
||
"email" => $row["email_corporate"],
|
||
"relationshipName" => $this->mapRelationship($row["relationship"],$row["gender"]),
|
||
"gender" => $row["gender"] == 'M' ? 'Male' : 'Female',
|
||
"dob" => $row["dob"]
|
||
];
|
||
}
|
||
|
||
return $payload;
|
||
}
|
||
|
||
|
||
function mapRelationship(string $relationship, ?string $gender = null): string
|
||
{
|
||
// Normalize input
|
||
$key = strtolower(trim($relationship));
|
||
$key = str_replace(['-', '_'], ' ', $key);
|
||
$key = preg_replace('/\s+/', ' ', $key);
|
||
|
||
// Base mapping
|
||
$map = [
|
||
'self' => 'self',
|
||
'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',
|
||
];
|
||
|
||
// Special handling for spouse
|
||
if ($key === 'spouse') {
|
||
if ($gender === 'M') {
|
||
return 'husband';
|
||
}
|
||
if ($gender === 'F') {
|
||
return 'wife';
|
||
}
|
||
|
||
// fallback if gender missing (better to throw error)
|
||
throw new \Exception("Gender required to map 'Spouse'");
|
||
}
|
||
|
||
return $map[$key] ?? '';
|
||
}
|
||
|
||
|
||
/**
|
||
* Send each family payload to API and attach the response
|
||
*
|
||
* @param array $familiesPayload [emp_code => ['policyDetails' => ..., 'memberDetails' => [...]]]
|
||
* @return array Same array but with ['apiResponse'] added for each family
|
||
*/
|
||
public function sendFamiliesToWellnessApi(array $familiesPayload): array
|
||
{
|
||
// CI4 HTTP client
|
||
// print_rr($familiesPayload);die();
|
||
$client = \Config\Services::curlrequest();//die();
|
||
$endpointUrl = getenv('WELLNESS_ONBOARD_ENDPOINT_URL');
|
||
// Custom headers
|
||
$headers = [
|
||
'Content-Type' => 'application/json',
|
||
'Authorization' => 'Basic ' . getenv('WELLNESS_ONBOARD_AUTHORIZATION')
|
||
];
|
||
|
||
foreach ($familiesPayload as $empCode => &$family) {
|
||
// print_rr($family);die();
|
||
try {
|
||
$response = $client->post($endpointUrl, [
|
||
'headers' => $headers,
|
||
'body' => json_encode($family),
|
||
'http_errors' => false, // so we can handle non-2xx manually
|
||
'timeout' => 30,
|
||
]);
|
||
|
||
$statusCode = $response->getStatusCode();
|
||
$body = (string) $response->getBody();
|
||
$decoded = json_decode($body, true);
|
||
|
||
$family['apiResponse'] = [
|
||
'statusCode' => $statusCode,
|
||
'rawBody' => $body,
|
||
'data' => $decoded,
|
||
];
|
||
|
||
|
||
} catch (\Throwable $e) {
|
||
// In case of exception, store error info
|
||
$family['apiResponse'] = [
|
||
'statusCode' => 0,
|
||
'rawBody' => null,
|
||
'data' => null,
|
||
'error' => $e->getMessage(),
|
||
];
|
||
}
|
||
|
||
// print_rr($body );die();
|
||
}
|
||
|
||
unset($family); // break reference
|
||
|
||
return $familiesPayload;
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Batch update wellness_onboard for each family using referenceId from API response.
|
||
*
|
||
* @param array $familiesWithResponse // output of sendFamiliesToApi()
|
||
* @return void
|
||
*/
|
||
public function updateWellnessOnboardResponseToDB(array $familiesWithResponse = []): void
|
||
{
|
||
// echo 'START';
|
||
// Collect all rows to update in a single big batch (optional but efficient)
|
||
$allUpdates = [];
|
||
|
||
// $apiResponse = [
|
||
// "message" => "success",
|
||
// "body" => "The policy details are posted successfully",
|
||
// "policyDetails" => [
|
||
// [
|
||
// "memberId" => "12847",
|
||
// "name" => "test name",
|
||
// "phone" => 9797976565,
|
||
// "email" => "test@gmail.com",
|
||
// "relationshipName" => "SELF",
|
||
// "gender" => "MALE",
|
||
// "dob" => "1975-08-09"
|
||
// ],
|
||
// [
|
||
// "memberId" => "12846",
|
||
// "name" => "dependent 1",
|
||
// "phone" => 9898989898,
|
||
// "email" => "dependent1@gmail.com",
|
||
// "relationshipName" => "SON",
|
||
// "gender" => "MALE",
|
||
// "dob" => "2001-08-09"
|
||
// ]
|
||
// ],
|
||
// "referenceId" => "TESTPOL001-client1-1764914537069"
|
||
// ];
|
||
|
||
// $familiesWithResponse = [
|
||
|
||
// "TEST_EMP_001" => [
|
||
// "policyDetails" => [
|
||
// "policyNumber" => "TESTPOL001",
|
||
// "employeeId" => "TEST_EMP_001",
|
||
// "policyName" => "Client Policy Name",
|
||
// "policyStartDate" => "2025-01-01",
|
||
// "policyEndDate" => "2025-12-31",
|
||
// "plan" => "plan-A",
|
||
// "source" => "client1",
|
||
// "employer" => "employeer1",
|
||
// "employeeCode" => "TEST_EMP_001",
|
||
// "accountNumber" => "",
|
||
// "ifsc" => "",
|
||
// "accountType" => ""
|
||
// ],
|
||
// "memberDetails" => [
|
||
// [
|
||
// "memberId" => "12847",
|
||
// "name" => "test name",
|
||
// "phone" => 9797976565,
|
||
// "email" => "test@gmail.com",
|
||
// "relationshipName" => "SELF",
|
||
// "gender" => "MALE",
|
||
// "dob" => "1975-08-09"
|
||
// ],
|
||
// [
|
||
// "memberId" => "12846",
|
||
// "name" => "dependent 1",
|
||
// "phone" => 9898989898,
|
||
// "email" => "dependent1@gmail.com",
|
||
// "relationshipName" => "SON",
|
||
// "gender" => "MALE",
|
||
// "dob" => "2001-08-09"
|
||
// ]
|
||
// ],
|
||
|
||
// "apiResponse" => [ 'statusCode' => 200 ,"rawBody" => "", "data" => $apiResponse]
|
||
// ]
|
||
// ];
|
||
|
||
|
||
|
||
foreach ($familiesWithResponse as $empCode => $family) {
|
||
|
||
$apiResponse = $family['apiResponse'] ?? null;
|
||
if (!$apiResponse || !isset($apiResponse['data'])) {
|
||
// No valid API data for this family
|
||
$this->myLogger->logme('error', "Wellness Onboard API error for emp_code {$empCode} No apiResponse found:");
|
||
continue;
|
||
}
|
||
|
||
// Your endpoint response
|
||
$statusCode = $apiResponse['statusCode'] ?? null;
|
||
if (empty($statusCode) || $statusCode == 400 || $statusCode == 500) {
|
||
$this->myLogger->logme('error', "Wellness Onboard API error for emp_code {$empCode} {}: " . ($apiResponse['rawBody'] ?? 'No response'));
|
||
|
||
// No referenceId, nothing to update
|
||
continue;
|
||
}
|
||
|
||
$data = $apiResponse['data'];
|
||
|
||
// Your endpoint response
|
||
$referenceId = $data['referenceId'] ?? null;
|
||
if (empty($referenceId)) {
|
||
// No referenceId, nothing to update
|
||
$this->myLogger->logme('error', "Wellness Onboard API error for emp_code {$empCode} No referenceId found:");
|
||
continue;
|
||
}
|
||
|
||
// All members in this family share the same referenceId
|
||
if (empty($family['memberDetails']) || !is_array($family['memberDetails'])) {
|
||
$this->myLogger->logme('error', "Wellness Onboard API error for emp_code {$empCode} No memberDetails found:");
|
||
continue;
|
||
}
|
||
|
||
foreach ($family['memberDetails'] as $member) {
|
||
$memberPk = $member['memberId'] ?? null; // This is employee_policy.id
|
||
|
||
if (empty($memberPk)) {
|
||
continue;
|
||
}
|
||
|
||
$allUpdates[] = [
|
||
'id' => $memberPk, // PK column of your table
|
||
'wellness_onboard' => $referenceId,
|
||
// uncomment if you have updated_at column
|
||
// 'updated_at' => date('Y-m-d H:i:s'),
|
||
];
|
||
}
|
||
}
|
||
// print_r($allUpdates);die();
|
||
// Do a single batch update for all families/members
|
||
log_message('error','[WellnessOnboard] DB update data - ' . json_encode($allUpdates));
|
||
if (!empty($allUpdates)) {
|
||
// 2nd param is the key to match on; here it's 'id'
|
||
$this->employeePolicyModel->updateBatch($allUpdates, 'id');
|
||
}
|
||
}
|
||
|
||
public function getTPADataVariationReport($file_id, $type = 'download')
|
||
{
|
||
// print_rr($this->initializeDeletionProcessForTpaApiData($file_id));
|
||
// die;
|
||
$fileInfo = $this->batchFileModel->find((int) $file_id);
|
||
if (empty($fileInfo)) {
|
||
if ($type === 'view') {
|
||
return [];
|
||
}
|
||
if ($type === 'download') {
|
||
return false;
|
||
}
|
||
|
||
return $this->respond(['status' => false, 'code' => 404, 'message' => 'File not found', 'data' => []], 200);
|
||
}
|
||
|
||
$client_id = (int) ($fileInfo['client_id'] ?? 0);
|
||
$client_policy_id = (int) ($fileInfo['client_policy_id'] ?? 0);
|
||
// `call_type` controls whether we should force a fresh reconciliation.
|
||
// - job => always recompute + persist rec_type snapshot
|
||
// - manual => compute only on first call; otherwise use cached rec_type snapshot
|
||
// $callType = strtolower((string) ($this->request->getGet('call_type') ?? 'manual'));
|
||
$isJobCall = $type === 'job';
|
||
|
||
$tpaApiDataModel = new TpaApiDataModel();
|
||
// Snapshot existence check:
|
||
// If any active row already has a non-empty rec_type, we consider this file
|
||
// already classified and can safely use cached mode for non-job calls.
|
||
$hasRecTypeSnapshot = $tpaApiDataModel->where('file_id', $file_id)
|
||
->where('is_active', 1)
|
||
->where('rec_type IS NOT NULL', null, false)
|
||
->where('rec_type !=', '')
|
||
->countAllResults() > 0;
|
||
|
||
// Compute mode rules:
|
||
// 1) job calls always recompute and overwrite rec_type for deterministic refresh.
|
||
// 2) first non-job call computes when no snapshot exists.
|
||
// Cached mode is used only for second+ non-job calls.
|
||
$shouldComputeAndPersist = $isJobCall || !$hasRecTypeSnapshot;
|
||
// echo $shouldComputeAndPersist;
|
||
// die;
|
||
$this->myLogger->logme(
|
||
'error',
|
||
'TPA variation report mode selected: ' . json_encode([
|
||
'file_id' => (int) $file_id,
|
||
'call_type' => $isJobCall,
|
||
'mode' => $shouldComputeAndPersist ? 'compute' : 'cached',
|
||
])
|
||
);
|
||
$emp_data_wo_tpa_id = [];
|
||
$not_in_nhance = [];
|
||
|
||
if ($shouldComputeAndPersist) {
|
||
// Load once and index in memory to avoid N+1 queries during reconciliation.
|
||
$allActiveTpaRows = $tpaApiDataModel->select('*')
|
||
->where('file_id', $file_id)
|
||
->where('is_active', 1)
|
||
->findAll();
|
||
|
||
$tpaByEmpCode = [];
|
||
foreach ($allActiveTpaRows as $tpaRow) {
|
||
$tpaByEmpCode[$tpaRow['emp_code']][] = $tpaRow;
|
||
}
|
||
|
||
$recTypeById = [];
|
||
foreach ($allActiveTpaRows as $tpaRow) {
|
||
// Default classification for active rows.
|
||
// Later loops will overwrite specific rows as `need_to_review` or `not_in_nhance`.
|
||
$recTypeById[$tpaRow['id']] = 'matched';
|
||
}
|
||
|
||
$emp_data_wo_tpa_id = $this->employeePolicyModel->getTPADataVariationReport($client_id, $client_policy_id, $file_id);
|
||
|
||
// Reconcile DB records against TPA records and classify records for rec_type updates.
|
||
$consumedTpaIdsByEmpCode = [];
|
||
foreach ($emp_data_wo_tpa_id as $db_key => $db_row) {
|
||
$empCode = (string) ($db_row['emp_code'] ?? '');
|
||
$empId = (string) ($db_row['id'] ?? '');
|
||
$empName = (string) ($db_row['name'] ?? '');
|
||
$tpa_temp_data = $tpaByEmpCode[$empCode] ?? [];
|
||
$excludeTpaIds = $consumedTpaIdsByEmpCode[$empCode] ?? [];
|
||
$match = $this->reconcileDbWithTpa($db_row, $tpa_temp_data, $excludeTpaIds);
|
||
$emp_data_wo_tpa_id[$db_key]['match'] = $match;
|
||
|
||
if (($match['status'] ?? '') === 'matched') {
|
||
$matchedTpaId = (int) ($match['tpa_record']['id'] ?? 0);
|
||
// echo 'matched' . $matchedTpaId . ' for emp_code ' . $empCode . PHP_EOL . '<br>';
|
||
if ($matchedTpaId > 0) {
|
||
$consumedTpaIdsByEmpCode[$empCode][] = $matchedTpaId;
|
||
// If compare-fields list has differences, the row must be reviewed.
|
||
// Otherwise keep it as matched.
|
||
$recTypeById[$matchedTpaId] = empty($match['not_matching']) ? 'matched' : 'need_to_review';
|
||
}
|
||
} else {
|
||
// echo 'not matched' . ' for emp_code ' . $empCode . PHP_EOL . ' - ' . $empId . ' - ' . $empName . ' - ' . '<br>';
|
||
// No match for this DB member: flag same-relation TPA rows not already paired.
|
||
$dbRel = strtolower(trim((string) ($db_row['relationship'] ?? '')));
|
||
foreach ($tpa_temp_data as $candidate) {
|
||
if (strtolower(trim((string) ($candidate['relation'] ?? ''))) !== $dbRel) {
|
||
continue;
|
||
}
|
||
$candidateId = (int) ($candidate['id'] ?? 0);
|
||
if ($candidateId > 0 && !in_array($candidateId, $excludeTpaIds, true)) {
|
||
$recTypeById[$candidateId] = '';
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
$master_emp_codes = $this->employeePolicyModel->getTPADataVariationReport($client_id, $client_policy_id, $file_id, [], true);
|
||
$master_emp_codes = array_column($master_emp_codes, 'emp_code');
|
||
|
||
$not_in_nhance = [];
|
||
foreach ($allActiveTpaRows as $tpaRow) {
|
||
if (!in_array($tpaRow['emp_code'], $master_emp_codes, true)) {
|
||
// TPA member not found in Nhance master employee list for this client/policy.
|
||
$not_in_nhance[] = $tpaRow;
|
||
$recTypeById[(int) $tpaRow['id']] = 'not_in_nhance';
|
||
}
|
||
}
|
||
|
||
if (!empty($recTypeById)) {
|
||
$updateRows = [];
|
||
foreach ($recTypeById as $id => $recType) {
|
||
$updateRows[] = [
|
||
'id' => (int) $id,
|
||
'rec_type' => $recType,
|
||
];
|
||
}
|
||
// Persist snapshot atomically so subsequent non-job calls can use cached mode.
|
||
$db = \Config\Database::connect();
|
||
$db->transStart();
|
||
$tpaApiDataModel->updateBatch($updateRows, 'id');
|
||
$db->transComplete();
|
||
}
|
||
|
||
// this will match tpa api data with emp/emp policy table and update ref in tpa api data once
|
||
$this->reconTpaApiDataWithEmployeepolicies(['file_id' => $file_id]);
|
||
} else {
|
||
// Cached mode:
|
||
// `not_in_nhance` stays sourced from persisted rec_type snapshot.
|
||
// `mismatch_data` must match compute-mode shape: every policy row with
|
||
// tpa_id NULL gets reconcileDbWithTpa against *all* active TPA rows for
|
||
// that emp_code (not only rows flagged need_to_review), otherwise second+
|
||
// loads drop rows / lose not_matching vs the first compute pass.
|
||
$not_in_nhance = $tpaApiDataModel->select('*')
|
||
->where('is_active', 1)
|
||
->where('file_id', $file_id)
|
||
->where('rec_type', 'not_in_nhance')
|
||
->findAll();
|
||
|
||
$allActiveTpaRowsCached = $tpaApiDataModel->select('*')
|
||
->where('file_id', $file_id)
|
||
->where('is_active', 1)
|
||
->findAll();
|
||
|
||
$tpaByEmpCodeCached = [];
|
||
foreach ($allActiveTpaRowsCached as $tpaRow) {
|
||
$tpaByEmpCodeCached[$tpaRow['emp_code']][] = $tpaRow;
|
||
}
|
||
|
||
$emp_data_wo_tpa_id = $this->employeePolicyModel->getTPADataVariationReport($client_id, $client_policy_id, $file_id);
|
||
$consumedTpaIdsByEmpCodeCached = [];
|
||
foreach ($emp_data_wo_tpa_id as $db_key => $db_row) {
|
||
$empCode = (string) ($db_row['emp_code'] ?? '');
|
||
$tpa_temp_data = $tpaByEmpCodeCached[$empCode] ?? [];
|
||
$excludeTpaIds = $consumedTpaIdsByEmpCodeCached[$empCode] ?? [];
|
||
$match = $this->reconcileDbWithTpa($db_row, $tpa_temp_data, $excludeTpaIds);
|
||
$emp_data_wo_tpa_id[$db_key]['match'] = $match;
|
||
if (($match['status'] ?? '') === 'matched') {
|
||
$matchedTpaId = (int) ($match['tpa_record']['id'] ?? 0);
|
||
if ($matchedTpaId > 0) {
|
||
$consumedTpaIdsByEmpCodeCached[$empCode][] = $matchedTpaId;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// print_rr($emp_data_wo_tpa_id);die();
|
||
|
||
|
||
// Intentionally keep `not_in_tpa` live from current join/query logic
|
||
// (as requested) and do not source it from rec_type snapshot.
|
||
$tpa_emp_codes = $tpaApiDataModel->select('ref')
|
||
->where('file_id', $file_id)
|
||
->where('is_active', 1)
|
||
->groupBy('ref')
|
||
->findAll();
|
||
|
||
// $tpa_emp_codes = array_column($tpa_emp_codes, 'ref');
|
||
$tpa_ref = array_column($tpa_emp_codes, 'ref');
|
||
$not_in_tpa = $this->employeePolicyModel->getTPADataVariationReport($client_id, $client_policy_id, $file_id, $tpa_ref);
|
||
|
||
// Format dates for UI/export (dd/mm/yyyy). Applied after reconciliation so
|
||
// reconcileDbWithTpa can still compare raw Y-m-d values from the database.
|
||
$this->formatVariationReportDataForDisplay($not_in_tpa, $not_in_nhance, $emp_data_wo_tpa_id);
|
||
|
||
if (!empty($not_in_tpa) || !empty($not_in_nhance) || !empty($emp_data_wo_tpa_id)) {
|
||
$not_in_nhance_button_enable_status = false;
|
||
if (count($not_in_nhance)) {
|
||
foreach ($not_in_nhance as $nih) {
|
||
$hasRefKey = array_key_exists('ref', $nih);
|
||
$ref = $hasRefKey ? $nih['ref'] : null;
|
||
$refIsEmpty = $ref === null || $ref === '';
|
||
if ($refIsEmpty) {
|
||
$not_in_nhance_button_enable_status = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
$not_in_nhance_inception_count = 0;
|
||
$not_in_nhance_deletion_count = 0;
|
||
foreach ($not_in_nhance as $nih) {
|
||
$hasRefKey = array_key_exists('ref', $nih);
|
||
$ref = $hasRefKey ? $nih['ref'] : null;
|
||
// Empty/null ref: no key, NULL, '', or whitespace-only string.
|
||
$refIsEmpty = !$hasRefKey
|
||
|| $ref === null
|
||
|| $ref === ''
|
||
|| (is_string($ref) && trim($ref) === '');
|
||
|
||
$actionIsDeletion = strtoupper(trim((string) ($nih['action_flag_status'] ?? ''))) === 'D';
|
||
|
||
// Every empty/null ref row counts as inception; those that also have flag D additionally count as deletion.
|
||
if ($refIsEmpty) {
|
||
$not_in_nhance_inception_count++;
|
||
if ($actionIsDeletion) {
|
||
$not_in_nhance_deletion_count++;
|
||
}
|
||
}
|
||
}
|
||
|
||
$not_in_nhance_proceed_button_text = sprintf(
|
||
'Proceed - Inception(%d) + Deletion(%d)',
|
||
$not_in_nhance_inception_count,
|
||
$not_in_nhance_deletion_count
|
||
);
|
||
|
||
$not_matched_count = 0;
|
||
$not_matched_data = [];
|
||
foreach ($emp_data_wo_tpa_id as $key => $row) {
|
||
$notMatching = $row['match']['not_matching'] ?? [];
|
||
if (isset($row['match']) && is_array($notMatching) && $notMatching !== []) {
|
||
$not_matched_count++;
|
||
$not_matched_data[] = $row;
|
||
}
|
||
}
|
||
|
||
$need_to_review_proceed_button_text = sprintf(
|
||
'Proceed - Need to Review ( %d )',
|
||
$not_matched_count
|
||
);
|
||
|
||
$response = [
|
||
'not_in_tpa' => $not_in_tpa,
|
||
'not_in_nhance' => $not_in_nhance,
|
||
'mismatch_data' => $emp_data_wo_tpa_id,
|
||
'not_in_nhance_button_enable_status' => $not_in_nhance_button_enable_status,
|
||
'not_in_nhance_inception_count' => $not_in_nhance_inception_count,
|
||
'not_in_nhance_deletion_count' => $not_in_nhance_deletion_count,
|
||
'not_in_nhance_proceed_button_text' => $not_in_nhance_proceed_button_text,
|
||
'not_matched_count' => $not_matched_count,
|
||
'not_matched_data' => $not_matched_data,
|
||
'need_to_review_proceed_button_text' => $need_to_review_proceed_button_text,
|
||
];
|
||
|
||
if ($type === 'view') {
|
||
return $this->respond(['status' => true, 'code' => 200, 'message' => '', 'data' => $response], 200);
|
||
} elseif ($type === 'download') {
|
||
$this->exportVariationReportExcel($not_in_tpa, $not_in_nhance, $emp_data_wo_tpa_id);
|
||
} else {
|
||
return $this->respond(['status' => true, 'code' => 200, 'message' => '', 'data' => $response], 200);
|
||
}
|
||
} else {
|
||
if ($type === 'view') {
|
||
return [];
|
||
}
|
||
|
||
if ($type === 'download') {
|
||
return false;
|
||
}
|
||
|
||
return $this->respond(['status' => false, 'code' => 202, 'message' => 'No data found', 'data' => []], 200);
|
||
}
|
||
}
|
||
|
||
public function proceedTPADataVariationNextStep($file_id)
|
||
{
|
||
// echo $file_id;die;
|
||
try {
|
||
if (empty($file_id)) {
|
||
return $this->respond(
|
||
[
|
||
'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
|
||
);
|
||
}
|
||
|
||
if($generationResult['status'])
|
||
{
|
||
if($generationResult['data']['file_id'])
|
||
{
|
||
// sleep(1);
|
||
//initiate update references b/w tpa_api_data and employess (pk update)
|
||
// $this->reconTpaApiDataWithEmployeepolicies(['file_id' => $file_id]);
|
||
// sleep(1);
|
||
//initiate deleteion if any
|
||
// $this->initializeDeletionProcessForTpaApiData(['file_id' => $file_id]);
|
||
|
||
}
|
||
else
|
||
{
|
||
//seems inception file id not there just put a log
|
||
$this->myLogger->logme(
|
||
'error',
|
||
'TPA RECON | Inception file id missing after generating employee upload from Not in Nhance data for file_id:'
|
||
);
|
||
|
||
}
|
||
}
|
||
} elseif ($tab === 'need_to_review') {
|
||
// For the "Need to Review" tab, generate a Correction Excel
|
||
// using the same overall pipeline as the Not in Nhance implementation.
|
||
// $generationResult = $this->generateCorrectionUploadFromNeedToReview((int) $file_id, $file);
|
||
|
||
//once correction file uploaded success fully update ref id b/w employeetable and tpaapi data
|
||
$generationResult = $this->updateEmployeeDataFromTpa(['batch_file_id' => (int) $file_id]);
|
||
|
||
if (empty($generationResult['success'])) {
|
||
return $this->respond(
|
||
[
|
||
'status' => false,
|
||
'code' => 422,
|
||
'message' => $generationResult['message'] ?? 'Unable to process the data from Need to Review tab.',
|
||
'data' => $generationResult['data'] ?? [],
|
||
],
|
||
200
|
||
);
|
||
}
|
||
}
|
||
|
||
$this->myLogger->logme(
|
||
'error',
|
||
'TPA variation review completed and proceed to next clicked' . json_encode(
|
||
[
|
||
'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'
|
||
? 'Review data update successfully.'
|
||
: '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;
|
||
if (! is_dir(WRITEPATH . 'uploads/excel')) {
|
||
mkdir(WRITEPATH . 'uploads/excel', 0755, true);
|
||
}
|
||
|
||
$writer = new Xlsx($spreadsheet);
|
||
$writer->save($filePath);
|
||
storage_mirror_generated_file($filePath, WRITEPATH . 'uploads/excel', $fileName);
|
||
|
||
// 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, 'batch_file_id' => $batchFileId]);
|
||
|
||
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 = [];
|
||
$consumedTpaIdsByEmpCode = [];
|
||
|
||
foreach ($dbRows as $dbRow) {
|
||
$empCode = (string) ($dbRow['emp_code'] ?? '');
|
||
$tpaRows = $TpaApiDataModel->select('*')
|
||
->where('emp_code', $empCode)
|
||
->where('file_id', $batchFileId)
|
||
->where('is_active', 1)
|
||
->findAll();
|
||
|
||
if (!count($tpaRows)) {
|
||
continue;
|
||
}
|
||
|
||
$excludeTpaIds = $consumedTpaIdsByEmpCode[$empCode] ?? [];
|
||
$match = $this->reconcileDbWithTpa($dbRow, $tpaRows, $excludeTpaIds);
|
||
if (($match['status'] ?? '') === 'matched') {
|
||
$matchedTpaId = (int) ($match['tpa_record']['id'] ?? 0);
|
||
if ($matchedTpaId > 0) {
|
||
$consumedTpaIdsByEmpCode[$empCode][] = $matchedTpaId;
|
||
}
|
||
}
|
||
|
||
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;
|
||
if (! is_dir(WRITEPATH . 'uploads/excel')) {
|
||
mkdir(WRITEPATH . 'uploads/excel', 0755, true);
|
||
}
|
||
|
||
$writer = new Xlsx($spreadsheet);
|
||
$writer->save($filePath);
|
||
storage_mirror_generated_file($filePath, WRITEPATH . 'uploads/excel', $fileName);
|
||
|
||
// 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' => [],
|
||
];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Apply TPA values to `employees` for rows in the same "Need to Review" set as
|
||
* {@see generateCorrectionUploadFromNeedToReview}: same `getTPADataVariationReport` slice,
|
||
* same `reconcileDbWithTpa` matching, then persist mismatched fields from TPA instead of
|
||
* generating a correction Excel.
|
||
*
|
||
* Updatable fields mirror the correction Excel allow-list where they exist on TPA rows:
|
||
* `name`, `dob`, `gender`, `relationship` (from TPA `relation`), `email_corporate` (if present on TPA).
|
||
* Note: {@see reconcileDbWithTpa} only pairs rows when DB `relationship` matches TPA `relation`,
|
||
* so `relationship` rarely appears in `not_matching`; name/dob/gender are the usual diffs.
|
||
*
|
||
* @param array $params Expects `batch_file_id` (int, required).
|
||
*
|
||
* @return array{success:bool,message:string,data:array}
|
||
*/
|
||
public function updateEmployeeDataFromTpa(array $params)
|
||
{
|
||
try {
|
||
|
||
$batchFileId = (int) ($params['batch_file_id'] ?? 0);
|
||
|
||
if ($batchFileId <= 0) {
|
||
return [
|
||
'success' => false,
|
||
'message' => 'batch_file_id is required and must be a positive integer.',
|
||
'data' => [],
|
||
];
|
||
}
|
||
|
||
$batchFile = $this->batchFileModel->find($batchFileId);
|
||
|
||
if (!$batchFile) {
|
||
return [
|
||
'success' => false,
|
||
'message' => 'Batch file not found.',
|
||
'data' => ['batch_file_id' => $batchFileId],
|
||
];
|
||
}
|
||
|
||
$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 [
|
||
'success' => false,
|
||
'message' => 'Incomplete batch file information. Client / policy / branch missing.',
|
||
'data' => [],
|
||
];
|
||
}
|
||
|
||
$TpaApiDataModel = new TpaApiDataModel();
|
||
|
||
$dbRows = $this->employeePolicyModel->getTPADataVariationReport(
|
||
$clientId,
|
||
$clientPolicyId,
|
||
$batchFileId
|
||
);
|
||
|
||
if (!is_array($dbRows) || $dbRows === []) {
|
||
return [
|
||
'success' => false,
|
||
'message' => 'No employee data found for this TPA variation batch.',
|
||
'data' => [],
|
||
];
|
||
}
|
||
|
||
$allowedFields = ['name', 'dob', 'relationship', 'email_corporate', 'gender'];
|
||
|
||
$employeeModel = new EmployeeModel();
|
||
$employeesUpdated = 0;
|
||
$rowsSkippedNoDiff = 0;
|
||
$rowsSkippedNoEmployee = 0;
|
||
|
||
$consumedTpaIdsByEmpCode = [];
|
||
|
||
foreach ($dbRows as $dbRow) {
|
||
$empCode = (string) ($dbRow['emp_code'] ?? '');
|
||
$tpaRows = $TpaApiDataModel->select('*')
|
||
->where('emp_code', $empCode)
|
||
->where('file_id', $batchFileId)
|
||
->where('is_active', 1)
|
||
->findAll();
|
||
|
||
if ($tpaRows === []) {
|
||
continue;
|
||
}
|
||
|
||
$excludeTpaIds = $consumedTpaIdsByEmpCode[$empCode] ?? [];
|
||
$match = $this->reconcileDbWithTpa($dbRow, $tpaRows, $excludeTpaIds);
|
||
|
||
if (($match['status'] ?? '') !== 'matched') {
|
||
continue;
|
||
}
|
||
|
||
$tpaRecord = $match['tpa_record'] ?? [];
|
||
$notMatching = $match['not_matching'] ?? [];
|
||
|
||
$matchedTpaId = (int) ($tpaRecord['id'] ?? 0);
|
||
if ($matchedTpaId > 0) {
|
||
$consumedTpaIdsByEmpCode[$empCode][] = $matchedTpaId;
|
||
}
|
||
|
||
if (!is_array($notMatching) || $notMatching === []) {
|
||
$rowsSkippedNoDiff++;
|
||
continue;
|
||
}
|
||
|
||
$employeeId = (int) ($dbRow['employee_id'] ?? 0);
|
||
|
||
if ($employeeId <= 0) {
|
||
$rowsSkippedNoEmployee++;
|
||
continue;
|
||
}
|
||
|
||
$employeeRow = $employeeModel->find($employeeId);
|
||
|
||
if (
|
||
!$employeeRow
|
||
|| (int) ($employeeRow['client_id'] ?? 0) !== $clientId
|
||
) {
|
||
$rowsSkippedNoEmployee++;
|
||
continue;
|
||
}
|
||
|
||
$updateData = [];
|
||
|
||
foreach ($notMatching as $field) {
|
||
if (!in_array($field, $allowedFields, true)) {
|
||
continue;
|
||
}
|
||
|
||
if ($field === 'relationship') {
|
||
$val = $tpaRecord['relation'] ?? null;
|
||
if ($val !== null && $val !== '') {
|
||
$updateData['relationship'] = $val;
|
||
}
|
||
continue;
|
||
}
|
||
|
||
if ($field === 'email_corporate') {
|
||
$val = $tpaRecord['email_corporate'] ?? $tpaRecord['email'] ?? null;
|
||
if ($val !== null && $val !== '') {
|
||
$updateData['email_corporate'] = $val;
|
||
}
|
||
continue;
|
||
}
|
||
|
||
$val = $tpaRecord[$field] ?? null;
|
||
if ($val !== null && $val !== '') {
|
||
$updateData[$field] = $val;
|
||
}
|
||
}
|
||
|
||
if ($updateData === []) {
|
||
continue;
|
||
}
|
||
|
||
if ($employeeModel->update($employeeId, $updateData)) {
|
||
$employeesUpdated++;
|
||
}
|
||
}
|
||
|
||
if ($employeesUpdated === 0) {
|
||
$this->myLogger->logme(
|
||
'error',
|
||
'updateEmployeeDataFromTpa: zero employee rows updated',
|
||
[
|
||
'batch_file_id' => $batchFileId,
|
||
'rows_skipped_no_diff' => $rowsSkippedNoDiff,
|
||
'rows_skipped_no_employee' => $rowsSkippedNoEmployee,
|
||
]
|
||
);
|
||
}
|
||
|
||
return [
|
||
'success' => true,
|
||
'message' => 'TPA-aligned employee updates applied where mismatches were reconciled.',
|
||
'data' => [
|
||
'batch_file_id' => $batchFileId,
|
||
'employees_updated' => $employeesUpdated,
|
||
'rows_skipped_no_diff' => $rowsSkippedNoDiff,
|
||
'rows_skipped_no_employee' => $rowsSkippedNoEmployee,
|
||
],
|
||
];
|
||
} catch (\Throwable $e) {
|
||
$this->myLogger->logme(
|
||
'error',
|
||
'updateEmployeeDataFromTpa failed: ' . json_encode([
|
||
'message' => $e->getMessage(),
|
||
'file' => $e->getFile(),
|
||
'line' => $e->getLine(),
|
||
], JSON_PRETTY_PRINT)
|
||
);
|
||
|
||
return [
|
||
'success' => false,
|
||
'message' => 'Unable to process the data from Need to Review tab.',
|
||
'data' => [],
|
||
];
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* @param array $params batch_file_id (required), file_id (optional, >0 filters employee_polices.file_id)
|
||
* @param mixed $jobId Optional queue job id when invoked from JobWorker (ignored).
|
||
*
|
||
* @return array{success:bool,message:string,data:array}
|
||
*/
|
||
public function updateTpaIdForNotInNhance($params, $jobId = null): array
|
||
{
|
||
try {
|
||
if (!is_array($params)) {
|
||
return [
|
||
'success' => false,
|
||
'message' => 'Invalid parameters.',
|
||
'data' => [],
|
||
];
|
||
}
|
||
|
||
$TpaApiDataModel = new TpaApiDataModel();
|
||
|
||
$fileId = (int) ($params['file_id'] ?? 0);
|
||
$batchFileId = (int) ($params['batch_file_id'] ?? 0);
|
||
|
||
if ($batchFileId <= 0) {
|
||
$this->myLogger->logme('error', 'Batch file ID missing in updateTpaIdForNotInNhance', ['params' => $params]);
|
||
|
||
return [
|
||
'success' => false,
|
||
'message' => 'Batch file ID is required.',
|
||
'data' => [],
|
||
];
|
||
}
|
||
|
||
$batchFileData = db_connect()->table('batch_files')->where('id', $batchFileId)->get()->getRowArray();
|
||
|
||
if (empty($batchFileData) || empty($batchFileData['client_policy_id'])) {
|
||
$this->myLogger->logme('error', 'Batch file not found or missing client_policy_id in updateTpaIdForNotInNhance', ['batch_file_id' => $batchFileId]);
|
||
|
||
return [
|
||
'success' => false,
|
||
'message' => 'Batch file not found or missing client policy.',
|
||
'data' => [],
|
||
];
|
||
}
|
||
|
||
$client_policy_data = $this->clientPolicyModel->where('id', $batchFileData['client_policy_id'])->first();
|
||
|
||
if (empty($client_policy_data)) {
|
||
$this->myLogger->logme('error', 'Client policy not found in updateTpaIdForNotInNhance', ['client_policy_id' => $batchFileData['client_policy_id']]);
|
||
|
||
return [
|
||
'success' => false,
|
||
'message' => 'Client policy not found.',
|
||
'data' => [],
|
||
];
|
||
}
|
||
|
||
// Get master emp codes from Nhance for this client & policy
|
||
$masterEmpRows = $this->employeePolicyModel->getTPADataVariationReport(
|
||
$batchFileData['client_id'],
|
||
$batchFileData['client_policy_id'],
|
||
$batchFileId,
|
||
[],
|
||
true
|
||
);
|
||
if (!is_array($masterEmpRows)) {
|
||
$masterEmpRows = [];
|
||
}
|
||
$masterEmpCodes = array_values(array_filter(
|
||
array_unique(array_column($masterEmpRows, 'emp_code')),
|
||
static fn ($code) => $code !== null && $code !== ''
|
||
));
|
||
|
||
// Fetch Not in Nhance rows for this batch file
|
||
$notInNhanceQuery = $TpaApiDataModel->select('*')
|
||
->where('is_active', 1)
|
||
->where('file_id', $batchFileId);
|
||
|
||
if ($masterEmpCodes !== []) {
|
||
$notInNhanceQuery->whereNotIn('emp_code', $masterEmpCodes);
|
||
}
|
||
|
||
$notInNhance = $notInNhanceQuery->findAll();
|
||
|
||
$uhidValue = $client_policy_data['policy_no'] ?? null;
|
||
|
||
$empPolicyIds = [];
|
||
foreach ($notInNhance as $tpaRow) {
|
||
$builder = $this->employeePolicyModel
|
||
->select('employee_polices.id')
|
||
->join('employees e', 'e.id = employee_polices.employee_id')
|
||
->where('e.name', $tpaRow['name'] ?? '')
|
||
->where('e.emp_code', $tpaRow['emp_code'] ?? '')
|
||
->where('e.dob', $tpaRow['dob'] ?? null)
|
||
->where('e.relationship', $tpaRow['relation'] ?? null)
|
||
->where('e.gender', $tpaRow['gender'] ?? null)
|
||
->where('employee_polices.client_policy_id', (int) $batchFileData['client_policy_id'])
|
||
->where('e.client_id', (int) $batchFileData['client_id']);
|
||
|
||
if ($fileId > 0) {
|
||
$builder->where('employee_polices.file_id', $fileId);
|
||
}
|
||
|
||
$empPolicyRow = $builder->first();
|
||
|
||
if (empty($empPolicyRow['id'])) {
|
||
continue;
|
||
}
|
||
|
||
$epId = (int) $empPolicyRow['id'];
|
||
if ($this->employeePolicyModel->update($epId, [
|
||
'tpa_id' => $tpaRow['tpa_id'] ?? null,
|
||
'uhid' => $uhidValue,
|
||
])) {
|
||
$empPolicyIds[] = $epId;
|
||
}
|
||
}
|
||
|
||
if ($empPolicyIds === []) {
|
||
$this->myLogger->logme(
|
||
'warning',
|
||
'updateTpaIdForNotInNhance: zero employee_policy rows updated',
|
||
[
|
||
'batch_file_id' => $batchFileId,
|
||
'not_in_nhance_count' => count($notInNhance),
|
||
]
|
||
);
|
||
}
|
||
|
||
return [
|
||
'success' => true,
|
||
'message' => 'TPA id / UHID applied on matching employee policies for Not in Nhance rows.',
|
||
'data' => [
|
||
'employee_policies_updated' => count($empPolicyIds),
|
||
'employee_policy_ids' => $empPolicyIds,
|
||
],
|
||
];
|
||
} catch (\Throwable $e) {
|
||
$this->myLogger->logme(
|
||
'error',
|
||
'updateTpaIdForNotInNhance exception: ' . $e->getMessage(),
|
||
['params' => $params, 'trace' => $e->getTraceAsString()]
|
||
);
|
||
|
||
return [
|
||
'success' => false,
|
||
'message' => 'Unexpected error while updating TPA id from Not in Nhance data.',
|
||
'data' => [],
|
||
];
|
||
}
|
||
}
|
||
|
||
|
||
// 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'
|
||
];
|
||
}
|
||
|
||
/**
|
||
* Convert a single variation-report date value to dd/mm/yyyy for display.
|
||
*/
|
||
private function formatVariationReportDateField($value): string
|
||
{
|
||
if ($value === null || $value === '') {
|
||
return '';
|
||
}
|
||
|
||
$formatted = change_date_format((string) $value, null, 'd/m/Y');
|
||
|
||
return ($formatted !== null && $formatted !== '') ? (string) $formatted : (string) $value;
|
||
}
|
||
|
||
/**
|
||
* Format known date columns on one variation-report row (TPA or DB).
|
||
*/
|
||
private function formatVariationReportRowDates(array $row, array $dateFields = ['dob', 'doj']): array
|
||
{
|
||
foreach ($dateFields as $field) {
|
||
if (!array_key_exists($field, $row)) {
|
||
continue;
|
||
}
|
||
if ($row[$field] === null || $row[$field] === '') {
|
||
continue;
|
||
}
|
||
$row[$field] = $this->formatVariationReportDateField($row[$field]);
|
||
}
|
||
|
||
return $row;
|
||
}
|
||
|
||
/**
|
||
* Apply dd/mm/yyyy formatting to all variation-report payloads returned to the UI/export.
|
||
*/
|
||
private function formatVariationReportDataForDisplay(
|
||
array &$notInTpa,
|
||
array &$notInNhance,
|
||
array &$mismatchData
|
||
): void {
|
||
foreach ($notInTpa as $idx => $row) {
|
||
$notInTpa[$idx] = $this->formatVariationReportRowDates($row);
|
||
}
|
||
|
||
foreach ($notInNhance as $idx => $row) {
|
||
$notInNhance[$idx] = $this->formatVariationReportRowDates($row);
|
||
}
|
||
|
||
foreach ($mismatchData as $idx => $row) {
|
||
$row = $this->formatVariationReportRowDates($row);
|
||
if (isset($row['match']['tpa_record']) && is_array($row['match']['tpa_record'])) {
|
||
$row['match']['tpa_record'] = $this->formatVariationReportRowDates($row['match']['tpa_record']);
|
||
}
|
||
$mismatchData[$idx] = $row;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Pair one Nhance policy row with a TPA API row for the same emp_code.
|
||
*
|
||
* When multiple dependents share a relation (e.g. two Sons), candidates are scored
|
||
* on name / DOB / gender and the best unique match wins. Already-paired TPA ids
|
||
* (same emp_code) can be passed via $excludeTpaIds so each TPA row maps once.
|
||
*/
|
||
public function reconcileDbWithTpa(array $db, array $tpaRows, array $excludeTpaIds = []): array
|
||
{
|
||
$normalizeName = static function ($name) {
|
||
return strtolower(
|
||
preg_replace('/[.\s_]+/', '', trim((string) $name))
|
||
);
|
||
};
|
||
|
||
$normalizeRelation = static function ($relation) {
|
||
return strtolower(trim((string) $relation));
|
||
};
|
||
|
||
$dbRel = $normalizeRelation($db['relationship'] ?? '');
|
||
|
||
$candidates = [];
|
||
foreach ($tpaRows as $tpa) {
|
||
if (isset($tpa['match']['status']) && $tpa['match']['status'] === 'matched') {
|
||
continue;
|
||
}
|
||
|
||
$tpaId = (int) ($tpa['id'] ?? 0);
|
||
if ($tpaId > 0 && in_array($tpaId, $excludeTpaIds, true)) {
|
||
continue;
|
||
}
|
||
|
||
if ($normalizeRelation($tpa['relation'] ?? '') !== $dbRel) {
|
||
continue;
|
||
}
|
||
|
||
$candidates[] = $tpa;
|
||
}
|
||
|
||
if ($candidates === []) {
|
||
return ['status' => 'no_match'];
|
||
}
|
||
|
||
$scoreCandidate = static function (array $tpa) use ($db, $normalizeName) {
|
||
$score = 0;
|
||
if ($normalizeName($db['name'] ?? '') === $normalizeName($tpa['name'] ?? '')) {
|
||
$score += 4;
|
||
}
|
||
if ((string) ($db['dob'] ?? '') === (string) ($tpa['dob'] ?? '')) {
|
||
$score += 2;
|
||
}
|
||
if (strtoupper(trim((string) ($db['gender'] ?? ''))) === strtoupper(trim((string) ($tpa['gender'] ?? '')))) {
|
||
$score += 1;
|
||
}
|
||
|
||
return $score;
|
||
};
|
||
|
||
$bestTpa = null;
|
||
$bestScore = -1;
|
||
foreach ($candidates as $tpa) {
|
||
$score = $scoreCandidate($tpa);
|
||
if ($score > $bestScore) {
|
||
$bestScore = $score;
|
||
$bestTpa = $tpa;
|
||
}
|
||
}
|
||
|
||
if ($bestTpa === null) {
|
||
return ['status' => 'no_match'];
|
||
}
|
||
|
||
// Multiple Son/Daughter rows: require a unique tie-breaker (name or DOB).
|
||
if (count($candidates) > 1) {
|
||
$topCount = 0;
|
||
foreach ($candidates as $tpa) {
|
||
if ($scoreCandidate($tpa) === $bestScore) {
|
||
$topCount++;
|
||
}
|
||
}
|
||
if ($topCount > 1 || $bestScore < 2) {
|
||
return ['status' => 'no_match'];
|
||
}
|
||
}
|
||
|
||
$diff = [];
|
||
|
||
if ($normalizeName($db['name'] ?? '') !== $normalizeName($bestTpa['name'] ?? '')) {
|
||
$diff[] = 'name';
|
||
}
|
||
|
||
if ((string) ($db['dob'] ?? '') !== (string) ($bestTpa['dob'] ?? '')) {
|
||
$diff[] = 'dob';
|
||
}
|
||
|
||
if (
|
||
strtoupper(trim((string) ($db['gender'] ?? ''))) !==
|
||
strtoupper(trim((string) ($bestTpa['gender'] ?? '')))
|
||
) {
|
||
$diff[] = 'gender';
|
||
}
|
||
|
||
return [
|
||
'status' => 'matched',
|
||
'tpa_record' => $bestTpa,
|
||
'not_matching' => $diff,
|
||
];
|
||
}
|
||
|
||
public 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;
|
||
}
|
||
|
||
public function bulkGenerateEcardAndStoreinS3(array $params = [])
|
||
{
|
||
$request = \Config\Services::request();
|
||
$isCli = is_cli();
|
||
|
||
/* ---------------------------------------------------------
|
||
* 1. INPUTS (shared for WEB + CLI)
|
||
* --------------------------------------------------------- */
|
||
$client_policy_id = $params['client_policy_id'] ?? (!$isCli ? $request->getGet('client_policy_id') : null);
|
||
$emp_code = $params['emp_code'] ?? (!$isCli ? $request->getGet('emp_code') : null);
|
||
$emp_pk = $params['emp_pk'] ?? (!$isCli ? $request->getGet('emp_pk') : null);
|
||
|
||
$batch_size = (int) ($params['batch_size'] ?? (!$isCli ? $request->getGet('batch_size') : 100));
|
||
$batch_size = $batch_size > 0 ? $batch_size : 100;
|
||
|
||
$batch_no = isset($params['batch_no']) ? (int) $params['batch_no'] : null;
|
||
$total_batches = (int) ($params['total_batches'] ?? 0);
|
||
$execution_mode = $params['execution_mode'] ?? (!$isCli ? $request->getGet('execution_mode') : 'sequential');
|
||
$execution_mode = in_array($execution_mode, ['sequential', 'parallel']) ? $execution_mode : 'sequential';
|
||
$is_dry_run = $params['is_dry_run'] ?? (!$isCli ? $request->getGet('is_dry_run') : false);
|
||
|
||
$log_search_context = 'ECARD_BULK_TO_S3';
|
||
if($is_dry_run)
|
||
{
|
||
$log_search_context = 'ECARD_BULK_TO_S3_DRY_RUN';
|
||
}
|
||
|
||
// Cursor (KEY FIX: avoids OFFSET issues)
|
||
$last_emp_id = (int) ($params['last_emp_id'] ?? 0);
|
||
|
||
$this->myLogger->logme('error', "$log_search_context"." INIT - ". json_encode([
|
||
'cli' => $isCli,
|
||
'policy' => $client_policy_id,
|
||
'batch_no' => $batch_no,
|
||
'last_emp_id' => $last_emp_id,
|
||
'mode' => $execution_mode,
|
||
'is_dry_run' => $is_dry_run
|
||
]));
|
||
|
||
/* ---------------------------------------------------------
|
||
* 2. WEB DISPATCHER (QUEUE CREATOR)
|
||
* --------------------------------------------------------- */
|
||
if (!$isCli && empty($params)) {
|
||
|
||
if (empty($client_policy_id)) {
|
||
return $this->respond(['status' => false, 'message' => 'client_policy_id required'], 200);
|
||
}
|
||
|
||
// COUNT QUERY (same filters as worker)
|
||
$countBuilder = $this->employeePolicyModel->builder()
|
||
->join('employees', 'employees.id = employee_polices.employee_id')
|
||
->where([
|
||
'employees.emp_status' => 'active',
|
||
'employees.is_active' => '1',
|
||
'employee_polices.status' => 'active',
|
||
'employee_polices.is_active' => '1',
|
||
'employee_polices.client_policy_id' => $client_policy_id
|
||
])
|
||
->where("employee_polices.tpa_id IS NOT NULL AND employee_polices.tpa_id <> ''");
|
||
|
||
if ($emp_code) $countBuilder->where('employees.emp_code', $emp_code);
|
||
if ($emp_pk) $countBuilder->where('employees.id', $emp_pk);
|
||
|
||
$total = (int) $countBuilder->countAllResults();
|
||
|
||
if ($total === 0) {
|
||
$this->myLogger->logme('error', "$log_search_context". 'No records found. Queue skipped.');
|
||
return $this->respond(['status' => 'NO_RECORDS'], 200);
|
||
}
|
||
|
||
$total_batches = (int) ceil($total / $batch_size);
|
||
|
||
$this->myLogger->logme('error', "$log_search_context".'Queueing jobs - '. json_encode([
|
||
'total' => $total,
|
||
'batches' => $total_batches,
|
||
'mode' => $execution_mode
|
||
]));
|
||
|
||
$basePayload = [
|
||
'client_policy_id' => $client_policy_id,
|
||
'batch_size' => $batch_size,
|
||
'total_batches' => $total_batches,
|
||
'execution_mode' => $execution_mode,
|
||
'emp_code' => $emp_code,
|
||
'emp_pk' => $emp_pk,
|
||
'last_emp_id' => 0,
|
||
'is_dry_run' => $is_dry_run
|
||
];
|
||
|
||
if ($execution_mode === 'parallel') {
|
||
for ($i = 1; $i <= $total_batches; $i++) {
|
||
Jobs::addJob([
|
||
'job_name' => 'bulkGenerateEcardAndStoreinS3',
|
||
'payload' => array_merge($basePayload, ['batch_no' => $i])
|
||
]);
|
||
}
|
||
} else {
|
||
Jobs::addJob([
|
||
'job_name' => 'bulkGenerateEcardAndStoreinS3',
|
||
'payload' => array_merge($basePayload, ['batch_no' => 1])
|
||
]);
|
||
}
|
||
|
||
return $this->respond([
|
||
'status' => 'ECARD_BULK_TO_S3 Job queued',
|
||
'message' => 'E-card re-generation process has started successfully.',
|
||
'dataStatus' => true,
|
||
'total' => $total,
|
||
'batches' => $total_batches
|
||
], 200);
|
||
}
|
||
|
||
/* ---------------------------------------------------------
|
||
* 3. CLI WORKER (ACTUAL PROCESSOR)
|
||
* --------------------------------------------------------- */
|
||
if ($batch_no === null) {
|
||
$this->myLogger->logme('error', "$log_search_context".'Worker called without batch_no');
|
||
return;
|
||
}
|
||
|
||
$this->myLogger->logme('error', "$log_search_context"."START Batch {$batch_no}");
|
||
|
||
$builder = $this->employeePolicyModel->builder();
|
||
$builder->select('
|
||
employee_polices.client_policy_id,
|
||
employees.emp_code,
|
||
employees.id as emp_id,
|
||
tpa.short_name,
|
||
employees.client_id,
|
||
employee_polices.rand_string
|
||
')
|
||
->join('client_policy', 'client_policy.id = employee_polices.client_policy_id')
|
||
->join('employees', 'employees.id = employee_polices.employee_id')
|
||
->join('tpa', 'tpa.id = client_policy.tpa_id')
|
||
->where([
|
||
'employees.emp_status' => 'active',
|
||
'employees.is_active' => '1',
|
||
'employee_polices.status' => 'active',
|
||
'employee_polices.is_active' => '1',
|
||
'employee_polices.client_policy_id' => $client_policy_id
|
||
])
|
||
->where("employee_polices.tpa_id IS NOT NULL AND employee_polices.tpa_id <> ''")
|
||
->orderBy('employees.id', 'ASC');
|
||
|
||
if ($emp_code) $builder->where('employees.emp_code', $emp_code);
|
||
if ($emp_pk) $builder->where('employees.id', $emp_pk);
|
||
if ($last_emp_id) $builder->where('employees.id >', $last_emp_id);
|
||
|
||
$rows = $builder->get($batch_size)->getResultArray();
|
||
$rowCount = count($rows);
|
||
|
||
$this->myLogger->logme('error', "$log_search_context"." Batch {$batch_no} fetched {$rowCount} rows");
|
||
|
||
if ($rowCount === 0) {
|
||
$this->myLogger->logme('error', "$log_search_context"." Batch {$batch_no} empty. STOPPING.");
|
||
return;
|
||
}
|
||
|
||
foreach ($rows as $row) {
|
||
$this->myLogger->logme('error', "$log_search_context".' Processing - '. json_encode([
|
||
'emp_id' => $row['emp_id'],
|
||
'emp_code' => $row['emp_code'],
|
||
'policy' => $row['client_policy_id']
|
||
]));
|
||
|
||
if(!$is_dry_run) //for tesing skip generate ecard and just log only
|
||
{
|
||
$ecard_gen_res = $this->generateIDCardForEmployee($row['rand_string'],0,2); // 2 means skip S3 check
|
||
}
|
||
|
||
$this->myLogger->logme('error', "$log_search_context".' processed - '. json_encode([
|
||
'emp_id' => $row['emp_id'],
|
||
'emp_code' => $row['emp_code'],
|
||
'policy' => $row['client_policy_id'],
|
||
// 'ecard_gen_res' => $ecard_gen_res
|
||
]));//check
|
||
}
|
||
|
||
$new_last_emp_id = end($rows)['emp_id'];
|
||
|
||
/* ---------------------------------------------------------
|
||
* 4. SEQUENTIAL RE-QUEUE (SAFE)
|
||
* --------------------------------------------------------- */
|
||
if ($execution_mode === 'sequential' && $rowCount === $batch_size) {
|
||
$this->myLogger->logme('error', "$log_search_context"."Re-queueing next batch - " . json_encode([
|
||
'next_batch' => $batch_no + 1,
|
||
'last_emp_id' => $new_last_emp_id
|
||
]));
|
||
|
||
Jobs::addJob([
|
||
'job_name' => 'bulkGenerateEcardAndStoreinS3',
|
||
'payload' => [
|
||
'client_policy_id' => $client_policy_id,
|
||
'batch_size' => $batch_size,
|
||
'batch_no' => $batch_no + 1,
|
||
'execution_mode' => 'sequential',
|
||
'last_emp_id' => $new_last_emp_id,
|
||
'emp_code' => $emp_code,
|
||
'emp_pk' => $emp_pk,
|
||
'is_dry_run' => $is_dry_run
|
||
]
|
||
]);
|
||
}
|
||
|
||
$this->myLogger->logme('error', "$log_search_context". "END Batch {$batch_no}");
|
||
}
|
||
|
||
public function visitOffBoardCheck()
|
||
{
|
||
$params = [
|
||
"memberIds" => ["adi_1034292323", "EMPENHANCE-M1", "EMPENHANCE-M3"],
|
||
// "policyNumber" => "570000/48/2026/290",
|
||
"policyNumber" => "09823428509239",
|
||
"source" => "NHANCE"
|
||
];
|
||
print_rr($this->visitOffBoard($params));
|
||
}
|
||
|
||
/**
|
||
* Executes the Delete Policy API call.
|
||
*
|
||
* @param array $params Contains 'memberIds', 'policyNumber', and 'source'.
|
||
* @return array
|
||
*/
|
||
public function visitOffBoard(array $params)
|
||
{
|
||
// 1. Load credentials from .env
|
||
$apiUrl = env('WELLNESS_ONBOARD_ENDPOINT_URL').'delete-policy-with-dependents';
|
||
$apiToken = env('WELLNESS_ONBOARD_AUTHORIZATION');
|
||
// echo $apiUrl;die();
|
||
// 2. Initialize the CI4 CURL service
|
||
$client = \Config\Services::curlrequest([
|
||
'base_uri' => $apiUrl,
|
||
'timeout' => 30,
|
||
]);
|
||
|
||
// $client = Services::curlrequest([
|
||
// 'base_uri' => $apiUrl,
|
||
// 'timeout' => 30,
|
||
// ]);
|
||
$params['source'] = 'NHANCE';
|
||
try {
|
||
// Log the start of the request for traceability
|
||
$this->myLogger->logme('error', 'VISIT_OFFBOARD: ' . ($params['policyNumber'] ?? 'N/A'));
|
||
|
||
// 3. Perform the POST request
|
||
$response = $client->request('POST', '', [
|
||
'headers' => [
|
||
'Authorization' => 'JWT ' . $apiToken,
|
||
'Content-Type' => 'application/json',
|
||
'Accept' => 'application/json',
|
||
],
|
||
'json' => [
|
||
'memberIds' => $params['memberIds'] ?? [],
|
||
'policyNumber' => $params['policyNumber'] ?? '',
|
||
'source' => $params['source'] ?? '',
|
||
],
|
||
'http_errors' => false, // Prevents throwing exceptions on 4xx/5xx responses
|
||
]);
|
||
|
||
$statusCode = $response->getStatusCode();
|
||
$rawBody = $response->getBody();
|
||
$result = json_decode($rawBody, true);
|
||
// print_rr($result);
|
||
|
||
// 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_data = [
|
||
'memberIds' => $params['memberIds'] ?? [],
|
||
'api_result' => $result
|
||
];
|
||
$this->updateVisitoffboardStatus($return_data);
|
||
return $return_data;
|
||
}
|
||
|
||
// Log API-level errors (4xx or 5xx)
|
||
$this->myLogger->logme('error', "VISIT_OFFBOARD API Failure (Code $statusCode): " . json_encode($rawBody));
|
||
return [
|
||
'status' => false,
|
||
'message' => 'The API returned an error response.',
|
||
'code' => $statusCode,
|
||
'details' => $result
|
||
];
|
||
|
||
} catch (\Exception $e) {
|
||
// 5. Catch network or system exceptions
|
||
$this->myLogger->logme('error', 'VISIT_OFFBOARD API Exception: ' . $e->getMessage());
|
||
return [
|
||
'status' => false,
|
||
'message' => 'A critical error occurred while contacting the API.',
|
||
'error' => $e->getMessage()
|
||
];
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 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);
|
||
|
||
if(empty($post_data) || (!isset($post_data['mails']) && !empty($post_data['mails'])) || (!isset($post_data['client_id']) && !empty($post_data['client_id']))){
|
||
return $this->respond(['status' => false, 'code' => 404, 'message' => 'No data send mail'], 200);
|
||
}
|
||
|
||
$client_data = $this->clientModel->where('is_active', 1)->where('id', $post_data['client_id'])->first();
|
||
|
||
if(empty($client_data)){
|
||
return $this->respond(['status' => false, 'code' => 404, 'message' => 'No client found'], 200);
|
||
}
|
||
|
||
$notificationModal = new NotificationModel();
|
||
$notification_data = $notificationModal
|
||
->where('client_id', $post_data['client_id'])
|
||
->where('template_name', 'hr_cd_insufficient_balance_mail')
|
||
->first();
|
||
|
||
if(empty($notification_data)){
|
||
return $this->respond(['status' => false, 'code' => 404, 'message' => 'No template found'], 200);
|
||
}
|
||
|
||
if(empty($notification_data['subject']) || empty($notification_data['mail_content'])){
|
||
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Template subject or mail content is empty'], 200);
|
||
}
|
||
|
||
if(empty($notification_data['enabled']) || $notification_data['enabled'] != 1){
|
||
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Template is disabled'], 200);
|
||
|
||
}
|
||
|
||
$common['mail_type'] = "hr_cd_insufficient_balance_mail";
|
||
$common['client_id'] = $post_data['client_id'];
|
||
$subject = $notification_data['subject'];
|
||
$mail_content = $notification_data['mail_content'];
|
||
|
||
foreach ($post_data['mails'] as $hr_id => $hr_data) {
|
||
|
||
$mail_content = str_ireplace('{{hr_name}}', $hr_data['name'], $mail_content);
|
||
$mail_content = str_ireplace('{{client_name}}', $client_data['client_name'], $mail_content);
|
||
$res = MailHelper::send_email(['mail' => $hr_data['mail'], 'subject' => $subject, 'message' => $mail_content, 'common' => $common]);
|
||
}
|
||
|
||
return $this->respond(['status' => true, 'code' => 200, 'message' => 'Mail send successfully'], 200);
|
||
|
||
}
|
||
|
||
public function clearCdSession()
|
||
{
|
||
clear_cd_balance_session();
|
||
return $this->response->setJSON(['status' => 'cleared']);
|
||
}
|
||
|
||
public function checkSessionStatus()
|
||
{
|
||
// Uses your existing get_cd_balance() helper
|
||
$data = get_cd_balance();
|
||
|
||
// Return as JSON so JavaScript can read it
|
||
return $this->response->setJSON($data);
|
||
}
|
||
|
||
public function bulkEcardDownloadAsZipFromS3($params)
|
||
{
|
||
try {
|
||
$limit = $params['limit'] ?? 100;
|
||
$batch_no = $params['batch_no'] ?? 1;
|
||
$last_id = $params['last_emp_policy_id'] ?? 0;
|
||
|
||
// Fetch batch data
|
||
$employee_data = $this->employeePolicyModel->getEmployeeDataWithPolicyUsingClientPolicyIdOrEmployeePolicyIds($params, $limit, $last_id);
|
||
|
||
if (empty($employee_data)) {
|
||
|
||
if(!empty($last_id)){
|
||
$this->myLogger->logme('error', "bulkEcardDownloadAsZipFromS3 - No more records after last_emp_policy_id: {$last_id}");
|
||
$this->myLogger->logme('error', "getEmployeeEcardFromTmpFolderAndZipToS3 - Queuing ZIP creation for folder: " . ($params['folder_name'] ?? 'N/A'));
|
||
$r = Jobs::addJob(['job_name' => 'getEmployeeEcardFromTmpFolderAndZipToS3', 'payload' => $params]);
|
||
}
|
||
|
||
return ['status' => true, 'message' => 'Proceeding to Zip'];
|
||
}
|
||
|
||
// Use a consistent folder name across batches (passed in params)
|
||
$folderName = $params['folder_name'] ?? 'bulk_ecards_' . $employee_data[0]['policy_no'] . '_' . date('Y-m-d_H-i-s');
|
||
$tempPath = FCPATH . 'tmp/' . $folderName . '/';
|
||
|
||
if (!is_dir($tempPath)) {
|
||
mkdir($tempPath, 0777, true);
|
||
}
|
||
|
||
$s3 = \Config\Services::getS3Service();
|
||
$pdf_count = 0;
|
||
$current_last_id = end($employee_data)['emp_policy_id'];
|
||
|
||
foreach ($employee_data as $emp_value) {
|
||
// Track the last ID in this batch
|
||
$current_last_id = $emp_value['emp_policy_id'];
|
||
|
||
$s3_key = 'ecard_' . $emp_value['name'] . '(' . $emp_value['emp_code'] . ')' . '_' . $emp_value['tpa_id'] . '.pdf';
|
||
$s3_key = $this->sanitizeFilePart($s3_key);
|
||
|
||
if ($s3->exists($s3_key)) {
|
||
$s3_url = $s3->getPresignedUrl($s3_key);
|
||
$pdf_content = file_get_contents($s3_url['url']);
|
||
|
||
if ($pdf_content !== false) {
|
||
file_put_contents($tempPath . $s3_key, $pdf_content);
|
||
$pdf_count++;
|
||
}
|
||
}
|
||
}
|
||
|
||
$hasMore = count($employee_data) == $limit;
|
||
|
||
$payload = [
|
||
'batch_no' => $batch_no + 1,
|
||
'last_emp_policy_id' => $current_last_id,
|
||
'folder_name' => $folderName,
|
||
'processed_in_this_batch_data_count' => count($employee_data),
|
||
'pdf_count' => $pdf_count,
|
||
'hr_id' => $params['hr_id'] ?? null
|
||
];
|
||
|
||
if ($hasMore) {
|
||
$this->myLogger->logme('error', "bulkEcardDownloadAsZipFromS3 - Queuing next batch: " . json_encode($payload));
|
||
$r = Jobs::addJob(['job_name' => 'bulkEcardDownloadAsZipFromS3', 'payload' => $payload]);
|
||
$message = "Queuing next batch";
|
||
} else {
|
||
$this->myLogger->logme('error', "bulkEcardDownloadAsZipFromS3 - No more records after this batch. Next proceeding with getEmployeeEcardFromTmpFolderAndZipToS3");
|
||
$r = Jobs::addJob(['job_name' => 'getEmployeeEcardFromTmpFolderAndZipToS3', 'payload' => $payload]);
|
||
$message = "All batch completed. Next proceeding with getEmployeeEcardFromTmpFolderAndZipToS3";
|
||
}
|
||
|
||
return ['status' => true, 'message' => $message];
|
||
|
||
} catch (\Throwable $e) {
|
||
|
||
$mail_response = $this->sendMailToHrWithZipAttachments($params);
|
||
|
||
$context = [
|
||
'error_message' => $e->getMessage(),
|
||
'exception_class' => get_class($e),
|
||
'file' => $e->getFile(),
|
||
'line' => $e->getLine(),
|
||
'trace' => $e->getTraceAsString(),
|
||
'mail_response' => $mail_response,
|
||
'params' => $params,
|
||
];
|
||
|
||
// Log detailed context for debugging
|
||
$this->myLogger->logme('error', 'bulkEcardDownloadAsZipFromS3 - Exception' . json_encode($context, JSON_PRETTY_PRINT));
|
||
|
||
// Return a detailed, structured error response
|
||
return [
|
||
'status' => false,
|
||
'message' => 'Exception occurred during bulk e-card download and ZIP creation.',
|
||
'error' => $context,
|
||
];
|
||
}
|
||
}
|
||
|
||
public function getEmployeeEcardFromTmpFolderAndZipToS3($params)
|
||
{
|
||
try {
|
||
|
||
$zipService = new \App\Libraries\ZipService();
|
||
|
||
$source = FCPATH . 'tmp/' . $params['folder_name'];
|
||
$destination = '/';
|
||
$zipName = $params['folder_name'] . '.zip' ?? '';
|
||
|
||
$result = $zipService->zipAndUploadS3($source, $destination, $zipName);
|
||
|
||
if($result['status'] === false){
|
||
$this->myLogger->logme('error', "getEmployeeEcardFromTmpFolderAndZipToS3 - ZIP creation/upload failed: " . json_encode($result));
|
||
$params['url'] = null; // Indicate failure
|
||
}else{
|
||
$params['url'] = $result['presigned_url']['url'] ?? null;
|
||
}
|
||
|
||
|
||
|
||
|
||
$mail_response = $this->sendMailToHrWithZipAttachments($params);
|
||
|
||
return ['zip_responce' => $result, 'mail_response' => $mail_response];
|
||
|
||
} catch (\Throwable $e) {
|
||
|
||
$mail_response = $this->sendMailToHrWithZipAttachments($params);
|
||
|
||
$context = [
|
||
'error_message' => $e->getMessage(),
|
||
'exception_class' => get_class($e),
|
||
'file' => $e->getFile(),
|
||
'line' => $e->getLine(),
|
||
'trace' => $e->getTraceAsString(),
|
||
'mail_response' => $mail_response,
|
||
'params' => $params,
|
||
];
|
||
|
||
// Log detailed context for debugging
|
||
$this->myLogger->logme('error', 'getEmployeeEcardFromTmpFolderAndZipToS3 - Exception' . json_encode($context, JSON_PRETTY_PRINT));
|
||
|
||
// Return a detailed, structured error response
|
||
return [
|
||
'status' => false,
|
||
'message' => 'Exception occurred during bulk e-card download and ZIP creation.',
|
||
'error' => $context,
|
||
];
|
||
|
||
}
|
||
}
|
||
|
||
public function sendMailToHrWithZipAttachments($params)
|
||
{
|
||
$hr_id = $params['hr_id'] ?? null;
|
||
$url = $params['url'] ?? null;
|
||
|
||
if (empty($hr_id)) {
|
||
$this->myLogger->logme('error', "sendMailToHrWithZipAttachments - No HR ID provided.");
|
||
return ['status' => false, 'message' => 'No HR ID provided.'];
|
||
}
|
||
|
||
$hr_data = $this->LevelContactModel->where('id', $hr_id)->where('is_active', 1)->first();
|
||
|
||
if (empty($hr_data) || empty($hr_data['email'])) {
|
||
$this->myLogger->logme('error', "sendMailToHrWithZipAttachments - No valid HR data found for ID: {$hr_id}");
|
||
return ['status' => false, 'message' => 'No valid HR data found for ID: ' . $hr_id];
|
||
}
|
||
|
||
if(empty($url)){
|
||
$subject = "Employee Bulk E-Card Download Failed";
|
||
$message = "Dear {$hr_data['name']},<br><br>We were unable to generate the bulk e-card ZIP file. Please re-initialize the process or contact support to retry.";
|
||
}else{
|
||
$subject = "Employee Bulk E-Cards Download";
|
||
$message = "Dear {$hr_data['name']},<br><br>Please find the employee e-cards attached below.<br><br>Download Link: <a href='{$url}'>Download E-Cards</a><br><br>Note : This link valid for 2 days only.";
|
||
}
|
||
|
||
$bbc = 'venkateshraman786@gmail.com';
|
||
|
||
$mail_response = MailHelper::send_email([
|
||
'mail' => $hr_data['email'],
|
||
'subject' => $subject,
|
||
'message' => $message,
|
||
'bcc' => $bbc,
|
||
'common' => [
|
||
'mail_type' => 'employee_bulk_ecard_download_by_hr',
|
||
]
|
||
]);
|
||
|
||
$this->myLogger->logme('error', "sendMailToHrWithZipAttachments - Email sent to HR ID: {$hr_id}, Email Response: " . json_encode($mail_response));
|
||
return $mail_response;
|
||
}
|
||
|
||
|
||
|
||
public function bulkEcardDownloadAsZipFromS3New($params)
|
||
{
|
||
try {
|
||
|
||
$limit = $params['limit'] ?? 100;
|
||
$last_id = $params['last_id'] ?? 0;
|
||
$zip_id = $params['zip_id'];
|
||
|
||
$employee_data = $this->employeePolicyModel->getEmployeeDataWithPolicyUsingClientPolicyIdOrEmployeePolicyIds($params, $limit, $last_id);
|
||
|
||
if (empty($employee_data)) {
|
||
// No more records, move to Zipping phase
|
||
return Jobs::addJob(['job_name' => 'getEmployeeEcardFromTmpFolderAndZipToS3', 'payload' => $params]);
|
||
}
|
||
|
||
$tempPath = FCPATH . 'tmp/' . $params['folder_name'] . '/';
|
||
if (!is_dir($tempPath)) mkdir($tempPath, 0777, true);
|
||
|
||
$s3 = \Config\Services::getS3Service();
|
||
$current_last_id = $last_id;
|
||
$pdf_count = 0;
|
||
|
||
foreach ($employee_data as $emp) {
|
||
$current_last_id = $emp['emp_policy_id'];
|
||
|
||
|
||
$s3_key = 'ecard_' . $emp['name'] . '(' . $emp['emp_code'] . ')' . '_' . $emp['tpa_id'] . '.pdf';
|
||
$s3_key = $this->sanitizeFilePart($s3_key);
|
||
|
||
if ($s3->exists($s3_key)) {
|
||
$s3_url = $s3->getPresignedUrl($s3_key);
|
||
$pdf_content = file_get_contents($s3_url['url']);
|
||
|
||
if ($pdf_content !== false) {
|
||
file_put_contents($tempPath . $s3_key, $pdf_content);
|
||
$pdf_count++;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Check if we need more batches
|
||
$params['last_id'] = $current_last_id;
|
||
$params['pdf_count'] = $pdf_count;
|
||
$params['batch_no'] = ($params['batch_no'] ?? 1) + 1;
|
||
|
||
if (count($employee_data) == $limit) {
|
||
return Jobs::addJob(['job_name' => 'bulkEcardDownloadAsZipFromS3', 'payload' => $params]);
|
||
} else {
|
||
return Jobs::addJob(['job_name' => 'getEmployeeEcardFromTmpFolderAndZipToS3', 'payload' => $params]);
|
||
}
|
||
|
||
} catch (\Throwable $e) {
|
||
$this->logAndNotifyError($e, $params);
|
||
}
|
||
}
|
||
|
||
public function getEmployeeEcardFromTmpFolderAndZipToS3New($params)
|
||
{
|
||
try {
|
||
$zipService = new \App\Libraries\ZipService();
|
||
$source = FCPATH . 'tmp/' . $params['folder_name'];
|
||
$zipName = $params['folder_name'] . '.zip';
|
||
$s3_dest_key = 'exports/zips/' . $zipName;
|
||
|
||
// 1. Create Zip and Upload
|
||
$result = $zipService->zipAndUploadS3($source, $s3_dest_key);
|
||
|
||
if ($result['status']) {
|
||
// 2. IMPORTANT: Update the Activity Record with the S3 Key
|
||
$history = $this->UserActivityHistoryModel->find($params['zip_id']);
|
||
$misc = json_decode($history['misc_data'], true);
|
||
$misc['status'] = 'completed';
|
||
$misc['s3_key'] = $s3_dest_key;
|
||
|
||
$this->UserActivityHistoryModel->update($params['zip_id'], [
|
||
'misc_data' => json_encode($misc)
|
||
]);
|
||
|
||
$params['url'] = base_url('downloadEmployeeEcardZip/' . md5($params['zip_id']));
|
||
}
|
||
|
||
// 3. Cleanup local files
|
||
$this->recursiveRemoveDir($source);
|
||
|
||
// 4. Email HR
|
||
return $this->sendMailToHrWithZipAttachments($params);
|
||
|
||
} catch (\Throwable $e) {
|
||
$this->logAndNotifyError($e, $params);
|
||
}
|
||
}
|
||
|
||
public function downloadEmployeeEcardZip($md5Id)
|
||
{
|
||
// Search by MD5 of ID
|
||
$data = $this->UserActivityHistoryModel->where('MD5(CAST(id AS CHAR))', $md5Id)->first();
|
||
|
||
if (!$data) return "File link expired or invalid.";
|
||
|
||
$misc = json_decode($data['misc_data'], true);
|
||
$s3Key = $misc['s3_key'] ?? null;
|
||
|
||
if (!$s3Key) return "File is still processing or failed to generate.";
|
||
|
||
$s3 = \Config\Services::getS3Service();
|
||
$presigned = $s3->getPresignedUrl($s3Key, 15); // 15 mins expiry
|
||
|
||
return redirect()->to($presigned['url']);
|
||
}
|
||
|
||
private function logAndNotifyError($e, $params)
|
||
{
|
||
$this->myLogger->logme('error', "[ECARD_ZIP]: " . $e->getMessage());
|
||
$params['url'] = null; // Forces "Failed" email
|
||
$this->sendMailToHrWithZipAttachments($params);
|
||
}
|
||
|
||
private function recursiveRemoveDir($dir)
|
||
{
|
||
if (!is_dir($dir)) return;
|
||
$files = array_diff(scandir($dir), array('.', '..'));
|
||
foreach ($files as $file) {
|
||
(is_dir("$dir/$file")) ? $this->recursiveRemoveDir("$dir/$file") : unlink("$dir/$file");
|
||
}
|
||
return rmdir($dir);
|
||
}
|
||
|
||
/**
|
||
* Reconcile TPA API rows with Nhance employee + employee policy records.
|
||
*
|
||
* Why this function exists:
|
||
* - TPA ingestion stores raw member rows in `tpa_api_data`.
|
||
* - Downstream processing may need a stable linkage back to the exact
|
||
* `employee_polices.id` record that represents that member in Nhance.
|
||
* - This method resolves that linkage and writes it into `tpa_api_data.ref`.
|
||
*
|
||
* Matching strategy:
|
||
* 1) Resolve candidate Nhance members by `emp_code` scoped to the same file's
|
||
* client and policy context.
|
||
* 2) Perform strict exact match on:
|
||
* - emp_code
|
||
* - name
|
||
* - dob
|
||
* - gender
|
||
* - relation/relationship
|
||
* 3) Update `tpa_api_data.ref` only when the exact match is found.
|
||
*
|
||
* Important behavior:
|
||
* - Only active rows are considered on both sides.
|
||
* - Already linked rows (`ref` present) are skipped to avoid accidental override.
|
||
* - Updates are done in batch and wrapped in DB transaction for consistency.
|
||
*
|
||
* @param int|string $file_id Batch file id whose TPA rows must be reconciled.
|
||
*
|
||
* @return array{
|
||
* status: bool,
|
||
* message: string,
|
||
* data: array{
|
||
* file_id:int,
|
||
* scanned:int,
|
||
* matched:int,
|
||
* skipped_already_mapped:int,
|
||
* unmatched:int
|
||
* }
|
||
* }
|
||
*/
|
||
public function reconTpaApiDataWithEmployeepolicies($file_id): array
|
||
{
|
||
try {
|
||
$fileId = (int) $file_id['file_id'];
|
||
if ($fileId <= 0) {
|
||
return [
|
||
'status' => false,
|
||
'message' => 'Invalid file id provided.',
|
||
'data' => [],
|
||
];
|
||
}
|
||
|
||
$fileInfo = $this->batchFileModel->find($fileId);
|
||
if (empty($fileInfo)) {
|
||
return [
|
||
'status' => false,
|
||
'message' => 'Batch file not found.',
|
||
'data' => ['file_id' => $fileId],
|
||
];
|
||
}
|
||
|
||
$clientId = (int) ($fileInfo['client_id'] ?? 0);
|
||
$clientPolicyId = (int) ($fileInfo['client_policy_id'] ?? 0);
|
||
if ($clientId <= 0 || $clientPolicyId <= 0) {
|
||
return [
|
||
'status' => false,
|
||
'message' => 'Client/policy context missing for provided file id.',
|
||
'data' => ['file_id' => $fileId],
|
||
];
|
||
}
|
||
|
||
$db = \Config\Database::connect();
|
||
|
||
// Pull only active TPA rows for this file. We include `ref` to skip
|
||
// rows that are already mapped by any previous reconciliation run.
|
||
$tpaRows = $db->table('tpa_api_data')
|
||
->select('id, emp_code, name, dob, relation, gender, ref')
|
||
->where('file_id', $fileId)
|
||
->where('is_active', 1)
|
||
->get()
|
||
->getResultArray();
|
||
|
||
if (empty($tpaRows)) {
|
||
return [
|
||
'status' => true,
|
||
'message' => 'No active TPA rows found for reconciliation.',
|
||
'data' => [
|
||
'file_id' => $fileId,
|
||
'scanned' => 0,
|
||
'matched' => 0,
|
||
'skipped_already_mapped' => 0,
|
||
'unmatched' => 0,
|
||
],
|
||
];
|
||
}
|
||
|
||
// return $tpaRows;
|
||
// Build Nhance-side candidate pool once, keyed by emp_code.
|
||
// Each candidate represents an active employee policy member.
|
||
$dbMembers = $db->table('employee_polices ep')
|
||
->select('
|
||
ep.id AS employee_policy_id,
|
||
emp.emp_code,
|
||
emp.name,
|
||
emp.relationship,
|
||
emp.dob,
|
||
emp.gender
|
||
')
|
||
->join('employees emp', 'ep.employee_id = emp.id')
|
||
->where('ep.is_active', 1)
|
||
->where('ep.status', 'active')
|
||
->where('ep.client_policy_id', $clientPolicyId)
|
||
->where('emp.client_id', $clientId)
|
||
->where('emp.is_active', 1)
|
||
->get()
|
||
->getResultArray();
|
||
|
||
// return $dbMembers;
|
||
$membersByEmpCode = [];
|
||
foreach ($dbMembers as $member) {
|
||
$membersByEmpCode[$member['emp_code']][] = $member;
|
||
}
|
||
|
||
$updates = [];
|
||
$matched = 0;
|
||
$skipped = 0;
|
||
$unmatched = 0;
|
||
|
||
$normalize = static function ($value): string {
|
||
return strtolower(trim((string) $value));
|
||
};
|
||
|
||
foreach ($tpaRows as $tpaRow) {
|
||
$existingRef = trim((string) ($tpaRow['ref'] ?? ''));
|
||
if ($existingRef !== '') {
|
||
$skipped++;
|
||
continue;
|
||
}
|
||
|
||
$empCode = (string) ($tpaRow['emp_code'] ?? '');
|
||
$candidates = $membersByEmpCode[$empCode] ?? [];
|
||
if (empty($candidates)) {
|
||
$unmatched++;
|
||
continue;
|
||
}
|
||
|
||
$tName = $normalize($tpaRow['name'] ?? '');
|
||
$tRel = $normalize($tpaRow['relation'] ?? '');
|
||
$tDob = (string) ($tpaRow['dob'] ?? '');
|
||
$tGender = strtoupper(trim((string) ($tpaRow['gender'] ?? '')));
|
||
|
||
// Strict exact matching only (no fallback):
|
||
// emp_code is already scoped via $membersByEmpCode.
|
||
// Remaining fields must all match together.
|
||
$picked = null;
|
||
foreach ($candidates as $candidate) {
|
||
$nameOk = $normalize($candidate['name'] ?? '') === $tName;
|
||
$relOk = $normalize($candidate['relationship'] ?? '') === $tRel;
|
||
$dobOk = (string) ($candidate['dob'] ?? '') === $tDob;
|
||
$genOk = strtoupper(trim((string) ($candidate['gender'] ?? ''))) === $tGender;
|
||
if ($nameOk && $relOk && $dobOk && $genOk) {
|
||
$picked = $candidate;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if ($picked === null) {
|
||
$unmatched++;
|
||
continue;
|
||
}
|
||
|
||
$updates[] = [
|
||
'id' => (int) $tpaRow['id'],
|
||
'ref' => (int) $picked['employee_policy_id'],
|
||
];
|
||
$matched++;
|
||
}
|
||
// return $updates;
|
||
if (!empty($updates)) {
|
||
$db->transStart();
|
||
$db->table('tpa_api_data')->updateBatch($updates, 'id');
|
||
$db->transComplete();
|
||
}
|
||
|
||
$payload = [
|
||
'file_id' => $fileId,
|
||
'scanned' => count($tpaRows),
|
||
'matched' => $matched,
|
||
'skipped_already_mapped' => $skipped,
|
||
'unmatched' => $unmatched,
|
||
];
|
||
|
||
$this->myLogger->logme('error', 'TPA ref reconciliation completed: ' . json_encode($payload));
|
||
|
||
return [
|
||
'status' => true,
|
||
'message' => 'TPA rows reconciled with employee policies successfully.',
|
||
'data' => $payload,
|
||
];
|
||
} catch (\Throwable $e) {
|
||
$this->myLogger->logme(
|
||
'error',
|
||
'Error in reconTpaApiDataWithEmployeepolicies: ' . $e->getMessage(),
|
||
['file_id' => $file_id]
|
||
);
|
||
|
||
return [
|
||
'status' => false,
|
||
'message' => 'Unable to reconcile TPA rows with employee policies.',
|
||
'data' => [
|
||
'file_id' => (int) $file_id,
|
||
'error' => $e->getMessage(),
|
||
],
|
||
];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Build and queue a Deletion import file from TPA reconciled data.
|
||
*
|
||
* The logic uses `tpa_api_data.ref` rows with `rec_type = matched` as the
|
||
* "currently present in TPA" snapshot. Any active Nhance member in the same
|
||
* client/policy scope not present in that ref set is prepared as a deletion row.
|
||
*
|
||
* @param int|string $file_id Source batch_file id of the TPA variation flow.
|
||
*
|
||
* @return array{
|
||
* status: bool,
|
||
* message: string,
|
||
* data: array
|
||
* }
|
||
*/
|
||
public function initializeDeletionProcessForTpaApiData($file_id): array
|
||
{
|
||
// echo 'DELETION';
|
||
try {
|
||
$fileId = (int) $file_id['file_id'];
|
||
if ($fileId <= 0) {
|
||
return [
|
||
'status' => false,
|
||
'message' => 'Invalid file id provided.',
|
||
'data' => [],
|
||
];
|
||
}
|
||
|
||
$fileInfo = $this->batchFileModel->find($fileId);
|
||
if (empty($fileInfo)) {
|
||
return [
|
||
'status' => false,
|
||
'message' => 'Batch file not found.',
|
||
'data' => ['file_id' => $fileId],
|
||
];
|
||
}
|
||
|
||
$clientId = (int) ($fileInfo['client_id'] ?? 0);
|
||
$clientPolicyId = (int) ($fileInfo['client_policy_id'] ?? 0);
|
||
$clientBranchId = (int) ($fileInfo['client_branch_id'] ?? 0);
|
||
|
||
if ($clientId <= 0 || $clientPolicyId <= 0 || $clientBranchId <= 0) {
|
||
return [
|
||
'status' => false,
|
||
'message' => 'Client/policy/branch context missing for provided file id.',
|
||
'data' => ['file_id' => $fileId],
|
||
];
|
||
}
|
||
|
||
$db = \Config\Database::connect();
|
||
|
||
// Take only mapped rows for this file where reconciliation is stable.
|
||
$mappedRows = $db->table('tpa_api_data tad')
|
||
->select('tad.ref')
|
||
->where('tad.file_id', $fileId)
|
||
->where('tad.is_active', 1)
|
||
->where('tad.action_flag_status', 'D')
|
||
// ->where('tad.rec_type', 'matched')
|
||
->where('tad.ref IS NOT NULL', null, false)
|
||
->where('tad.ref !=', '')
|
||
->groupBy('tad.ref')
|
||
->get()
|
||
->getResultArray();
|
||
// return $mappedRows;
|
||
$mappedPolicyIds = array_values(array_filter(array_map(
|
||
static fn($row) => (int) ($row['ref'] ?? 0),
|
||
$mappedRows
|
||
)));
|
||
|
||
if (empty($mappedPolicyIds)) {
|
||
return [
|
||
'status' => true,
|
||
'message' => 'No reconciled TPA mapped rows found. Deletion initialization skipped.',
|
||
'data' => ['file_id' => $fileId, 'candidate_count' => 0],
|
||
];
|
||
}
|
||
|
||
// Candidate deletions = active Nhance members in scope not present in mapped refs.
|
||
$candidateBuilder = $db->table('employee_polices ep')
|
||
->select("
|
||
ep.id AS employee_policy_id,
|
||
emp.emp_code,
|
||
emp.name,
|
||
emp.dob,
|
||
emp.gender,
|
||
emp.relationship,
|
||
ep.basic_cover_si,
|
||
ep.policy_end_date,
|
||
ep.premium,
|
||
ep.claim_status
|
||
")
|
||
->join('employees emp', 'ep.employee_id = emp.id')
|
||
->where('ep.is_active', 1)
|
||
->where('ep.status', 'active')
|
||
->where('ep.client_policy_id', $clientPolicyId)
|
||
->where('emp.client_id', $clientId)
|
||
->where('emp.is_active', 1)
|
||
->where('emp.emp_status', 'active');
|
||
|
||
$candidateBuilder->whereIn('ep.id', $mappedPolicyIds);
|
||
$candidateMembers = $candidateBuilder->get()->getResultArray();
|
||
|
||
// return $candidateMembers;
|
||
if (empty($candidateMembers)) {
|
||
return [
|
||
'status' => true,
|
||
'message' => 'No deletion candidates found from TPA reconciliation.',
|
||
'data' => ['file_id' => $fileId, 'candidate_count' => 0],
|
||
];
|
||
}
|
||
|
||
$spreadsheet = new Spreadsheet();
|
||
$sheet = $spreadsheet->getActiveSheet();
|
||
$sheet->setTitle('Deletion');
|
||
|
||
$headers = [
|
||
'S.No',
|
||
'Emp ID',
|
||
'Name of Emp/Dep',
|
||
'change event ',
|
||
'date of exit',
|
||
'reason for exit',
|
||
'Claim status',
|
||
];
|
||
|
||
foreach ($headers as $idx => $header) {
|
||
$col = Coordinate::stringFromColumnIndex($idx + 1);
|
||
$sheet->setCellValue($col . '1', $header);
|
||
}
|
||
|
||
$rowNo = 2;
|
||
$serial = 1;
|
||
$dateOfExit = date('d-M-Y');
|
||
|
||
foreach ($candidateMembers as $member) {
|
||
$sheet->setCellValue('A' . $rowNo, $serial);
|
||
$sheet->setCellValue('B' . $rowNo, (string) ($member['emp_code'] ?? ''));
|
||
$sheet->setCellValue('C' . $rowNo, (string) ($member['name'] ?? ''));
|
||
$sheet->setCellValue('D' . $rowNo, 'deletion');
|
||
$sheet->setCellValue('E' . $rowNo, $dateOfExit);
|
||
$sheet->setCellValue('F' . $rowNo, 'tpa deletion');
|
||
$sheet->setCellValue('G' . $rowNo, '0');
|
||
$rowNo++;
|
||
$serial++;
|
||
}
|
||
|
||
for ($c = 1; $c <= count($headers); $c++) {
|
||
$col = Coordinate::stringFromColumnIndex($c);
|
||
$sheet->getColumnDimension($col)->setAutoSize(true);
|
||
}
|
||
|
||
$generatedFileName = sprintf(
|
||
'tpa_auto_deletion_%d_%s.xls',
|
||
$fileId,
|
||
date('Ymd_His')
|
||
);
|
||
$generatedExcelPath = WRITEPATH . 'uploads/excel/' . $generatedFileName;
|
||
if (! is_dir(WRITEPATH . 'uploads/excel')) {
|
||
mkdir(WRITEPATH . 'uploads/excel', 0755, true);
|
||
}
|
||
|
||
$writer = new Xls($spreadsheet);
|
||
$writer->save($generatedExcelPath);
|
||
storage_mirror_generated_file($generatedExcelPath, WRITEPATH . 'uploads/excel', $generatedFileName);
|
||
// return "HI";
|
||
// 1) Create files-table entry for EmployeeServiceController::employeeDisembark.
|
||
$newFileId = $this->fileModel->insert([
|
||
'file_name' => $generatedFileName,
|
||
'client_id' => $clientId,
|
||
'policy_id' => $clientPolicyId,
|
||
'created_by' => (int) ($fileInfo['created_by'] ?? get_session_userid()),
|
||
'status' => 'inprogress',
|
||
'action' => 'deletion',
|
||
'client_branch_id' => $clientBranchId,
|
||
'uploaded_by' => 1,
|
||
'hr_file_id' => null,
|
||
'hr_id' => null,
|
||
]);
|
||
|
||
if (!$newFileId) {
|
||
return [
|
||
'status' => false,
|
||
'message' => 'Unable to create file entry for generated deletion file.',
|
||
'data' => ['file_id' => $fileId, 'generated_file_name' => $generatedFileName],
|
||
];
|
||
}
|
||
|
||
// 2) Trigger existing disembark processing and proceed only on success.
|
||
$empServiceController = new EmployeeServiceController();
|
||
$disembarkResult = $empServiceController->employeeDisembark(['file_id' => (int) $newFileId]);
|
||
|
||
if (!is_array($disembarkResult)) {
|
||
return [
|
||
'status' => false,
|
||
'message' => 'employeeDisembark failed for generated deletion file.',
|
||
'data' => [
|
||
'file_id' => $fileId,
|
||
'generated_file_id' => (int) $newFileId,
|
||
'generated_file_name' => $generatedFileName,
|
||
],
|
||
];
|
||
}
|
||
|
||
|
||
//call existing function to get deletion export data
|
||
|
||
$batch_data = [
|
||
'client_id' => $clientId,
|
||
'client_policy_id' => $clientPolicyId,
|
||
'client_branch_id' => $clientBranchId,
|
||
'insurer_or_tpa' => 'tpa',
|
||
'event_type' => 'deletion',
|
||
'actions' => 'export',
|
||
'file_name' => '',
|
||
];
|
||
$endorsementTs = date('YmdHis');
|
||
$objects = $this->employeePolicyModel->getDeletionEmployeeDataForExportExcel($batch_data);
|
||
// print_rr($objects);die;
|
||
foreach ($objects as $obj) {
|
||
$obj->endorsement_id = $endorsementTs;
|
||
}
|
||
|
||
$excel_header_columns = [
|
||
['column_index' => 0, 'column_name' => 'S.No', 'db_column_name' => 'index'],
|
||
['column_index' => 1, 'column_name' => 'EMP ID', 'db_column_name' => 'emp_code'],
|
||
['column_index' => 2, 'column_name' => 'EMP NAME', 'db_column_name' => 'emp_name'],
|
||
['column_index' => 3, 'column_name' => 'DOB', 'db_column_name' => 'emp_dob'],
|
||
['column_index' => 4, 'column_name' => 'GENDER', 'db_column_name' => 'emp_gender'],
|
||
['column_index' => 5, 'column_name' => 'RELATIONSHIP', 'db_column_name' => 'emp_relationship'],
|
||
['column_index' => 6, 'column_name' => 'SUM INSURED', 'db_column_name' => 'basic_cover_si'],
|
||
['column_index' => 7, 'column_name' => 'Date of Leaving', 'db_column_name' => 'dateofexit'],
|
||
['column_index' => 8, 'column_name' => 'Policy End Date', 'db_column_name' => 'policy_end_date'],
|
||
['column_index' => 9, 'column_name' => 'No Of Days', 'db_column_name' => 'no_of_days'],
|
||
['column_index' => 10, 'column_name' => 'Premium', 'db_column_name' => 'premium'],
|
||
['column_index' => 11, 'column_name' => 'Pro Rata Premium', 'db_column_name' => 'pro_rata_premium'],
|
||
['column_index' => 12, 'column_name' => 'GST', 'db_column_name' => 'gst'],
|
||
['column_index' => 13, 'column_name' => 'Total', 'db_column_name' => 'total'],
|
||
['column_index' => 14, 'column_name' => 'Claim Status', 'db_column_name' => 'claim_status'],
|
||
['column_index' => 15, 'column_name' => 'ENDORSEMENT_ID', 'db_column_name' => 'endorsement_id']
|
||
];
|
||
|
||
$excel_data_info = generate_insurer_based_excel($excel_header_columns, $objects);
|
||
|
||
// $tempFile = tmpfile();
|
||
$generatedImportFileName = sprintf(
|
||
'tpa_auto_deletion_import_%d_%s.xlsx',
|
||
$fileId,
|
||
date('Ymd_His')
|
||
);
|
||
$generatedImportPath = WRITEPATH . 'uploads/import_excel/' . $generatedImportFileName;
|
||
if (! is_dir(WRITEPATH . 'uploads/import_excel')) {
|
||
mkdir(WRITEPATH . 'uploads/import_excel', 0755, true);
|
||
}
|
||
$success = generate_excel($excel_data_info['header'], $excel_data_info['data'], $generatedImportPath);
|
||
if ($success && is_file($generatedImportPath)) {
|
||
storage_mirror_generated_file($generatedImportPath, WRITEPATH . 'uploads/import_excel', $generatedImportFileName);
|
||
}
|
||
// print_rr($success);
|
||
|
||
// die;
|
||
// 3) Build a separate import-format file from sample_import_Deletion.xlsx
|
||
// for batch_file import validation pipeline.
|
||
// $importTemplatePath = ROOTPATH . 'public/sample_import_excel/sample_import_Deletion.xlsx';
|
||
// if (!file_exists($importTemplatePath)) {
|
||
// return [
|
||
// 'status' => false,
|
||
// 'message' => 'Import template file not found for deletion batch file format.',
|
||
// 'data' => [
|
||
// 'file_id' => $fileId,
|
||
// 'generated_file_id' => (int) $newFileId,
|
||
// 'template_path' => $importTemplatePath,
|
||
// ],
|
||
// ];
|
||
// }
|
||
|
||
// $importSpreadsheet = IOFactory::load($importTemplatePath);
|
||
// $importSheet = $importSpreadsheet->getActiveSheet();
|
||
// $importRowNo = 2;
|
||
// $importSerial = 1;
|
||
// $endorsementTs = date('YmdHis');
|
||
// $formatDate = static function ($value): string {
|
||
// if (empty($value)) {
|
||
// return '';
|
||
// }
|
||
// $ts = strtotime((string) $value);
|
||
// if ($ts === false) {
|
||
// return (string) $value;
|
||
// }
|
||
// return date('d-M-Y', $ts);
|
||
// };
|
||
|
||
|
||
// foreach ($candidateMembers as $memberKey => $member) {
|
||
// $policyEndDateRaw = (string) ($member['policy_end_date'] ?? '');
|
||
// $policyEndTs = strtotime($policyEndDateRaw);
|
||
// $exitTs = strtotime($dateOfExit);
|
||
// $noOfDays = 0;
|
||
// if ($policyEndTs !== false && $exitTs !== false && $policyEndTs >= $exitTs) {
|
||
// $noOfDays = (int) floor(($policyEndTs - $exitTs) / 86400);
|
||
// }
|
||
|
||
// $premium = (float) ($member['premium'] ?? 0);
|
||
// $proRata = $noOfDays > 0 ? round(($premium * $noOfDays) / 365, 2) : 0.00;
|
||
// $gst = round($proRata * 0.18, 2);
|
||
// $total = round($proRata + $gst, 2);
|
||
// $claimStatus = ((string) ($member['claim_status'] ?? '0') === '1') ? '1' : '0';
|
||
|
||
// $importSheet->setCellValue('A' . $importRowNo, $importSerial);
|
||
// $importSheet->setCellValue('B' . $importRowNo, (string) ($member['emp_code'] ?? ''));
|
||
// $importSheet->setCellValue('C' . $importRowNo, (string) ($member['name'] ?? ''));
|
||
// $importSheet->setCellValue('D' . $importRowNo, $formatDate($member['dob'] ?? ''));
|
||
// $importSheet->setCellValue('E' . $importRowNo, (string) ($member['gender'] ?? ''));
|
||
// $importSheet->setCellValue('F' . $importRowNo, (string) ($member['relationship'] ?? ''));
|
||
// $importSheet->setCellValue('G' . $importRowNo, (string) ($member['basic_cover_si'] ?? ''));
|
||
// $importSheet->setCellValue('H' . $importRowNo, $dateOfExit);
|
||
// $importSheet->setCellValue('I' . $importRowNo, $formatDate($policyEndDateRaw));
|
||
// $importSheet->setCellValue('J' . $importRowNo, (string) $noOfDays);
|
||
// $importSheet->setCellValue('K' . $importRowNo, (string) round($premium, 2));
|
||
// $importSheet->setCellValue('L' . $importRowNo, (string) $proRata);
|
||
// $importSheet->setCellValue('M' . $importRowNo, (string) $gst);
|
||
// $importSheet->setCellValue('N' . $importRowNo, (string) $total);
|
||
// $importSheet->setCellValue('O' . $importRowNo, $claimStatus);
|
||
// $endorsementNo = 'TPA_ENDO_' . $endorsementTs . '_' . $memberKey;
|
||
// $importSheet->setCellValue('P' . $importRowNo, $endorsementNo);
|
||
// $importRowNo++;
|
||
// $importSerial++;
|
||
// }
|
||
|
||
// $generatedImportFileName = sprintf(
|
||
// 'tpa_auto_deletion_import_%d_%s.xlsx',
|
||
// $fileId,
|
||
// date('Ymd_His')
|
||
// );
|
||
// $generatedImportPath = WRITEPATH . 'uploads/import_excel/' . $generatedImportFileName;
|
||
// $importWriter = new Xlsx($importSpreadsheet);
|
||
// $importWriter->save($generatedImportPath);
|
||
|
||
$newBatchData = [
|
||
'client_id' => $clientId,
|
||
'client_policy_id' => $clientPolicyId,
|
||
'client_branch_id' => $clientBranchId,
|
||
'event_type' => 'deletion',
|
||
'actions' => 'import',
|
||
'insurer_or_tpa' => 'insurer',
|
||
'batch_code' => generate_random_string(4),
|
||
'created_by' => (int) ($fileInfo['created_by'] ?? get_session_userid()),
|
||
'status' => 'pending',
|
||
'file_name' => $generatedImportFileName,
|
||
'count' => count($candidateMembers),
|
||
];
|
||
|
||
$newBatchFileId = $this->batchFileModel->insert($newBatchData);
|
||
if (!$newBatchFileId) {
|
||
return [
|
||
'status' => false,
|
||
'message' => 'Unable to create batch file entry for generated deletion file.',
|
||
'data' => ['file_id' => $fileId, 'generated_file_name' => $generatedImportFileName],
|
||
];
|
||
}
|
||
|
||
$empDataServiceController = new EmpDataServiceController();
|
||
$importValidationResult = $empDataServiceController->importDeletionValidation(['file_id' => (int) $newBatchFileId]);
|
||
|
||
$resultPayload = [
|
||
'source_file_id' => $fileId,
|
||
'generated_file_id' => (int) $newFileId,
|
||
'generated_batch_file_id' => (int) $newBatchFileId,
|
||
'generated_file_name' => $generatedFileName,
|
||
'generated_import_file_name' => $generatedImportFileName,
|
||
'candidate_count' => count($candidateMembers),
|
||
'endorsement_count' => count($disembarkResult),
|
||
'import_validation_result' => $importValidationResult,
|
||
];
|
||
|
||
$this->myLogger->logme('error', 'TPA auto deletion file initialized: ' . json_encode($resultPayload));
|
||
|
||
return [
|
||
'status' => true,
|
||
'message' => 'Deletion file generated and queued for validation.',
|
||
'data' => $resultPayload,
|
||
];
|
||
} catch (\Throwable $e) {
|
||
$this->myLogger->logme(
|
||
'error',
|
||
'Error in initializeDeletionProcessForTpaApiData: ' . $e->getMessage(),
|
||
['file_id' => (int) $file_id]
|
||
);
|
||
|
||
return [
|
||
'status' => false,
|
||
'message' => 'Unable to initialize deletion process from TPA data.',
|
||
'data' => [
|
||
'file_id' => (int) $file_id,
|
||
'error' => $e->getMessage(),
|
||
],
|
||
];
|
||
}
|
||
}
|
||
|
||
|
||
public function tpaReportsDashboard()
|
||
{
|
||
$METABASE_SECRET_KEY = getenv('METABASE_SECRET_KEY');
|
||
$policy_id = $this->request->getGet('client_policy') ?? null;
|
||
|
||
if ($this->request->getGet('api') != 1) {
|
||
$data = [
|
||
'tab_name' => 'TPA Reports',
|
||
'page_name' => 'TPA Reports',
|
||
'metabaseUrl' => 'https://nsights.nhanceindia.in',
|
||
'dashboardApiUrl' => base_url('/employee/tpaReportsDashboard'),
|
||
];
|
||
|
||
return $this->loadLayout('meta_dashboard_demo_one', $data);
|
||
}
|
||
|
||
if (empty($policy_id)) {
|
||
return $this->respond([
|
||
'status' => 'failed',
|
||
'message' => 'Client policy is required.',
|
||
'data' => [],
|
||
]);
|
||
}
|
||
|
||
$client_policy_data = $this->clientPolicyModel
|
||
->select('tpa.dashboard_id')
|
||
->join('tpa', 'client_policy.tpa_id = tpa.id')
|
||
->where('client_policy.id', $policy_id)
|
||
->first();
|
||
|
||
$database_id = isset($client_policy_data['dashboard_id']) ? (int) $client_policy_data['dashboard_id'] : null;
|
||
|
||
if (empty($database_id)) {
|
||
|
||
if ($this->request->getGet('api') == 1) {
|
||
return $this->respond([
|
||
'status' => 'failed',
|
||
'message' => 'There is no dashboard for this TPA.',
|
||
'data' => []
|
||
]);
|
||
}
|
||
|
||
return view('errors/404', [
|
||
'message' => 'There is no dashboard for this TPA.'
|
||
]);
|
||
}
|
||
|
||
$payload = [
|
||
'resource' => [
|
||
'dashboard' => $database_id
|
||
],
|
||
'exp' => time() + (10 * 60), // 10 minutes
|
||
'params' => (object) ['client_policy' => $policy_id ], // MUST be object for Metabase
|
||
|
||
];
|
||
|
||
$token = JWT::encode($payload, $METABASE_SECRET_KEY, 'HS256');
|
||
// dd($token);
|
||
|
||
return $this->respond([
|
||
'status' => 'success',
|
||
'message' => 'Form data received successfully!',
|
||
'data' => [
|
||
'metabaseToken' => $token,
|
||
'metabaseUrl' => 'https://nsights.nhanceindia.in',
|
||
],
|
||
]);
|
||
}
|
||
|
||
|
||
}
|