From 81b8f765d4d89ea12f7edd1f2dfd6e1dd1af417f Mon Sep 17 00:00:00 2001 From: "sanjeev.p" Date: Wed, 24 Dec 2025 16:55:45 +0530 Subject: [PATCH 1/5] FIX_FAQ --- app/Views/faq_list.php | 133 +++++++++++++++++++++++++--- app/Views/frontend_content_list.php | 124 ++++++++++++++++++++++++-- app/Views/pos_list.php | 124 ++++++++++++++++++++++++-- 3 files changed, 357 insertions(+), 24 deletions(-) diff --git a/app/Views/faq_list.php b/app/Views/faq_list.php index e725b7e3..9a4d6d8c 100644 --- a/app/Views/faq_list.php +++ b/app/Views/faq_list.php @@ -3,6 +3,33 @@ position: absolute; } .dataTables_length label {height: 21px !important;} + +.custom-dropdown-menu { + display: none; + position: absolute; + background-color: #ffffff !important; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; + padding: 0.5rem 0; + min-width: 10rem; + z-index: 9999; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); +} + +.custom-dropdown-menu .dropdown-item { + display: block !important; + width: 100% !important; + padding: 0.5rem 1rem !important; + color: #212529 !important; + text-decoration: none !important; + background-color: transparent !important; +} + +.custom-dropdown-menu .dropdown-item:hover { + background-color: #f8f9fa !important; + color: #16181b !important; + cursor: pointer !important; +} @@ -16,13 +43,15 @@ S.No. Category Question - Answer + Status Action - + $row) { ?> @@ -36,11 +65,11 @@ ? htmlspecialchars(substr($question, 0, 50)) . "..." : htmlspecialchars($question); ?> - 50) ? htmlspecialchars(substr($answer, 0, 50)) . "..." : htmlspecialchars($answer); - ?> + ?> --> @@ -62,12 +91,7 @@ - - - - + @@ -353,4 +377,93 @@ }); + diff --git a/app/Views/frontend_content_list.php b/app/Views/frontend_content_list.php index f0df3b93..ce3db484 100644 --- a/app/Views/frontend_content_list.php +++ b/app/Views/frontend_content_list.php @@ -3,6 +3,32 @@ position: absolute; } .dataTables_length label {height: 21px !important;} +.custom-dropdown-menu { + display: none; + position: absolute; + background-color: #ffffff !important; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; + padding: 0.5rem 0; + min-width: 10rem; + z-index: 9999; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); +} + +.custom-dropdown-menu .dropdown-item { + display: block !important; + width: 100% !important; + padding: 0.5rem 1rem !important; + color: #212529 !important; + text-decoration: none !important; + background-color: transparent !important; +} + +.custom-dropdown-menu .dropdown-item:hover { + background-color: #f8f9fa !important; + color: #16181b !important; + cursor: pointer !important; +} @@ -23,7 +49,7 @@ - + $row) { ?> @@ -51,12 +77,7 @@ - - - - + @@ -503,4 +524,93 @@ } + diff --git a/app/Views/pos_list.php b/app/Views/pos_list.php index c6b08022..2c1c1af5 100644 --- a/app/Views/pos_list.php +++ b/app/Views/pos_list.php @@ -3,6 +3,32 @@ position: absolute; } .dataTables_length label {height: 21px !important;} +.custom-dropdown-menu { + display: none; + position: absolute; + background-color: #ffffff !important; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; + padding: 0.5rem 0; + min-width: 10rem; + z-index: 9999; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); +} + +.custom-dropdown-menu .dropdown-item { + display: block !important; + width: 100% !important; + padding: 0.5rem 1rem !important; + color: #212529 !important; + text-decoration: none !important; + background-color: transparent !important; +} + +.custom-dropdown-menu .dropdown-item:hover { + background-color: #f8f9fa !important; + color: #16181b !important; + cursor: pointer !important; +} @@ -24,7 +50,7 @@ - + $row) { ?> @@ -54,12 +80,7 @@ - - - - No data available - - + @@ -480,5 +501,94 @@ + + From c63d11299f03fff39268fab497711f2aac55cd99 Mon Sep 17 00:00:00 2001 From: velz Date: Wed, 24 Dec 2025 18:41:31 +0530 Subject: [PATCH 2/5] FEAT_ECARD_S3MIG --- app/Config/Routes.php | 3 + app/Config/Services.php | 10 + app/Controllers/EmployeeController.php | 598 ++++++++++++------ .../EmployeeMultiEventServiceController.php | 4 +- app/Controllers/JobWorker.php | 6 + app/Libraries/S3Service.php | 268 ++++++++ composer.json | 3 +- 7 files changed, 709 insertions(+), 183 deletions(-) create mode 100644 app/Libraries/S3Service.php diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 13aff9ac..4f942872 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -214,6 +214,7 @@ $routes->group("/employee", ["filter" => "authMVC"], function ($routes) { $routes->get("retail-endorsement-list", "EmployeeController::retailendorsementlist"); $routes->post("retail-endorsement-save", "EmployeeController::retailendorsementsave"); $routes->get("getTPADataVariationReport/(:num)", "EmployeeController::getTPADataVariationReport/$1"); + $routes->get("bulkGenerateEcardAndStoreinS3", "EmployeeController::bulkGenerateEcardAndStoreinS3"); }); @@ -509,6 +510,8 @@ $routes->get('cli/sendZeptoMail', 'MasterController::testZeptoSMTP'); $routes->cli('cli/processjob', 'JobWorker::processJob'); $routes->cli('cli/processjobs', 'JobWorker::processJobs'); +$routes->cli('cli/bulkGenerateEcardAndStoreinS3', 'EmployeeController::bulkGenerateEcardAndStoreinS3'); + $routes->get("processjob", "JobWorker::processJob"); $routes->cli('cli/new_gmail_token', 'MasterController::generateNewGmailAPIToken'); $routes->cli('cli/send_mail_cli', 'MasterController::testGmailAPIViaCLI'); diff --git a/app/Config/Services.php b/app/Config/Services.php index 5f982877..73d75683 100755 --- a/app/Config/Services.php +++ b/app/Config/Services.php @@ -9,6 +9,7 @@ use App\Libraries\GmailAPI; use App\Libraries\MyGoogleDrive; use App\Libraries\RuleImportService; use App\Libraries\DataServiceSqlite; +use App\Libraries\S3Service; use App\Controllers\Home; /** @@ -90,5 +91,14 @@ class Services extends BaseService return new RuleImportService(); } + + public static function getS3Service($getShared = true) + { + if ($getShared) { + return static::getSharedInstance('getS3Service'); + } + + return new S3Service(); + } } diff --git a/app/Controllers/EmployeeController.php b/app/Controllers/EmployeeController.php index 32217c91..fe377c2a 100755 --- a/app/Controllers/EmployeeController.php +++ b/app/Controllers/EmployeeController.php @@ -101,6 +101,14 @@ class EmployeeController extends AdminController 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']; @@ -1429,7 +1437,10 @@ class EmployeeController extends AdminController //E-CARD DOWNLOAD FUNCTION USING DOM PDF ( CURRENTLY USING THIS ) Dompdf public function generateIDCardForEmployee($rand_string, $people = 0, $mode = 0) { - // dd($rand_string, $people); + $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.'); @@ -1438,7 +1449,7 @@ class EmployeeController extends AdminController $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') + ->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') @@ -1465,7 +1476,44 @@ class EmployeeController extends AdminController $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'; + // 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); @@ -1562,6 +1610,7 @@ class EmployeeController extends AdminController } // return $html; + // echo $html;die(); // DomPdf $options = new Options(); $options->set('isRemoteEnabled', true); @@ -1585,28 +1634,34 @@ class EmployeeController extends AdminController $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 '
PDF generated and uploaded to S3 successfully.
'; + unlink($temp_local_path); - if ($mode == 1) { - // Inline view - return $this->response - ->setHeader('Content-Type', 'application/pdf') - ->setHeader('Content-Disposition', 'inline; filename="' . $filename . '"') - ->setBody($dompdf->output()); - } else { - // Force download - return $this->response - ->setHeader('Content-Type', 'application/pdf') - ->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"') - ->setBody($dompdf->output()); - } + // exit(); + // if ($mode == 1) { + // // Inline view + // return $this->response + // ->setHeader('Content-Type', 'application/pdf') + // ->setHeader('Content-Disposition', 'inline; filename="' . $filename . '"') + // ->setBody($dompdf->output()); + // } else { + // // Force download + // return $this->response + // ->setHeader('Content-Type', 'application/pdf') + // ->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"') + // ->setBody($dompdf->output()); + // } - $this->myLogger->logme('error', 'generateIDCardForEmployee function completed successfully.'); + // $this->myLogger->logme('error', 'generateIDCardForEmployee function completed successfully.'); } catch (\Exception $e) { $this->myLogger->logme('error', 'Exception occurred: ' . $e->getMessage()); @@ -3764,206 +3819,389 @@ class EmployeeController extends AdminController array $notInTPA, array $notInNhance, array $reviewNeeded, - string $filename = 'employee_review.xlsx' -) { + string $filename = 'employee_review.xlsx') + { - function setCell($sheet, int $col, int $row, $value) -{ - $cell = Coordinate::stringFromColumnIndex($col) . $row; - $sheet->setCellValue($cell, $value); -} + function setCell($sheet, int $col, int $row, $value) + { + $cell = Coordinate::stringFromColumnIndex($col) . $row; + $sheet->setCellValue($cell, $value); + } -$EXPORT_COLUMNS = [ + $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 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 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 (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', - ], -]; + // 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(); + $spreadsheet = new Spreadsheet(); - /* ========================================================= - * SHEET 1 — NOT IN TPA - * ========================================================= */ - $sheet1 = $spreadsheet->getActiveSheet(); - $sheet1->setTitle('Not in TPA'); + /* ========================================================= + * SHEET 1 — NOT IN TPA + * ========================================================= */ + $sheet1 = $spreadsheet->getActiveSheet(); + $sheet1->setTitle('Not in TPA'); - $cols = $EXPORT_COLUMNS['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] ?? ''); + foreach ($cols as $label) { + setCell($sheet1, $colNo++, 1, $label); } - $rowNo++; - } - foreach (range(1, count($cols)) as $c) { - $sheet1->getColumnDimension(Coordinate::stringFromColumnIndex($c))->setAutoSize(true); - } + $rowNo = 2; + foreach ($notInTPA as $row) { + $colNo = 1; + foreach ($cols as $key => $label) { + setCell($sheet1, $colNo++, $rowNo, $row[$key] ?? ''); + } + $rowNo++; + } - /* ========================================================= - * SHEET 2 — NOT IN NHANCE - * ========================================================= */ - $sheet2 = $spreadsheet->createSheet(); - $sheet2->setTitle('Not in Nhance'); + foreach (range(1, count($cols)) as $c) { + $sheet1->getColumnDimension(Coordinate::stringFromColumnIndex($c))->setAutoSize(true); + } - $cols = $EXPORT_COLUMNS['not_in_nhance']; + /* ========================================================= + * SHEET 2 — NOT IN NHANCE + * ========================================================= */ + $sheet2 = $spreadsheet->createSheet(); + $sheet2->setTitle('Not in Nhance'); - $colNo = 1; - foreach ($cols as $label) { - setCell($sheet2, $colNo++, 1, $label); - } + $cols = $EXPORT_COLUMNS['not_in_nhance']; - $rowNo = 2; - foreach ($notInNhance as $row) { $colNo = 1; - foreach ($cols as $key => $label) { - setCell($sheet2, $colNo++, $rowNo, $row[$key] ?? ''); + foreach ($cols as $label) { + setCell($sheet2, $colNo++, 1, $label); } - $rowNo++; - } - foreach (range(1, count($cols)) as $c) { - $sheet2->getColumnDimension(Coordinate::stringFromColumnIndex($c))->setAutoSize(true); - } + $rowNo = 2; + foreach ($notInNhance as $row) { + $colNo = 1; + foreach ($cols as $key => $label) { + setCell($sheet2, $colNo++, $rowNo, $row[$key] ?? ''); + } + $rowNo++; + } - /* ========================================================= - * SHEET 3 — REVIEW NEEDED - * ========================================================= */ - $sheet3 = $spreadsheet->createSheet(); - $sheet3->setTitle('Review Needed'); + foreach (range(1, count($cols)) as $c) { + $sheet2->getColumnDimension(Coordinate::stringFromColumnIndex($c))->setAutoSize(true); + } - $mainCols = $EXPORT_COLUMNS['review_main']; - $tpaCols = $EXPORT_COLUMNS['review_tpa']; + /* ========================================================= + * SHEET 3 — REVIEW NEEDED + * ========================================================= */ + $sheet3 = $spreadsheet->createSheet(); + $sheet3->setTitle('Review Needed'); - // headers - $colNo = 1; - foreach ($mainCols as $label) { - setCell($sheet3, $colNo++, 1, $label); - } - foreach ($tpaCols as $label) { - setCell($sheet3, $colNo++, 1, $label); - } + $mainCols = $EXPORT_COLUMNS['review_main']; + $tpaCols = $EXPORT_COLUMNS['review_tpa']; - // rows - $rowNo = 2; - foreach ($reviewNeeded as $row) { - - // main (DB) + // headers $colNo = 1; - foreach ($mainCols as $key => $label) { - setCell($sheet3, $colNo++, $rowNo, $row[$key] ?? ''); + foreach ($mainCols as $label) { + setCell($sheet3, $colNo++, 1, $label); + } + foreach ($tpaCols as $label) { + setCell($sheet3, $colNo++, 1, $label); } - $tpaData = []; - $notMatching = []; + // rows + $rowNo = 2; + foreach ($reviewNeeded as $row) { - 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'); + // main (DB) + $colNo = 1; + foreach ($mainCols as $key => $label) { + setCell($sheet3, $colNo++, $rowNo, $row[$key] ?? ''); } - 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'); + $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++; } - $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; } - foreach (range(1, count($mainCols) + count($tpaCols)) as $c) { - $sheet3->getColumnDimension(Coordinate::stringFromColumnIndex($c))->setAutoSize(true); + public function bulkGenerateEcardAndStoreinS3(array $params = []) + { + /** + * --------------------------- + * 1. Detect mode + collect inputs + * --------------------------- + */ + + $client_policy_id = $params['client_policy_id'] ?? null; + $emp_code = $params['emp_code'] ?? null; + $emp_pk = $params['emp_pk'] ?? null; + $batch_size = $params['batch_size'] ?? null; + $batch_no = $params['batch_no'] ?? null; + $execution_mode = $params['execution_mode'] ?? 'sequential';//parallel + $total_batches = $params['total_batches'] ?? 0;//parallel + + if (is_cli()) { + $mode = 'CLI'; + + + } elseif (empty($params) && $this->request->getMethod() === 'get') { + $mode = 'WEB'; + + $client_policy_id = $this->request->getGet('client_policy_id'); + $emp_code = $this->request->getGet('emp_code'); + $emp_pk = $this->request->getGet('emp_pk'); + $execution_mode = $this->request->getGet('execution_mode') ?? 'sequential'; + $batch_size = (int) ($this->request->getGet('batch_size') ?? 100); + if($client_policy_id == null || empty($client_policy_id) || $client_policy_id == '') + { + return $this->respond(['status' => false, 'code' => 200, 'message' => 'client_policy_id is necessary'], 200); + } + /** + * --------------------------- + * 2. Calculate total records + * --------------------------- + */ + $total = $this->employeePolicyModel + ->join('employees', 'employees.id = employee_polices.employee_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.client_policy_id', $client_policy_id) + ->countAllResults(); + + $total_batches = (int) ceil($total / $batch_size); + // echo $total_batches;die(); + + + + /** + * --------------------------- + * 3. Push JOB per batch + * --------------------------- + */ + if ($execution_mode === 'parallel') { + for ($batch_no = 1; $batch_no <= $total_batches; $batch_no++) { + Jobs::addJob([ + 'job_name' => 'bulkGenerateEcardAndStoreinS3', + 'payload' => [ + 'client_policy_id' => $client_policy_id, + 'emp_code' => $emp_code, + 'emp_pk' => $emp_pk, + 'batch_size' => $batch_size, + 'batch_no' => $batch_no, + 'total_batches' => $total_batches, + 'execution_mode' => 'parallel', + ], + ]); + } + } + + if ($execution_mode === 'sequential') { + Jobs::addJob([ + 'job_name' => 'bulkGenerateEcardAndStoreinS3', + 'payload' => [ + 'client_policy_id' => $client_policy_id, + 'batch_size' => $batch_size, + 'batch_no' => $batch_no ?? 1, + 'total_batches' => $total_batches, + 'execution_mode' => 'sequential', + ], + ]); + } + + return $this->respond(['status' => true, 'code' => 200, 'message' => 'E-card generation started', + 'total' => $total, + 'batches' => $total_batches,], 200); + // return [ + // 'status' => true, + // 'message' => 'E-card generation started', + // 'total' => $total, + // 'batches' => $total_batches, + // ]; + } + //else { + // return true; + // } + + /** + * --------------------------- + * 4. Build query (CLI execution) + * --------------------------- + */ + $builder = $this->employeePolicyModel + ->select(' + employee_polices.client_policy_id, + employees.emp_code, + tpa.short_name, + employees.client_id, + employee_polices.rand_string, + employees.id as emp_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.client_policy_id', $client_policy_id); + + if (!empty($emp_code)) { + $builder->where('employees.emp_code', $emp_code); + } + + if (!empty($emp_pk)) { + $builder->where('employees.id', $emp_pk); + } + + /** + * --------------------------- + * 5. Apply batching (only if provided) + * --------------------------- + */ + if (!empty($batch_size) && !empty($batch_no)) { + $offset = ($batch_no - 1) * $batch_size; + $builder->limit($batch_size, $offset); + } + + $res = $builder->findAll(); + + /** + * --------------------------- + * 6. Process batch + * --------------------------- + */ + foreach ($res as $row) { + $ecard_gen_res = $this->generateIDCardForEmployee( + $row['rand_string'], + 0, + 2 // skip S3 check, force regenerate + ); + + // print_rr([ + // 'batch' => $batch_no, + // 'emp' => $row['emp_code'], + // 'res' => $ecard_gen_res, + // ]); + + // echo date('Y-m-d H:i:s') . PHP_EOL; + } + + if ($execution_mode === 'sequential' && $batch_no < $total_batches) { + Jobs::addJob([ + 'job_name' => 'bulkGenerateEcardAndStoreinS3', + 'payload' => [ + 'client_policy_id' => $client_policy_id, + 'batch_size' => $batch_size, + 'batch_no' => ($batch_no + 1), + 'total_batches' => $total_batches, + 'execution_mode' => 'sequential', + ], + ]); + } + + // echo "BATCH {$batch_no} COMPLETED @ " . date('Y-m-d H:i:s') . PHP_EOL; + return array($batch_no); } - /* ========================================================= - * 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; -} - } diff --git a/app/Controllers/EmployeeMultiEventServiceController.php b/app/Controllers/EmployeeMultiEventServiceController.php index 782a189b..3c8846e9 100644 --- a/app/Controllers/EmployeeMultiEventServiceController.php +++ b/app/Controllers/EmployeeMultiEventServiceController.php @@ -1029,7 +1029,7 @@ class EmployeeMultiEventServiceController extends BaseController //check physical file if (!file_exists($file_name_with_path)) { //file not found update status and reason - $message = "Physcial file not found"; + $message = "Physcial file not found - " . $file_name_with_path; // echo $message; $this->myLogger->logme('error', ($message . ' for file id ' . $file_id)); $this->fileModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([5]), 'error_data' => $message])])->update(); @@ -1402,7 +1402,7 @@ class EmployeeMultiEventServiceController extends BaseController //check physical file if (!file_exists($file_name_with_path)) { //file not found update status and reason - $message = "Physcial file not found"; + $message = "Physcial file not found - " . $file_name_with_path; $this->myLogger->logme('error', ($message . ' for file id ' . $file_id)); $this->fileModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([5]), 'error_data' => $message])])->update(); return array('error_summary' => [5], 'error_data' => $message); diff --git a/app/Controllers/JobWorker.php b/app/Controllers/JobWorker.php index c32da5e6..4a52fc54 100755 --- a/app/Controllers/JobWorker.php +++ b/app/Controllers/JobWorker.php @@ -194,6 +194,10 @@ class JobWorker extends AdminController 'type' => 'CC', // Handler Category 'handler' => 'App\Controllers\MediAssistApiController', ], + 'bulkGenerateEcardAndStoreinS3' => [ + 'type' => 'CC', // Handler Category + 'handler' => 'App\Controllers\EmployeeController', + ] ]; @@ -253,6 +257,8 @@ class JobWorker extends AdminController // print_r($jobdata); // echo 'listen'; // die(); + // $jobdata = ['id' => 11954,'uuid' => '001700c2-8127-4d02-80b3-ea26e7603ccf']; + // dd($job); $query = " SELECT id, name, payload, uuid FROM jobs diff --git a/app/Libraries/S3Service.php b/app/Libraries/S3Service.php new file mode 100644 index 00000000..872b13ab --- /dev/null +++ b/app/Libraries/S3Service.php @@ -0,0 +1,268 @@ +bucket = getenv('AWS_BUCKET'); + $this->region = getenv('AWS_DEFAULT_REGION'); + + $this->s3Client = new S3Client([ + 'version' => 'latest', + 'region' => $this->region, + 'credentials' => [ + 'key' => getenv('AWS_ACCESS_KEY_ID'), + 'secret' => getenv('AWS_SECRET_ACCESS_KEY'), + ], + ]); + + $this->baseUrl = "https://{$this->bucket}.s3.{$this->region}.amazonaws.com/"; + // echo $this->baseUrl;die(); + } + + /** + * Upload file to S3 + * + * @param mixed $file File object or file path + * @param string $folder Folder path in S3 bucket (optional) + * @param string $fileName Custom file name (optional) + * @return array ['success' => bool, 'url' => string, 'key' => string, 'message' => string] + */ + public function upload($file, string $folder = '', string $fileName = null): array + { + try { + // Handle CodeIgniter file upload object + if (is_object($file) && method_exists($file, 'isValid')) { + if (!$file->isValid()) { + return [ + 'success' => false, + 'message' => 'Invalid file upload', + 'url' => null, + 'key' => null + ]; + } + $filePath = $file->getTempName(); + $originalName = $fileName ?? $file->getClientName(); + } else { + // Handle file path string + $filePath = $file; + $originalName = $fileName ?? basename($file); + } + + // Generate unique file name + $extension = pathinfo($originalName, PATHINFO_EXTENSION); + // $uniqueName = pathinfo($originalName, PATHINFO_FILENAME) . '_' . time() . '.' . $extension; + $uniqueName = pathinfo($originalName, PATHINFO_FILENAME) . '.' . $extension; + + // Build S3 key (path) + $key = $folder ? rtrim($folder, '/') . '/' . $uniqueName : $uniqueName; + + // Upload to S3 + // NEW - Faster with streaming and proper content type + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $mimeType = finfo_file($finfo, $filePath); + finfo_close($finfo); + + $result = $this->s3Client->putObject([ + 'Bucket' => $this->bucket, + 'Key' => $key, + 'Body' => fopen($filePath, 'rb'), // Stream instead of loading into memory + 'ContentType' => $mimeType, + // 'ACL' => 'public-read', + ]); + + return [ + 'success' => true, + 'url' => $this->baseUrl . $key, + 'key' => $key, + 'message' => 'File uploaded successfully' + ]; + + } catch (AwsException $e) { + log_message('error', 'S3 Upload Error: ' . $e->getMessage()); + return [ + 'success' => false, + 'message' => 'Upload failed: ' . $e->getMessage(), + 'url' => null, + 'key' => null + ]; + } + } + + /** + * Download file from S3 + * + * @param string $key S3 object key (file path in bucket) + * @param string $savePath Local path to save the file (optional) + * @return array ['success' => bool, 'path' => string, 'content' => string, 'message' => string] + */ + public function download(string $key, string $savePath = null): array + { + try { + $result = $this->s3Client->getObject([ + 'Bucket' => $this->bucket, + 'Key' => $key, + ]); + + $content = (string) $result['Body']; + + // If save path is provided, save to local file + if ($savePath) { + $directory = dirname($savePath); + if (!is_dir($directory)) { + mkdir($directory, 0755, true); + } + file_put_contents($savePath, $content); + + return [ + 'success' => true, + 'path' => $savePath, + 'content' => $content, + 'message' => 'File downloaded successfully' + ]; + } + + return [ + 'success' => true, + 'path' => null, + 'content' => $content, + 'message' => 'File content retrieved successfully' + ]; + + } catch (AwsException $e) { + log_message('error', 'S3 Download Error: ' . $e->getMessage()); + return [ + 'success' => false, + 'path' => null, + 'content' => null, + 'message' => 'Download failed: ' . $e->getMessage() + ]; + } + } + + /** + * Get a pre-signed URL for temporary access to a private file + * + * @param string $key S3 object key + * @param int $expiration Expiration time in minutes (default: 60) + * @return array ['success' => bool, 'url' => string, 'message' => string] + */ + public function getPresignedUrl(string $key, int $expiration = 60): array + { + try { + $cmd = $this->s3Client->getCommand('GetObject', [ + 'Bucket' => $this->bucket, + 'Key' => $key + ]); + + $request = $this->s3Client->createPresignedRequest($cmd, "+{$expiration} minutes"); + $presignedUrl = (string) $request->getUri(); + + return [ + 'success' => true, + 'url' => $presignedUrl, + 'message' => 'Pre-signed URL generated successfully' + ]; + + } catch (AwsException $e) { + log_message('error', 'S3 Presigned URL Error: ' . $e->getMessage()); + return [ + 'success' => false, + 'url' => null, + 'message' => 'Failed to generate URL: ' . $e->getMessage() + ]; + } + } + + /** + * Delete file from S3 + * + * @param string $key S3 object key + * @return array ['success' => bool, 'message' => string] + */ + public function delete(string $key): array + { + try { + $this->s3Client->deleteObject([ + 'Bucket' => $this->bucket, + 'Key' => $key, + ]); + + return [ + 'success' => true, + 'message' => 'File deleted successfully' + ]; + + } catch (AwsException $e) { + log_message('error', 'S3 Delete Error: ' . $e->getMessage()); + return [ + 'success' => false, + 'message' => 'Delete failed: ' . $e->getMessage() + ]; + } + } + + /** + * Check if file exists in S3 + * + * @param string $key S3 object key + * @return bool + */ + public function exists(string $key): bool + { + return $this->s3Client->doesObjectExist($this->bucket, $key); + } + + /** + * List files in S3 bucket + * + * @param string $prefix Folder prefix (optional) + * @return array ['success' => bool, 'files' => array, 'message' => string] + */ + public function listFiles(string $prefix = ''): array + { + try { + $result = $this->s3Client->listObjectsV2([ + 'Bucket' => $this->bucket, + 'Prefix' => $prefix, + ]); + + $files = []; + if (isset($result['Contents'])) { + foreach ($result['Contents'] as $object) { + $files[] = [ + 'key' => $object['Key'], + 'size' => $object['Size'], + 'last_modified' => $object['LastModified']->format('Y-m-d H:i:s'), + 'url' => $this->baseUrl . $object['Key'] + ]; + } + } + + return [ + 'success' => true, + 'files' => $files, + 'message' => 'Files retrieved successfully' + ]; + + } catch (AwsException $e) { + log_message('error', 'S3 List Error: ' . $e->getMessage()); + return [ + 'success' => false, + 'files' => [], + 'message' => 'Failed to list files: ' . $e->getMessage() + ]; + } + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index e86456ca..0aed2a9b 100755 --- a/composer.json +++ b/composer.json @@ -14,6 +14,7 @@ "ext-intl": "*", "ext-json": "*", "ext-mbstring": "*", + "aws/aws-sdk-php": "^3.369", "botman/botman": "^2.8", "botman/driver-web": "^1.5", "dompdf/dompdf": "^2.0", @@ -72,7 +73,7 @@ ] }, "config": { - "optimize-autoloader": true, + "optimize-autoloader": false, "preferred-install": "dist", "sort-packages": true, "process-timeout": 900 From c1c0887b2d8f8d0d9f4ec5158237763eadd1321b Mon Sep 17 00:00:00 2001 From: Gowtham M Date: Wed, 24 Dec 2025 18:45:25 +0530 Subject: [PATCH 3/5] sync tpa claims to nhance database: GWM --- app/Config/Routes.php | 3 +- app/Controllers/MediAssistApiController.php | 355 +++++++++++++++++++- 2 files changed, 342 insertions(+), 16 deletions(-) diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 13aff9ac..60be1178 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -767,11 +767,12 @@ $routes->get('claimStatus','VidalApiController::claimStatus'); $routes->get('EcardRequest','MediAssistApiController::EcardRequest'); $routes->get('HospitalNetwork','MediAssistApiController::HospitalNetwork'); $routes->get('GetBenefDetails','MediAssistApiController::GetBenefDetails'); -$routes->get('ClaimDetail','VidalApiController::ClaimDetail'); +$routes->get('ClaimDetail','MediAssistApiController::ClaimDetail'); $routes->get('SubmitClaim','MediAssistApiController::SubmitClaim'); $routes->get('IntimateClaim','MediAssistApiController::IntimateClaim'); $routes->get('IRSubmission','MediAssistApiController::IRSubmission'); $routes->get('ClaimStatusUpdate','MediAssistApiController::ClaimStatusUpdate'); +$routes->get('syncTpaClaimToNhance','MediAssistApiController::syncTpaClaimToNhance'); // API service diff --git a/app/Controllers/MediAssistApiController.php b/app/Controllers/MediAssistApiController.php index 245157e4..692eee3a 100644 --- a/app/Controllers/MediAssistApiController.php +++ b/app/Controllers/MediAssistApiController.php @@ -6,6 +6,7 @@ use App\Controllers\BaseController; use App\Models\BatchFileModel; use App\Models\EmployeePolicyModel; use App\Models\TpaApiDataModel; +use App\Models\ClientPolicyModel; use CodeIgniter\HTTP\ResponseInterface; use CodeIgniter\HTTP\IncomingRequest; use CodeIgniter\HTTP\RequestInterface; @@ -25,6 +26,7 @@ class MediAssistApiController extends BaseController } + public function SubmitClaim ($claimId = null) { @@ -482,7 +484,7 @@ class MediAssistApiController extends BaseController } } - public function ClaimDetail($claimId = null) // 585 this id for test + public function ClaimDetail($claimId = 585) // 585 this id for test { helper('api'); @@ -545,19 +547,21 @@ class MediAssistApiController extends BaseController // dd($body); - // $body = [ - // "policyNo" => "97000063250400000031", - // "startDate" => "31/08/2025", - // "endDate" => "01/09/2025", - // "employeeCode" => "CITPL120193", - // "memberID" => "", - // "claimNo" => "", - // "claimRefNo" => "HOSP4078102577_16092025111030" - // ]; + $body = [ + "policyNo" => "97000063250400000031", + "startDate" => "01/11/2025", + "endDate" => "05/11/2025", + "employeeCode" => "", + "memberID" => "", + "claimNo" => "", + "claimRefNo" => "" + ]; // CALL API $response = call_third_party_api($url, $method, $headers, $body); + dd($response); + if ($response['status'] != true || empty($response['data']['claimsData'][0])) { log_message('error', 'CLAIM STATUS FAILED | for ticket ID: ' . $claimId.' | response: '.json_encode($response)); @@ -616,9 +620,9 @@ class MediAssistApiController extends BaseController // Maping tpa claim status with local claim Status if (isset($validStatuses[$currentStatus])) { - $updateArray = ['claim_status_id' => $validStatuses[$currentStatus] , 'tpa_claim_status' => $currentStatus , 'tpa_claim_id' => $tpa_claim_no , 'updated_at' => date('Y-m-d H:i:s')]; + $updateArray = ['claim_status_id' => $validStatuses[$currentStatus] , 'tpa_claim_status' => $currentStatus , 'tpa_claim_id' => $tpa_claim_no, 'claim_number' => $tpa_claim_no, 'updated_at' => date('Y-m-d H:i:s')]; }else{ - $updateArray = ['tpa_claim_status' => $currentStatus , 'tpa_claim_id' => $tpa_claim_no , 'updated_at' => date('Y-m-d H:i:s')]; + $updateArray = ['tpa_claim_status' => $currentStatus , 'tpa_claim_id' => $tpa_claim_no, 'claim_number' => $tpa_claim_no , 'updated_at' => date('Y-m-d H:i:s')]; } // UPDATE ticket_master @@ -797,7 +801,6 @@ class MediAssistApiController extends BaseController // unlink($file_array['json_file_path']); // delete temp json file } - public function ClaimStatusUpdate() { helper('api'); @@ -928,9 +931,9 @@ class MediAssistApiController extends BaseController // Maping tpa claim status with local claim Status if (isset($validStatuses[$currentStatus])) { - $updateArray = ['claim_status_id' => $validStatuses[$currentStatus] , 'tpa_claim_status' => $currentStatus , 'tpa_claim_id' => $tpa_claim_no , 'updated_at' => date('Y-m-d H:i:s')]; + $updateArray = ['claim_status_id' => $validStatuses[$currentStatus] , 'tpa_claim_status' => $currentStatus , 'tpa_claim_id' => $tpa_claim_no , 'claim_number' => $tpa_claim_no , 'updated_at' => date('Y-m-d H:i:s')]; }else{ - $updateArray = ['tpa_claim_status' => $currentStatus , 'tpa_claim_id' => $tpa_claim_no , 'updated_at' => date('Y-m-d H:i:s')]; + $updateArray = ['tpa_claim_status' => $currentStatus , 'tpa_claim_id' => $tpa_claim_no , 'claim_number' => $tpa_claim_no, 'updated_at' => date('Y-m-d H:i:s')]; } // UPDATE ticket_master @@ -952,6 +955,328 @@ class MediAssistApiController extends BaseController ]); } + public function syncTpaClaimToNhance() + { + helper(['api', 'date']); + + $url = getenv('MEDI_ASSIST_API_BASE_URL_CLAIMSTATUS'); + $method = 'POST'; + + $headers = [ + 'Content-Type: application/json', + 'Username:' . getenv('MEDI_ASSIST_API_USERNAME'), + 'Password:' . getenv('MEDI_ASSIST_API_PASSWORD'), + ]; + + // REQUEST DATES + $reqStartDate = $this->request->getGet('start_date'); + $reqEndDate = $this->request->getGet('end_date'); + + // If start_date OR end_date is missing → last 7 days + if (empty($reqStartDate) || empty($reqEndDate)) { + + $endDateObj = new \DateTime(); // today + $startDateObj = (clone $endDateObj)->modify('-6 days'); + + } else { + + $startDateObj = new \DateTime($reqStartDate); + $endDateObj = new \DateTime($reqEndDate); + } + + // Final usable variables + $reqStartDate = $startDateObj->format('Y-m-d'); + $reqEndDate = $endDateObj->format('Y-m-d'); + + // Final usable variables + $reqStartDate = new \DateTime($reqStartDate); + $reqEndDate = new \DateTime($reqEndDate); + + + + // FETCH POLICY DATA + $policies = $this->db->table('client_policy cp') + ->select(" + cp.policy_no AS policyNo, + cp.policy_start_date AS policyStartDate, + cp.policy_end_date AS policyEndDate + ") + ->where('cp.is_active', 1) + ->where('cp.policy_type_id', 2) + ->where('cp.policy_status', 1) + // ->where('cp.policy_no', '97000063250400000031') + ->where('cp.tpa_id', $this->mediAssistTpaId) + ->get() + ->getResultArray(); + + if (empty($policies)) { + log_message('error', 'No policies found for claim sync'); + return $this->response->setJSON([ + 'status' => false, + 'message' => 'Policies not found' + ]); + } + + + + $finalResult = []; + $errorData = []; + + + // LOOP POLICIES + + foreach ($policies as $policy) { + + $policyStart = new \DateTime($policy['policyStartDate']); + $policyEnd = new \DateTime($policy['policyEndDate']); + + + // ADJUST DATE RANGE (inside policy period) + + $startDate = max($reqStartDate, $policyStart); + $endDate = min($reqEndDate, $policyEnd); + + + if ($startDate > $endDate) { + continue; // No valid range for this policy + } + + + // SPLIT INTO 7-DAY CHUNKS + + $chunkStart = clone $startDate; + + while ($chunkStart <= $endDate) { + + $chunkEnd = clone $chunkStart; + $chunkEnd->modify('+6 days'); + + if ($chunkEnd > $endDate) { + $chunkEnd = clone $endDate; + } + + + // PREPARE BODY + + $body = [ + "policyNo" => $policy['policyNo'], + "startDate" => $chunkStart->format('d/m/Y'), + "endDate" => $chunkEnd->format('d/m/Y'), + "employeeCode" => "", + "memberID" => "", + "claimNo" => "", + "claimRefNo" => "", + ]; + + + // CALL TPA API + + $response = call_third_party_api($url, $method, $headers, $body); + + if (empty($response['status']) || empty($response['data']['claimsData'])) { + + log_message('error','CLAIM STATUS FAILED | ' .'policyNo: ' . $policy['policyNo'] .' | ' . $chunkStart->format('Y-m-d') .' to ' . $chunkEnd->format('Y-m-d') .' | response: ' . json_encode($response) ); + + $errorData[] = [ + 'policy_no' => $policy['policyNo'], + 'start' => $chunkStart->format('Y-m-d'), + 'end' => $chunkEnd->format('Y-m-d'), + ]; + + } else { + + $finalResult = array_merge($finalResult,$response['data']['claimsData']); + } + + // Move to next chunk + $chunkStart->modify('+7 days'); + } + } + + + // 5️⃣ FINAL RESPONSE + foreach ($finalResult as $key => $value) { + + $relationship = strtolower(trim($value['relation'] ?? '')); + + if ($relationship === 'employee') { + $relationship = 'self'; + } + + $ticket = $this->db->table('ticket_master tm')->select("tm.id") + ->where('tm.policy_no', $value['policY_NUMBER']) + ->where('tm.emp_code', $value['employeE_NO']) + ->where('tm.claim_number', $value['tpA_CLAIM_NO']) + ->get() + ->getRowArray(); + + if(!$ticket) + { + + // VALID STATUS LIST + $validStatuses = [ + + "Claim Received" => 1, + "In Progress" => 5, + "Processed" => 11, + "Claim Paid" => 11, + "Denied" => 13, + "Cancelled" => 13, + + "Information Awaited" => 4, + "Confirmation Awaited" => 4, + "Information Awaited Reminder" => 4, + "Information Awaited Final Reminder" => 4, + "Insurer Concurrence Awaited" => 6, + "Closed" => 12, + + "Physical Documents Awaited" => 9, + "Processed - Payment Initiated" => 10, + "Processed - Transaction Failed" => 10, + "Processed - Account Details Updated" => 10, + "Processed - Debit Note Raised With Insurer for Payment"=> 10, + "Processed - Payment Initiated by Insurer" => 10, + "Payment - Refunded to Insurer" => 14, + "Processed - Processing Payment" => 10, + "Processed - Physical Documents Awaited" => 9, + + // Extra Mappings (based on your DB list) + "NON ID" => 1, + "ID NOT GENERATED" => 2, + "CDA" => 3, + "REJECTED" => 8, + "APPROVED" => 9, + "PAYMENT INITIATED" => 10, + "SETTLED" => 11, + "RETURNED" => 14, + "UNDER PROCESS - TPA" => 61, + "DENIAL REVIEW AWAITED" => 66, + ]; + + $currentStatus = trim($value['claim_Current_Status'] ?? ''); + + $claimStatusId = $validStatuses[$currentStatus] ?? null; + + if (!$claimStatusId) { + log_message('error', 'Unknown claim status: '.$currentStatus); + continue; + } + + $clientpolicy = $this->db->table('client_policy cp') + ->select(" + cp.id as client_policy_id, + cp.client_id , + cp.insurer_id , + cp.tpa_id , + client_rm.id as acm_id + ") + ->join('client_rm', 'client_rm.client_id = cp.client_id AND client_rm.level = 3', 'left') + ->where('cp.policy_no', $value['policY_NUMBER']) + ->get() + ->getRowArray(); + + $employee = $this->db->table('employees e') + ->select(" + e.id as emp_id, + e.emp_code , + e2.id as insured_emp_id, + ") + ->join( + 'employees e2', + "e2.emp_code = e.emp_code AND e2.relationship = ".$this->db->escape($relationship), + 'left' + ) + ->where('e.emp_code', $value['employeE_NO']) + ->where('e.relationship', 'self') + ->get() + ->getRowArray(); + + + + $claimData = [ + // Core + 'ticket_type_id' => 1, + 'claim_status_id' => $claimStatusId, + 'policy_no' => $value['policY_NUMBER'] ?? null, + 'claim_number' => $value['tpA_CLAIM_NO'] ?? null, + 'tpa_claim_id' => $value['tpA_CLAIM_NO'] ?? null, + + // local promary id + 'tpa_id' => $clientpolicy['tpa_id'] ?? null, + 'insurer_id' => $clientpolicy['insurer_id'] ?? null, + 'client_policy_id' => $clientpolicy['client_policy_id'] ?? null, + 'client_id' => $clientpolicy['client_id'] ?? null, + 'acm_id' => $clientpolicy['acm_id'] ?? null, + + // Employee / Insured + 'emp_id' => $employee['emp_id'] ?? null, + 'insured_emp_id' => $employee['insured_emp_id'] ?? null, + 'emp_code' => $value['employeE_NO'] ?? null, + 'emp_name' => $value['employeE_NAME'] ?? null, + 'insured_name' => $value['beneficiarY_NAME'] ?? null, + 'relationship' => $relationship, + 'emp_mobile' => $value['mobile'] ?? null, + 'emp_mail' => $value['email'] ?? null, + + // Claim info + 'claim_type' => 1, + 'mode_of_intimation' => 5, + 'claim_amount' => $value['estimateD_CLAIM_AMOUNT'] + ?? $value['finaL_BILL_AMOUNT'] + ?? null, + 'approved_amount' => $value['claiM_APPROVED_AMOUNT'] ?? null, + + // Dates + 'dob' => $this->mediDate($value['datE_OF_BIRTH'] ?? null), + 'doa' => $this->mediDate($value['datE_OF_ADMISSION'] ?? null), + 'dod' => $this->mediDate($value['datE_OF_DISCHARGE'] ?? null), + 'raised_date' => $this->mediDate($value['claiM_REGISTERED_DATE'] ?? null), + 'approved_date' => $this->mediDate($value['approved_Date'] ?? null), + 'settled_date' => $this->mediDate($value['paiD_DATE'] ?? null), + + // Hospital + 'hospital_name' => $value['hospitaL_NAME'] ?? null, + 'hospital_address' => $value['hospitaL_ADDRESS'] ?? null, + 'hospital_state' => $value['hospitaL_STATE'] ?? null, + 'hospital_city' => $value['hospitaL_CITY'] ?? null, + 'hospital_pin_code'=> $value['hosP_PINCODE'] ?? null, + + // Payment + 'utr_details' => $value['banK_CHEQUE_NO'] ?? null, + 'settle_letter' => $value['settlement_LetterLink'] ?? null, + ]; + + $this->db->table('ticket_master')->insert($claimData); + + log_message( + 'info', + 'New claim created | Policy: '.$claimData['policy_no']. + ' | Claim: '.$claimData['claim_number'] + ); + + } + + } + + + return $this->response->setJSON([ + 'status' => true, + 'message' => 'TPA claim status sync completed', + 'total_records' => count($finalResult), + 'result' => $finalResult, + 'errors' => $errorData + ]); + } + + + public function mediDate($date) + { + if (empty($date)) return null; + $dt = \DateTime::createFromFormat('d/m/Y H:i:s', $date); + return $dt ? $dt->format('Y-m-d') : null; + } + + From 40cb975f6389e5f749db7c9aad81abf981b9452d Mon Sep 17 00:00:00 2001 From: Gowtham M Date: Wed, 24 Dec 2025 18:47:16 +0530 Subject: [PATCH 4/5] sync tpa claims to nhance database: GWM --- app/Controllers/MediAssistApiController.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/Controllers/MediAssistApiController.php b/app/Controllers/MediAssistApiController.php index 692eee3a..ccf064db 100644 --- a/app/Controllers/MediAssistApiController.php +++ b/app/Controllers/MediAssistApiController.php @@ -547,20 +547,20 @@ class MediAssistApiController extends BaseController // dd($body); - $body = [ - "policyNo" => "97000063250400000031", - "startDate" => "01/11/2025", - "endDate" => "05/11/2025", - "employeeCode" => "", - "memberID" => "", - "claimNo" => "", - "claimRefNo" => "" - ]; + // $body = [ + // "policyNo" => "97000063250400000031", + // "startDate" => "01/11/2025", + // "endDate" => "05/11/2025", + // "employeeCode" => "", + // "memberID" => "", + // "claimNo" => "", + // "claimRefNo" => "" + // ]; // CALL API $response = call_third_party_api($url, $method, $headers, $body); - dd($response); + // dd($response); if ($response['status'] != true || empty($response['data']['claimsData'][0])) { log_message('error', 'CLAIM STATUS FAILED | for ticket ID: ' . $claimId.' | response: '.json_encode($response)); From 75b2c052fdd395d7bce4e198d8cacdb7dcc55c9f Mon Sep 17 00:00:00 2001 From: Gowtham M Date: Wed, 24 Dec 2025 18:49:48 +0530 Subject: [PATCH 5/5] sync tpa correction : GWM --- app/Controllers/MediAssistApiController.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Controllers/MediAssistApiController.php b/app/Controllers/MediAssistApiController.php index ccf064db..df595bb5 100644 --- a/app/Controllers/MediAssistApiController.php +++ b/app/Controllers/MediAssistApiController.php @@ -484,7 +484,7 @@ class MediAssistApiController extends BaseController } } - public function ClaimDetail($claimId = 585) // 585 this id for test + public function ClaimDetail($claimId = null) // 585 this id for test { helper('api'); @@ -545,7 +545,7 @@ class MediAssistApiController extends BaseController } - // dd($body); + // $body = [ // "policyNo" => "97000063250400000031", @@ -560,7 +560,7 @@ class MediAssistApiController extends BaseController // CALL API $response = call_third_party_api($url, $method, $headers, $body); - // dd($response); + if ($response['status'] != true || empty($response['data']['claimsData'][0])) { log_message('error', 'CLAIM STATUS FAILED | for ticket ID: ' . $claimId.' | response: '.json_encode($response));