361 lines
11 KiB
PHP
361 lines
11 KiB
PHP
<?php
|
|
|
|
namespace App\Libraries\TPAClaimsImportServices;
|
|
|
|
use CodeIgniter\Database\BaseConnection;
|
|
use PhpOffice\PhpSpreadsheet\IOFactory;
|
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
|
use App\Models\TicketMasterModel;
|
|
use App\Models\EmployeeModel;
|
|
use App\Models\ClaimDumpFileModel;
|
|
use App\Models\ClaimsDumpFhplModel;
|
|
use RuntimeException;
|
|
|
|
abstract class BaseTpaClaimImportService
|
|
{
|
|
protected BaseConnection $db;
|
|
protected $claimDumpFileModel;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->db = db_connect();
|
|
$this->claimDumpFileModel = new ClaimDumpFileModel();
|
|
}
|
|
|
|
/**
|
|
* First JOB for insert TPA wise Bulk Upload
|
|
*/
|
|
public function runTpaClaimDumpInsert(string $filePath, int $fileId): array
|
|
{
|
|
// 1. Start Transaction
|
|
$this->db->transBegin();
|
|
|
|
try {
|
|
$fileData = $this->claimDumpFileModel->where('id', $fileId)->first();
|
|
|
|
// Determine sheet name logic...
|
|
if (env('FHPL_PRIMARY_KEY_CONSTANT') == $fileData['tpa_id']) {
|
|
$rows = $this->readExcelBySheetName($filePath, 'Claims&Preauth');
|
|
} else if (env('R_CARE_PRIMARY_KEY_CONSTANT') == $fileData['tpa_id']) {
|
|
$rows = $this->readExcelBySheetName($filePath, 'CL');
|
|
} else {
|
|
$rows = $this->readExcel($filePath);
|
|
}
|
|
|
|
if (empty($rows)) {
|
|
$this->db->transRollback(); // ROLLBACK BEFORE RETURN
|
|
return ['status' => false, 'message' => 'Excel file contains no data or wrong file upload'];
|
|
}
|
|
|
|
$tpaInsertData = $this->mapTPAData($rows, $fileId);
|
|
|
|
if (empty($tpaInsertData)) {
|
|
$this->db->transRollback(); // ROLLBACK BEFORE RETURN
|
|
return ['status' => false, 'message' => 'These records already exist in the system.'];
|
|
}
|
|
|
|
$return_res = $this->bulkInsertTPATable($tpaInsertData);
|
|
|
|
if ($return_res !== true) {
|
|
$this->db->transRollback(); // ROLLBACK BEFORE RETURN
|
|
return ['status' => false, 'message' => 'TPA Import bulk insert failed'];
|
|
}
|
|
|
|
// 2. Commit if everything is fine
|
|
$this->db->transCommit();
|
|
return ['status' => true, 'message' => 'File uploaded successfully', 'record_count' => count($tpaInsertData)];
|
|
|
|
} catch (\Throwable $e) {
|
|
// 3. Rollback on any crash/exception
|
|
$this->db->transRollback();
|
|
return ['status' => false, 'message' => 'System error : ' . $e->getMessage()];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Second JOB for insert Ticket Master table after insert the TPA bulk upload success
|
|
*/
|
|
public function runTicketMasterInsert(array $params): array
|
|
{
|
|
// 1. Start manual transaction
|
|
$this->db->transBegin();
|
|
|
|
try {
|
|
$file_id = $params['file_id'];
|
|
$ticketMasterData = $this->mapClaimMasterData($file_id);
|
|
|
|
// Check if mapping failed
|
|
if (!$ticketMasterData['status']) {
|
|
$this->db->transRollback(); // ALWAYS rollback before early return
|
|
return $ticketMasterData;
|
|
}
|
|
|
|
$message = '';
|
|
$hasExecutedTask = false;
|
|
$status = true;
|
|
|
|
// Process Mapped Data
|
|
if (!empty($ticketMasterData['mapped_array'])) {
|
|
$insert_res = $this->importClaimMaster($ticketMasterData['mapped_array']);
|
|
if (!$insert_res) {
|
|
$this->db->transRollback();
|
|
return ['status' => false, 'message' => 'Ticket Master Claim bulk insert failed'];
|
|
}
|
|
$message .= 'Ticket Master Claim bulk insert success. ';
|
|
$hasExecutedTask = true;
|
|
}else{
|
|
$status = false;
|
|
}
|
|
|
|
// Process Rejected Reasons
|
|
if (!empty($ticketMasterData['rejected_reason_array'])) {
|
|
$update_res = $this->updateTicketMasterRejectedReasonInTPATable($ticketMasterData['rejected_reason_array']);
|
|
if (!$update_res) {
|
|
$this->db->transRollback();
|
|
return ['status' => false, 'message' => 'Updating rejected reasons failed'];
|
|
}
|
|
|
|
$message .= empty($ticketMasterData['mapped_array'])
|
|
? 'Those employee or dependent not in our system. '
|
|
: 'Ticket Master Claim rejected reason updated successfully. ';
|
|
$hasExecutedTask = true;
|
|
}
|
|
|
|
// If nothing was processed but no error occurred
|
|
if (!$hasExecutedTask) {
|
|
$this->db->transRollback();
|
|
return ['status' => false, 'message' => 'No data found to process.'];
|
|
}
|
|
|
|
// 2. Commit the transaction
|
|
$this->db->transCommit();
|
|
return ['status' => $status, 'message' => trim($message)];
|
|
|
|
} catch (\Throwable $th) {
|
|
// 3. Rollback on crash
|
|
$this->db->transRollback();
|
|
return [
|
|
'status' => false,
|
|
'message' => 'System error during Ticket Master Insert: ' . $th->getMessage()
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Read Excel and return associative rows (header based)
|
|
*/
|
|
protected function readExcel(string $filePath): array
|
|
{
|
|
helper('excel_util_helper');
|
|
|
|
if (!file_exists($filePath)) {
|
|
throw new RuntimeException("File not found: {$filePath}");
|
|
}
|
|
|
|
$spreadsheet = IOFactory::load($filePath);
|
|
$sheet = $spreadsheet->getActiveSheet();
|
|
|
|
$rows = $sheet->toArray(null, true, true, true);
|
|
|
|
// dd($rows);
|
|
|
|
if (count($rows) < 2) {
|
|
return [];
|
|
}
|
|
|
|
// First row is header
|
|
$headers = array_shift($rows);
|
|
$headers = array_map('trim', $headers);
|
|
|
|
$data = [];
|
|
|
|
foreach ($rows as $row) {
|
|
|
|
if(check_row_is_empty_or_null($row)){
|
|
break;
|
|
}
|
|
|
|
$item = [];
|
|
foreach ($headers as $key => $headerName) {
|
|
if ($headerName !== '') {
|
|
$item[$headerName] = $row[$key] ?? null;
|
|
}
|
|
}
|
|
$data[] = $item;
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Read Excel By Sheet name and return associative rows (header based)
|
|
*/
|
|
|
|
protected function readExcelBySheetName(string $filePath, string $sheetName): array
|
|
{
|
|
if (!file_exists($filePath)) {
|
|
throw new RuntimeException("File not found: {$filePath}");
|
|
}
|
|
|
|
$spreadsheet = IOFactory::load($filePath);
|
|
|
|
// Get sheet by name
|
|
$sheet = $spreadsheet->getSheetByName($sheetName);
|
|
|
|
if ($sheet === null) {
|
|
throw new RuntimeException("Sheet '{$sheetName}' not found in Excel file");
|
|
}
|
|
|
|
$rows = $sheet->toArray(null, true, true, true);
|
|
|
|
// Need at least header + one row
|
|
if (count($rows) < 2) {
|
|
return [];
|
|
}
|
|
|
|
// First row = headers
|
|
$headers = array_shift($rows);
|
|
$headers = array_map('trim', $headers);
|
|
|
|
$data = [];
|
|
|
|
foreach ($rows as $row) {
|
|
// Skip completely empty rows
|
|
if (!array_filter($row)) {
|
|
continue;
|
|
}
|
|
|
|
$item = [];
|
|
|
|
foreach ($headers as $key => $headerName) {
|
|
if ($headerName !== '') {
|
|
$item[$headerName] = $row[$key] ?? null;
|
|
}
|
|
}
|
|
|
|
$data[] = $item;
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
|
|
/**
|
|
* Dublicate check in the ticket_master table records
|
|
*/
|
|
protected function checkDublicateTicketMasterClaim(array $param): bool
|
|
{
|
|
$ticketMaster = new TicketMasterModel();
|
|
$ticket_master_data = $ticketMaster
|
|
->where('doa', $param['doa'])
|
|
->where('tpa_no', $param['tpa_no'])
|
|
->where('claim_amount', $param['claim_amount'])
|
|
->where('emp_code', $param['emp_code'])
|
|
->where('is_active', 1)
|
|
->findAll();
|
|
|
|
if(count($ticket_master_data) > 0){
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Dublicate check in the TPA specific table records
|
|
*/
|
|
protected function checkDuplicateTpaClaim(string $table, array $params): bool
|
|
{
|
|
return $this->db->table($table)
|
|
->where($params)
|
|
->where('is_active', 1)
|
|
->countAllResults() > 0;
|
|
}
|
|
|
|
/**
|
|
* Dublicate check in the TPA specific table records
|
|
*/
|
|
protected function getTpaClaimDumpData(string $table, array $params): array
|
|
{
|
|
return $this->db
|
|
->table($table)
|
|
->where('is_active', 1)
|
|
->where('file_id', $params['file_id'])
|
|
->where('ticket_id IS NULL')
|
|
->where('master_reject_reason IS NULL')
|
|
->get()
|
|
->getResultArray();
|
|
}
|
|
|
|
/**
|
|
* Dublicate check in the TPA specific table records
|
|
*/
|
|
public function getEmployeeDetails(int $client_id, int $client_policy_id, string $emp_code, string $relation): array
|
|
{
|
|
$EmployeeModel = new EmployeeModel();
|
|
$employeeData = $EmployeeModel
|
|
->select([
|
|
'employees.id AS id',
|
|
'employees.email_corporate AS emp_mail',
|
|
'employees.mobile AS emp_mobile',
|
|
'employees.name AS name',
|
|
'employees.emp_code AS emp_code',
|
|
|
|
// insured employee
|
|
'insured.id AS insured_emp_id',
|
|
'insured.name AS insured_name'
|
|
])
|
|
->join(
|
|
'employee_polices',
|
|
'employees.id = employee_polices.employee_id'
|
|
)
|
|
->join(
|
|
'employees AS insured',
|
|
"insured.emp_code = employees.emp_code
|
|
AND insured.client_id = employees.client_id
|
|
AND LOWER(insured.relationship) = " . $EmployeeModel->db->escape(strtolower($relation)),
|
|
'left'
|
|
)
|
|
->where('employees.is_active', 1)
|
|
->where('employee_polices.is_active', 1)
|
|
->where('employee_polices.client_policy_id', $client_policy_id)
|
|
->where('employees.client_id', $client_id)
|
|
->where('employees.emp_code', $emp_code)
|
|
->where('LOWER(employees.relationship)', 'self')
|
|
->first();
|
|
|
|
|
|
return $employeeData ?? [];
|
|
}
|
|
|
|
/**
|
|
* Map Excel rows to TPA table structure
|
|
*/
|
|
abstract protected function mapTPAData(array $rows, $fileId): array;
|
|
|
|
/**
|
|
* Map DB rows to Ticket Master table structure
|
|
*/
|
|
abstract protected function mapClaimMasterData($fileId): array;
|
|
|
|
/**
|
|
* Insert into TPA-specific table (bulk)
|
|
*/
|
|
abstract protected function bulkInsertTPATable(array $data): bool;
|
|
|
|
/**
|
|
* Insert into Ticket-Master-specific table (bulk)
|
|
*/
|
|
abstract protected function importClaimMaster(array $data): bool;
|
|
|
|
/**
|
|
* Update TPA table with ticket_master primary key
|
|
*/
|
|
abstract protected function updateTicketIdInTPATable(): bool;
|
|
|
|
/**
|
|
* Update TPA table with ticket_master insert rejected reason
|
|
*/
|
|
abstract protected function updateTicketMasterRejectedReasonInTPATable(array $data): bool;
|
|
}
|