From 4d7312e32e0ccdc49843e5adb4eb904e33caca4f Mon Sep 17 00:00:00 2001 From: Venkatesh Date: Wed, 8 Jul 2026 17:45:35 +0530 Subject: [PATCH] FEAT_TPA_CLAIM_DUMP_UPDATE_EXISTING_TICKET_STATUS --- app/Commands/TestIciciStatusUpdate.php | 413 ++++++++++++++ app/Commands/TestTpaStatusUpdate.php | 524 ++++++++++++++++++ .../AbhiClaimImportService.php | 39 +- .../BaseTpaClaimImportService.php | 178 +++++- .../FhplClaimImportService.php | 39 +- .../IciciClaimImportService.php | 41 +- .../MediAssistClaimImportService.php | 39 +- .../RcareClaimImportService.php | 39 +- .../VidalClaimImportService.php | 39 +- 9 files changed, 1205 insertions(+), 146 deletions(-) create mode 100644 app/Commands/TestIciciStatusUpdate.php create mode 100644 app/Commands/TestTpaStatusUpdate.php diff --git a/app/Commands/TestIciciStatusUpdate.php b/app/Commands/TestIciciStatusUpdate.php new file mode 100644 index 00000000..8221514f --- /dev/null +++ b/app/Commands/TestIciciStatusUpdate.php @@ -0,0 +1,413 @@ + 'Optional claim_dump_files.id to process', + ]; + protected $options = [ + '--scenario' => 'Seed a controlled pending dump row for one existing ICICI ticket and test status update', + '--apply' => 'Actually run runTicketMasterInsert (default is map-only dry-run)', + '--new-status' => 'Dump status string to use in scenario (default: REJECTED)', + ]; + + public function run(array $params) + { + helper('utility_helper'); + + $db = db_connect(); + $iciciTpaId = (int) env('ICICI_PRIMARY_KEY_CONSTANT'); + $fileId = $this->resolveFileId($params); + $apply = $this->hasFlag('apply'); + $scenario = $this->hasFlag('scenario'); + $newStatus = $this->resolveOptionValue('new-status', 'REJECTED'); + + CLI::write("ICICI_PRIMARY_KEY_CONSTANT = {$iciciTpaId}", 'yellow'); + CLI::write('Parsed args: file_id=' . $fileId . ', apply=' . ($apply ? 'yes' : 'no') . ', scenario=' . ($scenario ? 'yes' : 'no') . ', new_status=' . $newStatus, 'yellow'); + + if ($scenario) { + $fileId = $this->seedScenario($db, $iciciTpaId, $newStatus); + if ($fileId <= 0) { + return; + } + } + + if ($fileId <= 0) { + $recent = $db->table('claim_dump_files') + ->select('id, tpa_id, client_id, client_policy_id, file_name, status, created_at') + ->where('tpa_id', $iciciTpaId) + ->orderBy('id', 'DESC') + ->limit(10) + ->get() + ->getResultArray(); + + CLI::write('No --file_id provided. Recent ICICI claim_dump_files:', 'cyan'); + if (empty($recent)) { + CLI::error('No ICICI claim dump files found.'); + $this->printMatchPreview($db, $iciciTpaId); + return; + } + + foreach ($recent as $row) { + CLI::write(json_encode($row)); + } + + CLI::newLine(); + CLI::write('Controlled scenario test:', 'green'); + CLI::write(' php spark tpa:test-icici-status --scenario'); + CLI::write(' php spark tpa:test-icici-status --scenario --apply'); + CLI::write('Existing file (use positional file_id):'); + CLI::write(' php spark tpa:test-icici-status 68'); + CLI::write(' php spark tpa:test-icici-status 68 --apply'); + $this->printMatchPreview($db, $iciciTpaId); + return; + } + + $file = $db->table('claim_dump_files')->where('id', $fileId)->get()->getRowArray(); + if (empty($file)) { + CLI::error("claim_dump_files id={$fileId} not found"); + return; + } + + CLI::write('File: ' . json_encode([ + 'id' => $file['id'], + 'tpa_id' => $file['tpa_id'], + 'status' => $file['status'], + 'file_name' => $file['file_name'], + 'client_policy_id' => $file['client_policy_id'], + ]), 'cyan'); + + if ((int) $file['tpa_id'] !== $iciciTpaId) { + CLI::error("File tpa_id={$file['tpa_id']} is not ICICI ({$iciciTpaId}). Aborting."); + return; + } + + $pendingDump = $db->table('claims_dump_icici') + ->where('file_id', $fileId) + ->where('is_active', 1) + ->where('ticket_id IS NULL', null, false) + ->where('master_reject_reason IS NULL', null, false) + ->countAllResults(); + + CLI::write("Pending dump rows for mapClaimMasterData: {$pendingDump}", 'yellow'); + + $service = new IciciClaimImportService(); + + if ($apply) { + CLI::write('APPLY mode: running runTicketMasterInsert...', 'light_red'); + + $pendingBefore = $db->table('claims_dump_icici') + ->select('id, ticket_id, master_reject_reason, updated_status, employee_member_id, uhid, claimed_amount, doa') + ->where('file_id', $fileId) + ->where('is_active', 1) + ->get() + ->getResultArray(); + CLI::write('Dump rows BEFORE: ' . json_encode($pendingBefore, JSON_PRETTY_PRINT)); + + $result = $service->runTicketMasterInsert(['file_id' => $fileId]); + CLI::write('Result: ' . json_encode($result, JSON_PRETTY_PRINT)); + + $pendingAfter = $db->table('claims_dump_icici') + ->select('id, ticket_id, master_reject_reason, updated_status, employee_member_id, uhid, claimed_amount, doa') + ->where('file_id', $fileId) + ->where('is_active', 1) + ->get() + ->getResultArray(); + CLI::write('Dump rows AFTER: ' . json_encode($pendingAfter, JSON_PRETTY_PRINT)); + + $ticketIds = array_values(array_filter(array_column($pendingAfter, 'ticket_id'))); + if (!empty($ticketIds)) { + $ticketsAfter = $db->table('ticket_master') + ->select('id, claim_status_id, claim_dump_ref_id, emp_code, tpa_no, claim_amount, doa') + ->whereIn('id', $ticketIds) + ->get() + ->getResultArray(); + CLI::write('Linked tickets AFTER: ' . json_encode($ticketsAfter, JSON_PRETTY_PRINT)); + } + + return; + } + + CLI::write('DRY-RUN mode: calling mapClaimMasterData only (no DB writes)...', 'green'); + + $ref = new \ReflectionClass($service); + $method = $ref->getMethod('mapClaimMasterData'); + $method->setAccessible(true); + $mapped = $method->invoke($service, $fileId); + + if (empty($mapped['status'])) { + CLI::error('mapClaimMasterData failed: ' . ($mapped['message'] ?? 'unknown')); + if (!empty($mapped['error_data'])) { + CLI::write(json_encode($mapped['error_data'], JSON_PRETTY_PRINT)); + } + return; + } + + $inserts = $mapped['mapped_array'] ?? []; + $rejects = $mapped['rejected_reason_array'] ?? []; + $updates = $mapped['status_update_array'] ?? []; + + CLI::newLine(); + CLI::write('=== RESULT COUNTS ===', 'yellow'); + CLI::write('New tickets to insert : ' . count($inserts)); + CLI::write('Status updates (existing) : ' . count($updates)); + CLI::write('Rejected / skipped rows : ' . count($rejects)); + + CLI::newLine(); + CLI::write('=== STATUS UPDATE ARRAY ===', 'cyan'); + CLI::write(empty($updates) ? '(none)' : json_encode($updates, JSON_PRETTY_PRINT)); + + CLI::newLine(); + CLI::write('=== REJECT / SKIP REASONS (first 20) ===', 'cyan'); + CLI::write(json_encode(array_slice($rejects, 0, 20), JSON_PRETTY_PRINT)); + + if (!empty($updates)) { + CLI::newLine(); + CLI::write('Ticket fields BEFORE update:', 'yellow'); + $ids = array_column($updates, 'id'); + $before = $db->table('ticket_master') + ->select('id, emp_code, tpa_no, claim_amount, doa, claim_status_id, claim_dump_ref_id, file_id') + ->whereIn('id', $ids) + ->get() + ->getResultArray(); + CLI::write(json_encode($before, JSON_PRETTY_PRINT)); + } + + CLI::newLine(); + CLI::write('To apply for real:', 'green'); + CLI::write(" php spark tpa:test-icici-status {$fileId} --apply"); + } + + private function resolveFileId(array $params): int + { + if (!empty($params['file_id'])) { + return (int) $params['file_id']; + } + if (!empty($params[0]) && is_numeric($params[0])) { + return (int) $params[0]; + } + + // Fallback for --file_id=68 / --file_id 68 (CI option parsing can miss these) + $argv = $_SERVER['argv'] ?? []; + foreach ($argv as $i => $arg) { + if (preg_match('/^--file[_-]id=(.+)$/', (string) $arg, $m)) { + return (int) $m[1]; + } + if (in_array($arg, ['--file_id', '--file-id'], true) && isset($argv[$i + 1])) { + return (int) $argv[$i + 1]; + } + } + + $opt = CLI::getOption('file_id') ?? CLI::getOption('file-id'); + return (int) ($opt ?? 0); + } + + private function hasFlag(string $name): bool + { + if (CLI::getOption($name) !== null) { + return true; + } + + $argv = $_SERVER['argv'] ?? []; + return in_array('--' . $name, $argv, true); + } + + private function resolveOptionValue(string $name, string $default): string + { + $opt = CLI::getOption($name); + if (is_string($opt) && $opt !== '') { + return $opt; + } + + $argv = $_SERVER['argv'] ?? []; + foreach ($argv as $i => $arg) { + if (preg_match('/^--' . preg_quote($name, '/') . '=(.+)$/', (string) $arg, $m)) { + return trim($m[1]); + } + if ($arg === '--' . $name && isset($argv[$i + 1]) && strpos((string) $argv[$i + 1], '--') !== 0) { + return (string) $argv[$i + 1]; + } + } + + return $default; + } + + /** + * Create a temporary claim_dump_files + one pending claims_dump_icici row + * matching an existing ticket, with a different dump status. + */ + private function seedScenario($db, int $iciciTpaId, string $newStatus): int + { + CLI::write("Seeding controlled ICICI status-update scenario (new_status={$newStatus})...", 'cyan'); + + $ticket = $db->table('ticket_master') + ->select('id, client_id, client_policy_id, emp_code, tpa_no, claim_amount, doa, claim_status_id, claim_dump_ref_id, tpa_id') + ->where('tpa_id', $iciciTpaId) + ->where('is_active', 1) + ->where('emp_code IS NOT NULL', null, false) + ->where('tpa_no IS NOT NULL', null, false) + ->where('claim_amount IS NOT NULL', null, false) + ->where('doa IS NOT NULL', null, false) + ->orderBy('id', 'DESC') + ->get() + ->getRowArray(); + + if (empty($ticket)) { + // Fall back to any ticket, then override tpa matching by using that ticket's keys + $ticket = $db->table('ticket_master') + ->select('id, client_id, client_policy_id, emp_code, tpa_no, claim_amount, doa, claim_status_id, claim_dump_ref_id, tpa_id') + ->where('is_active', 1) + ->where('claim_created_by', 'DUMP_TPA') + ->where('emp_code IS NOT NULL', null, false) + ->where('tpa_no IS NOT NULL', null, false) + ->where('claim_amount IS NOT NULL', null, false) + ->where('doa IS NOT NULL', null, false) + ->orderBy('id', 'DESC') + ->get() + ->getRowArray(); + } + + if (empty($ticket)) { + CLI::error('No suitable existing ticket found to seed a status-update scenario.'); + return 0; + } + + CLI::write('Using existing ticket: ' . json_encode([ + 'id' => $ticket['id'], + 'emp_code' => $ticket['emp_code'], + 'tpa_no' => $ticket['tpa_no'], + 'claim_amount' => $ticket['claim_amount'], + 'doa' => $ticket['doa'], + 'claim_status_id' => $ticket['claim_status_id'], + 'claim_dump_ref_id' => $ticket['claim_dump_ref_id'] ?? null, + 'tpa_id' => $ticket['tpa_id'], + ]), 'yellow'); + + // Clear stale claim_dump_ref_id so the scenario can re-test link backfill. + if (!empty($ticket['claim_dump_ref_id'])) { + $db->table('ticket_master')->where('id', $ticket['id'])->update([ + 'claim_dump_ref_id' => null, + ]); + $ticket['claim_dump_ref_id'] = null; + CLI::write('Cleared stale ticket.claim_dump_ref_id for retest.', 'yellow'); + } + + // Ensure a physical file exists for resolveTpaClaimDumpFile if --apply uses controller later + $uploadDir = WRITEPATH . 'uploads' . DIRECTORY_SEPARATOR . 'claim_dump_excel' . DIRECTORY_SEPARATOR; + if (!is_dir($uploadDir)) { + mkdir($uploadDir, 0775, true); + } + $fileName = 'icici_status_test_' . date('Ymd_His') . '.xlsx'; + $filePath = $uploadDir . $fileName; + if (!is_file($filePath)) { + file_put_contents($filePath, 'placeholder'); + } + + $fileInsert = [ + 'tpa_id' => $iciciTpaId, + 'client_id' => $ticket['client_id'], + 'client_policy_id' => $ticket['client_policy_id'], + 'file_name' => $fileName, + 'status' => 'pending', + 'created_by' => 1, + 'created_at' => date('Y-m-d H:i:s'), + 'is_active' => 1, + ]; + + // claim_dump_files may have different nullable columns; insert only known-safe ones + $fileCols = array_column($db->query('SHOW COLUMNS FROM claim_dump_files')->getResultArray(), 'Field'); + $fileInsert = array_intersect_key($fileInsert, array_flip($fileCols)); + + $db->table('claim_dump_files')->insert($fileInsert); + $fileId = (int) $db->insertID(); + if ($fileId <= 0) { + CLI::error('Failed to create claim_dump_files row for scenario.'); + return 0; + } + + $dumpInsert = [ + 'client_id' => $ticket['client_id'], + 'client_policy_id' => $ticket['client_policy_id'], + 'file_id' => $fileId, + 'employee_member_id' => $ticket['emp_code'], + 'uhid' => $ticket['tpa_no'], + 'claimed_amount' => $ticket['claim_amount'], + 'doa' => $ticket['doa'], + 'updated_status' => $newStatus, + 'relation' => 'SELF', + 'is_active' => 1, + 'created_by' => 1, + 'created_at' => date('Y-m-d H:i:s'), + 'ticket_id' => null, + 'master_reject_reason' => null, + ]; + + $dumpCols = array_column($db->query('SHOW COLUMNS FROM claims_dump_icici')->getResultArray(), 'Field'); + $dumpInsert = array_intersect_key($dumpInsert, array_flip($dumpCols)); + + $db->table('claims_dump_icici')->insert($dumpInsert); + $dumpId = (int) $db->insertID(); + + CLI::write("Seeded file_id={$fileId}, dump_id={$dumpId}", 'green'); + CLI::write("Expected: if ticket claim_status_id ({$ticket['claim_status_id']}) != mapped REJECTED(8)/chosen status, status_update_array should contain ticket {$ticket['id']}", 'green'); + + return $fileId; + } + + private function printMatchPreview($db, int $iciciTpaId): void + { + CLI::newLine(); + CLI::write('Preview: dump rows that match existing tickets (possible status updates)', 'cyan'); + + $sql = " + SELECT + cd.id AS dump_id, + cd.file_id, + cd.employee_member_id, + cd.uhid, + cd.claimed_amount, + cd.doa, + cd.updated_status AS dump_status, + tm.id AS ticket_id, + tm.claim_status_id AS current_status_id + FROM claims_dump_icici cd + INNER JOIN ticket_master tm + ON tm.is_active = 1 + AND tm.emp_code = cd.employee_member_id + AND tm.tpa_no = cd.uhid + AND tm.claim_amount = cd.claimed_amount + AND tm.doa = cd.doa + WHERE cd.is_active = 1 + AND tm.tpa_id = ? + ORDER BY cd.id DESC + LIMIT 10 + "; + + $rows = $db->query($sql, [$iciciTpaId])->getResultArray(); + if (empty($rows)) { + CLI::write('No overlapping dump/ticket pairs found.'); + return; + } + + CLI::write(json_encode($rows, JSON_PRETTY_PRINT)); + } +} diff --git a/app/Commands/TestTpaStatusUpdate.php b/app/Commands/TestTpaStatusUpdate.php new file mode 100644 index 00000000..6dc61edc --- /dev/null +++ b/app/Commands/TestTpaStatusUpdate.php @@ -0,0 +1,524 @@ + 'Optional claim_dump_files.id to process', + ]; + protected $options = [ + '--tpa' => 'TPA key: icici|abhi|mediassist|fhpl|rcare|vidal|all (default: all for --scenario)', + '--scenario' => 'Seed one pending dump row matching an existing ticket', + '--apply' => 'Actually run runTicketMasterInsert (default is map-only dry-run)', + '--new-status' => 'Dump status string for scenario (defaults per TPA)', + ]; + + /** + * Per-TPA dump column mapping used to seed scenario rows. + */ + private function tpaConfigs(): array + { + return [ + 'icici' => [ + 'env' => 'ICICI_PRIMARY_KEY_CONSTANT', + 'table' => 'claims_dump_icici', + 'status_column' => 'updated_status', + 'default_status'=> 'REJECTED', + 'same_status' => 'PAID', + 'dump_to_ticket'=> [ + 'employee_member_id' => 'emp_code', + 'uhid' => 'tpa_no', + 'claimed_amount' => 'claim_amount', + 'doa' => 'doa', + ], + 'extra_dump' => [ + 'relation' => 'SELF', + ], + ], + 'abhi' => [ + 'env' => 'ABHI_PRIMARY_KEY_CONSTANT', + 'table' => 'claims_dump_abhi', + 'status_column' => 'claim_status', + 'default_status'=> 'Rejected', + 'same_status' => 'Settled', + 'dump_to_ticket'=> [ + 'member_code' => 'emp_code', + 'healthcard_id' => 'tpa_no', + 'claimed_amount' => 'claim_amount', + 'doa' => 'doa', + ], + 'extra_dump' => [ + 'relation' => 'SELF', + ], + ], + 'mediassist' => [ + 'env' => 'MEDI_ASSIST_PRIMARY_KEY_CONSTANT', + 'table' => 'claims_dump_medi_assist', + 'status_column' => 'claim_status', + 'default_status'=> 'Rejected', + 'same_status' => 'Settled', + 'dump_to_ticket'=> [ + 'pribenef_employee_code' => 'emp_code', + 'event_id' => 'tpa_no', + 'claim_amount' => 'claim_amount', + 'date_of_admission' => 'doa', + ], + 'extra_dump' => [ + 'benef_relation' => 'SELF', + ], + ], + 'fhpl' => [ + 'env' => 'FHPL_PRIMARY_KEY_CONSTANT', + 'table' => 'claims_dump_fhpl', + 'status_column' => 'current_claim_status', + 'default_status'=> 'Rejected', + 'same_status' => 'Settled', + 'dump_to_ticket'=> [ + 'employee_id' => 'emp_code', + 'uhid_no' => 'tpa_no', + 'claim_amount' => 'claim_amount', + 'admission_date' => 'doa', + ], + 'extra_dump' => [ + 'relationship' => 'SELF', + ], + ], + 'rcare' => [ + 'env' => 'R_CARE_PRIMARY_KEY_CONSTANT', + 'table' => 'claims_dump_reliance', + 'status_column' => 'final_status', + 'default_status'=> 'Rejected', + 'same_status' => 'Settled', + 'dump_to_ticket'=> [ + 'employee_member_id' => 'emp_code', + 'uhid' => 'tpa_no', + 'claimed_amount' => 'claim_amount', + 'doa_opd_treatment_from' => 'doa', + ], + 'extra_dump' => [ + 'relation' => 'SELF', + ], + ], + 'vidal' => [ + 'env' => 'VIDAL_PRIMARY_KEY_CONSTANT', + 'table' => 'claims_dump_vidal', + 'status_column' => 'claim_status', + 'default_status'=> 'Rejected', + 'same_status' => 'Settled', + 'dump_to_ticket'=> [ + 'employee_number' => 'emp_code', + 'primary_policy_holder_card_id' => 'tpa_no', + 'claim_amount' => 'claim_amount', + 'date_of_admission' => 'doa', + ], + 'extra_dump' => [ + 'relation' => 'SELF', + ], + ], + ]; + } + + public function run(array $params) + { + helper('utility_helper'); + + $db = db_connect(); + $apply = $this->hasFlag('apply'); + $scenario = $this->hasFlag('scenario'); + $tpaOpt = strtolower((string) ($this->resolveOptionValue('tpa', '') ?: (CLI::getOption('tpa') ?? ''))); + $fileId = $this->resolveFileId($params); + $newStatusOverride = $this->resolveOptionValue('new-status', ''); + + $configs = $this->tpaConfigs(); + + // Resolve which TPAs to run + if ($tpaOpt === '' || $tpaOpt === 'all') { + $selected = array_keys($configs); + if (!$scenario && $fileId <= 0) { + $this->printUsage($configs); + return; + } + } elseif (isset($configs[$tpaOpt])) { + $selected = [$tpaOpt]; + } else { + CLI::error("Unknown --tpa={$tpaOpt}. Use: " . implode('|', array_keys($configs)) . '|all'); + return; + } + + foreach ($selected as $tpaKey) { + CLI::newLine(); + CLI::write(str_repeat('=', 60), 'yellow'); + CLI::write('TPA: ' . strtoupper($tpaKey), 'yellow'); + CLI::write(str_repeat('=', 60), 'yellow'); + + try { + $this->runForTpa( + $db, + $tpaKey, + $configs[$tpaKey], + $scenario, + $apply, + $fileId, + $newStatusOverride + ); + } catch (\Throwable $e) { + CLI::error("[{$tpaKey}] " . $e->getMessage()); + } + } + } + + private function runForTpa( + $db, + string $tpaKey, + array $cfg, + bool $scenario, + bool $apply, + int $fileId, + string $newStatusOverride + ): void { + $tpaId = (int) env($cfg['env']); + CLI::write("{$cfg['env']} = {$tpaId}", 'cyan'); + CLI::write("table={$cfg['table']}, status_column={$cfg['status_column']}", 'cyan'); + + if (!$this->tableExists($db, $cfg['table'])) { + CLI::error("Table {$cfg['table']} does not exist. Skipping."); + return; + } + + $newStatus = $newStatusOverride !== '' ? $newStatusOverride : $cfg['default_status']; + $currentFileId = $fileId; + + if ($scenario) { + $currentFileId = $this->seedScenario($db, $tpaKey, $cfg, $tpaId, $newStatus); + if ($currentFileId <= 0) { + return; + } + } + + if ($currentFileId <= 0) { + $this->listRecentFiles($db, $tpaId, $tpaKey); + return; + } + + $file = $db->table('claim_dump_files')->where('id', $currentFileId)->get()->getRowArray(); + if (empty($file)) { + CLI::error("claim_dump_files id={$currentFileId} not found"); + return; + } + + CLI::write('File: ' . json_encode([ + 'id' => $file['id'], + 'tpa_id' => $file['tpa_id'], + 'status' => $file['status'], + 'file_name' => $file['file_name'], + 'client_policy_id' => $file['client_policy_id'], + ])); + + if ((int) $file['tpa_id'] !== $tpaId) { + CLI::error("File tpa_id={$file['tpa_id']} does not match {$tpaKey} ({$tpaId}). Skipping."); + return; + } + + $pending = $db->table($cfg['table']) + ->where('file_id', $currentFileId) + ->where('is_active', 1) + ->where('ticket_id IS NULL', null, false) + ->where('master_reject_reason IS NULL', null, false) + ->countAllResults(); + CLI::write("Pending dump rows: {$pending}"); + + $service = TpaClaimsImportFactory::make($tpaId); + + if ($apply) { + CLI::write('APPLY mode...', 'light_red'); + + $beforeDump = $db->table($cfg['table']) + ->select($this->dumpSelectColumns($cfg)) + ->where('file_id', $currentFileId) + ->where('is_active', 1) + ->get()->getResultArray(); + CLI::write('Dump BEFORE: ' . json_encode($beforeDump, JSON_PRETTY_PRINT)); + + $result = $service->runTicketMasterInsert(['file_id' => $currentFileId]); + CLI::write('Result: ' . json_encode($result, JSON_PRETTY_PRINT)); + + $afterDump = $db->table($cfg['table']) + ->select($this->dumpSelectColumns($cfg)) + ->where('file_id', $currentFileId) + ->where('is_active', 1) + ->get()->getResultArray(); + CLI::write('Dump AFTER: ' . json_encode($afterDump, JSON_PRETTY_PRINT)); + + $ticketIds = array_values(array_filter(array_column($afterDump, 'ticket_id'))); + if (!empty($ticketIds)) { + $tickets = $db->table('ticket_master') + ->select('id, claim_status_id, claim_dump_ref_id, emp_code, tpa_no, claim_amount, doa') + ->whereIn('id', $ticketIds) + ->get()->getResultArray(); + CLI::write('Tickets AFTER: ' . json_encode($tickets, JSON_PRETTY_PRINT)); + } + return; + } + + CLI::write('DRY-RUN mode (mapClaimMasterData only)...', 'green'); + $ref = new \ReflectionClass($service); + $method = $ref->getMethod('mapClaimMasterData'); + $method->setAccessible(true); + $mapped = $method->invoke($service, $currentFileId); + + if (empty($mapped['status'])) { + CLI::write('mapClaimMasterData: ' . ($mapped['message'] ?? 'failed')); + if (!empty($mapped['already_processed'])) { + CLI::write('(already processed — dump rows were NOT deleted)', 'green'); + } + return; + } + + $inserts = $mapped['mapped_array'] ?? []; + $rejects = $mapped['rejected_reason_array'] ?? []; + $updates = $mapped['status_update_array'] ?? []; + + CLI::write('inserts=' . count($inserts) . ' updates=' . count($updates) . ' rejects=' . count($rejects)); + CLI::write('status_update_array: ' . (empty($updates) ? '(none)' : json_encode($updates, JSON_PRETTY_PRINT))); + CLI::write('rejected_reason_array: ' . json_encode(array_slice($rejects, 0, 10), JSON_PRETTY_PRINT)); + + if (!empty($updates)) { + $ids = array_column($updates, 'id'); + $before = $db->table('ticket_master') + ->select('id, emp_code, tpa_no, claim_amount, doa, claim_status_id, claim_dump_ref_id') + ->whereIn('id', $ids) + ->get()->getResultArray(); + CLI::write('Tickets BEFORE: ' . json_encode($before, JSON_PRETTY_PRINT)); + } + + CLI::write("To apply: php spark tpa:test-status --tpa={$tpaKey} {$currentFileId} --apply", 'green'); + } + + private function seedScenario($db, string $tpaKey, array $cfg, int $tpaId, string $newStatus): int + { + CLI::write("Seeding scenario for {$tpaKey} (new_status={$newStatus})...", 'cyan'); + + $ticket = $db->table('ticket_master') + ->select('id, client_id, client_policy_id, emp_code, tpa_no, claim_amount, doa, claim_status_id, claim_dump_ref_id, tpa_id') + ->where('tpa_id', $tpaId) + ->where('is_active', 1) + ->where('emp_code IS NOT NULL', null, false) + ->where('tpa_no IS NOT NULL', null, false) + ->where('claim_amount IS NOT NULL', null, false) + ->where('doa IS NOT NULL', null, false) + ->orderBy('id', 'DESC') + ->get()->getRowArray(); + + if (empty($ticket)) { + // Fall back: any ticket with identity keys (still allows match by doa/emp/amount/tpa_no) + $ticket = $db->table('ticket_master') + ->select('id, client_id, client_policy_id, emp_code, tpa_no, claim_amount, doa, claim_status_id, claim_dump_ref_id, tpa_id') + ->where('is_active', 1) + ->where('emp_code IS NOT NULL', null, false) + ->where('tpa_no IS NOT NULL', null, false) + ->where('claim_amount IS NOT NULL', null, false) + ->where('doa IS NOT NULL', null, false) + ->orderBy('id', 'DESC') + ->get()->getRowArray(); + } + + if (empty($ticket)) { + CLI::error("[{$tpaKey}] No suitable existing ticket found to seed."); + return 0; + } + + CLI::write('Using ticket: ' . json_encode([ + 'id' => $ticket['id'], + 'emp_code' => $ticket['emp_code'], + 'tpa_no' => $ticket['tpa_no'], + 'claim_amount' => $ticket['claim_amount'], + 'doa' => $ticket['doa'], + 'claim_status_id' => $ticket['claim_status_id'], + 'claim_dump_ref_id' => $ticket['claim_dump_ref_id'], + 'tpa_id' => $ticket['tpa_id'], + ])); + + if (!empty($ticket['claim_dump_ref_id'])) { + $db->table('ticket_master')->where('id', $ticket['id'])->update(['claim_dump_ref_id' => null]); + CLI::write('Cleared stale ticket.claim_dump_ref_id for retest.', 'yellow'); + } + + $uploadDir = WRITEPATH . 'uploads' . DIRECTORY_SEPARATOR . 'claim_dump_excel' . DIRECTORY_SEPARATOR; + if (!is_dir($uploadDir)) { + mkdir($uploadDir, 0775, true); + } + $fileName = "{$tpaKey}_status_test_" . date('Ymd_His') . '.xlsx'; + file_put_contents($uploadDir . $fileName, 'placeholder'); + + $fileInsert = [ + 'tpa_id' => $tpaId, + 'client_id' => $ticket['client_id'], + 'client_policy_id' => $ticket['client_policy_id'], + 'file_name' => $fileName, + 'status' => 'pending', + 'created_by' => 1, + 'created_at' => date('Y-m-d H:i:s'), + 'is_active' => 1, + ]; + $fileCols = array_column($db->query('SHOW COLUMNS FROM claim_dump_files')->getResultArray(), 'Field'); + $fileInsert = array_intersect_key($fileInsert, array_flip($fileCols)); + $db->table('claim_dump_files')->insert($fileInsert); + $fileId = (int) $db->insertID(); + if ($fileId <= 0) { + CLI::error("[{$tpaKey}] Failed to create claim_dump_files row."); + return 0; + } + + $dumpInsert = [ + 'client_id' => $ticket['client_id'], + 'client_policy_id' => $ticket['client_policy_id'], + 'file_id' => $fileId, + 'is_active' => 1, + 'created_by' => 1, + 'created_at' => date('Y-m-d H:i:s'), + 'ticket_id' => null, + 'master_reject_reason' => null, + $cfg['status_column'] => $newStatus, + ]; + + foreach ($cfg['dump_to_ticket'] as $dumpCol => $ticketCol) { + $dumpInsert[$dumpCol] = $ticket[$ticketCol] ?? null; + } + foreach ($cfg['extra_dump'] as $col => $val) { + $dumpInsert[$col] = $val; + } + + $dumpCols = array_column($db->query('SHOW COLUMNS FROM ' . $cfg['table'])->getResultArray(), 'Field'); + $dumpInsert = array_intersect_key($dumpInsert, array_flip($dumpCols)); + + $db->table($cfg['table'])->insert($dumpInsert); + $dumpId = (int) $db->insertID(); + + CLI::write("Seeded file_id={$fileId}, dump_id={$dumpId}", 'green'); + return $fileId; + } + + private function dumpSelectColumns(array $cfg): string + { + $cols = ['id', 'ticket_id', 'master_reject_reason', 'file_id', $cfg['status_column']]; + foreach (array_keys($cfg['dump_to_ticket']) as $col) { + $cols[] = $col; + } + return implode(', ', array_unique($cols)); + } + + private function listRecentFiles($db, int $tpaId, string $tpaKey): void + { + $recent = $db->table('claim_dump_files') + ->select('id, tpa_id, client_id, client_policy_id, file_name, status, created_at') + ->where('tpa_id', $tpaId) + ->orderBy('id', 'DESC') + ->limit(5) + ->get()->getResultArray(); + + CLI::write("Recent {$tpaKey} claim_dump_files:"); + if (empty($recent)) { + CLI::write('(none)'); + } else { + foreach ($recent as $row) { + CLI::write(json_encode($row)); + } + } + CLI::write("Seed: php spark tpa:test-status --tpa={$tpaKey} --scenario", 'green'); + CLI::write("Apply: php spark tpa:test-status --tpa={$tpaKey} --scenario --apply", 'green'); + } + + private function printUsage(array $configs): void + { + CLI::write('Test existing-ticket status/link update for TPA claim dumps.', 'cyan'); + CLI::newLine(); + CLI::write('Dry-run all TPAs (seed scenario, no DB ticket update):'); + CLI::write(' php spark tpa:test-status --tpa=all --scenario'); + CLI::newLine(); + CLI::write('Apply all TPAs (writes to DB):'); + CLI::write(' php spark tpa:test-status --tpa=all --scenario --apply'); + CLI::newLine(); + CLI::write('Single TPA:'); + foreach (array_keys($configs) as $key) { + CLI::write(" php spark tpa:test-status --tpa={$key} --scenario"); + CLI::write(" php spark tpa:test-status --tpa={$key} --scenario --apply"); + } + CLI::newLine(); + CLI::write('Same-status (no status change, only null-link fill):'); + CLI::write(' php spark tpa:test-status --tpa=abhi --scenario --new-status Settled'); + } + + private function tableExists($db, string $table): bool + { + return !empty($db->query("SHOW TABLES LIKE " . $db->escape($table))->getResultArray()); + } + + private function resolveFileId(array $params): int + { + if (!empty($params['file_id'])) { + return (int) $params['file_id']; + } + if (!empty($params[0]) && is_numeric($params[0])) { + return (int) $params[0]; + } + + $argv = $_SERVER['argv'] ?? []; + foreach ($argv as $i => $arg) { + if (preg_match('/^--file[_-]id=(.+)$/', (string) $arg, $m)) { + return (int) $m[1]; + } + if (in_array($arg, ['--file_id', '--file-id'], true) && isset($argv[$i + 1])) { + return (int) $argv[$i + 1]; + } + } + + return (int) (CLI::getOption('file_id') ?? CLI::getOption('file-id') ?? 0); + } + + private function hasFlag(string $name): bool + { + if (CLI::getOption($name) !== null) { + return true; + } + return in_array('--' . $name, $_SERVER['argv'] ?? [], true); + } + + private function resolveOptionValue(string $name, string $default): string + { + $opt = CLI::getOption($name); + if (is_string($opt) && $opt !== '') { + return $opt; + } + + $argv = $_SERVER['argv'] ?? []; + foreach ($argv as $i => $arg) { + if (preg_match('/^--' . preg_quote($name, '/') . '=(.+)$/', (string) $arg, $m)) { + return trim($m[1]); + } + if ($arg === '--' . $name && isset($argv[$i + 1]) && strpos((string) $argv[$i + 1], '--') !== 0) { + return (string) $argv[$i + 1]; + } + } + + return $default; + } +} diff --git a/app/Libraries/TPAClaimsImportServices/AbhiClaimImportService.php b/app/Libraries/TPAClaimsImportServices/AbhiClaimImportService.php index 81a01aec..08da325e 100644 --- a/app/Libraries/TPAClaimsImportServices/AbhiClaimImportService.php +++ b/app/Libraries/TPAClaimsImportServices/AbhiClaimImportService.php @@ -242,20 +242,6 @@ class AbhiClaimImportService extends BaseTpaClaimImportService $item[$value] = change_date_format($item[$value] ?? null, 'm/d/Y h:i:s A', 'Y-m-d'); } - $params = [ - 'doa' => $item['doa'] ?? null, - 'member_code' => $item['member_code'] ?? null, - 'claimed_amount' => $item['claimed_amount'] ?? null, - 'healthcard_id' => $item['healthcard_id'] ?? null - ]; - - $is_duplicate = $this->checkDuplicateTpaClaim('claims_dump_abhi', $params); - - if ($is_duplicate) { - $item = []; - continue; - } - $item['file_id'] = $file_id ?? null; $item['client_id'] = $file_data['client_id'] ?? null; $item['client_policy_id'] = $file_data['client_policy_id'] ?? null; @@ -276,7 +262,7 @@ class AbhiClaimImportService extends BaseTpaClaimImportService $tpaClaimDumpData = $this->getTpaClaimDumpData('claims_dump_abhi', ['file_id' => $file_id]); if (empty($tpaClaimDumpData)) { - return ['status' => false, 'message' => "No data to insert in TICKET MASTER"]; + return $this->emptyClaimMasterMappingResponse('claims_dump_abhi', (int) $file_id); } @@ -302,6 +288,7 @@ class AbhiClaimImportService extends BaseTpaClaimImportService $mapped = []; $rejecetd_reason = []; + $status_update_array = []; foreach ($tpaClaimDumpData as $row) { @@ -312,11 +299,16 @@ class AbhiClaimImportService extends BaseTpaClaimImportService 'tpa_no' => $row['healthcard_id'] ?? null ]; - $isduplicate = $this->checkDublicateTicketMasterClaim($params); + $newStatusId = $this->checkStatusMapping($this->statusMapping, $row['claim_status'] ?? '') ?? 61; + $existingTicket = $this->getExistingTicketMasterClaim($params); - if ($isduplicate) { - $reason = "This claim already exists in our system."; - $rejecetd_reason[] = ["id" => $row['id'], "master_reject_reason" => $reason]; + if ($this->handleExistingTicketStatusUpdate( + $existingTicket, + $newStatusId, + (int) $row['id'], + $status_update_array, + $rejecetd_reason + )) { continue; } @@ -358,7 +350,7 @@ class AbhiClaimImportService extends BaseTpaClaimImportService } // Meta fields - $item['claim_status_id'] = $this->checkStatusMapping($this->statusMapping, $row['claim_status']); + $item['claim_status_id'] = $newStatusId; $item['file_id'] = $file_id; $item['claim_dump_ref_id'] = $row['id']; $item['claim_dump_date'] = $file_data['claim_dump_date'] ?? null; @@ -372,7 +364,12 @@ class AbhiClaimImportService extends BaseTpaClaimImportService $mapped[] = $item; } - return ['status' => true, 'mapped_array' => $mapped, 'rejected_reason_array' => $rejecetd_reason]; + return [ + 'status' => true, + 'mapped_array' => $mapped, + 'rejected_reason_array' => $rejecetd_reason, + 'status_update_array' => $status_update_array, + ]; } catch (\Throwable $th) { $errorData = [ diff --git a/app/Libraries/TPAClaimsImportServices/BaseTpaClaimImportService.php b/app/Libraries/TPAClaimsImportServices/BaseTpaClaimImportService.php index 467fceba..d5df02fc 100644 --- a/app/Libraries/TPAClaimsImportServices/BaseTpaClaimImportService.php +++ b/app/Libraries/TPAClaimsImportServices/BaseTpaClaimImportService.php @@ -116,16 +116,28 @@ abstract class BaseTpaClaimImportService // Check if mapping failed if (!$ticketMasterData['status']) { + // Already-processed dump rows (ticket_id linked) must not be deleted as a "failure". + if (!empty($ticketMasterData['already_processed'])) { + $this->db->transCommit(); + return [ + 'status' => true, + 'message' => $ticketMasterData['message'] ?? 'Claim dump already processed for this file.', + ]; + } + $this->rollbackAndCleanupClaimDumpData($file_id); return $ticketMasterData; } $message = ''; $hasExecutedTask = false; - $status = true; + $hasInserts = !empty($ticketMasterData['mapped_array']); + $hasExistingTicketUpdates = !empty($ticketMasterData['status_update_array']); + $hasRejectedReasons = !empty($ticketMasterData['rejected_reason_array']); + $hasExistingTicketLinks = $this->hasExistingTicketLinkUpdates($ticketMasterData['rejected_reason_array'] ?? []); // Process Mapped Data - if (!empty($ticketMasterData['mapped_array'])) { + if ($hasInserts) { $insert_res = $this->importClaimMaster($ticketMasterData['mapped_array']); if (!$insert_res) { return $this->failTicketMasterInsert($file_id, 'Ticket Master Claim bulk insert failed'); @@ -137,20 +149,33 @@ abstract class BaseTpaClaimImportService $message .= 'Ticket Master Claim bulk insert success. '; $hasExecutedTask = true; - }else{ - $status = false; } - // Process Rejected Reasons - if (!empty($ticketMasterData['rejected_reason_array'])) { + // Update existing tickets: status and/or missing claim_dump_ref_id + if ($hasExistingTicketUpdates) { + $update_status_res = $this->updateExistingTicketStatuses($ticketMasterData['status_update_array']); + if (!$update_status_res) { + return $this->failTicketMasterInsert($file_id, 'Updating existing tickets failed'); + } + + $message .= 'Existing ticket updated successfully. '; + $hasExecutedTask = true; + } + + // Process Rejected Reasons (also writes ticket_id onto TPA dump rows for existing tickets) + if ($hasRejectedReasons) { $update_res = $this->updateTicketMasterRejectedReasonInTPATable($ticketMasterData['rejected_reason_array']); if (!$update_res) { return $this->failTicketMasterInsert($file_id, 'Updating rejected reasons failed'); } - - $message .= empty($ticketMasterData['mapped_array']) - ? 'Those employee or dependent not in our system. ' - : 'Ticket Master Claim rejected reason updated successfully. '; + + if ($hasExistingTicketLinks) { + $message .= 'Existing claim dump ticket_id linked successfully. '; + } elseif (!$hasInserts && !$hasExistingTicketUpdates) { + $message .= 'Those employee or dependent not in our system. '; + } else { + $message .= 'Ticket Master Claim rejected reason updated successfully. '; + } $hasExecutedTask = true; } @@ -162,6 +187,7 @@ abstract class BaseTpaClaimImportService // 2. Commit the transaction $this->db->transCommit(); + $status = $hasInserts || $hasExistingTicketUpdates || $hasExistingTicketLinks; if (!$status) { $this->cleanupClaimDumpData($file_id); } @@ -323,22 +349,110 @@ abstract class BaseTpaClaimImportService */ 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(); + return $this->getExistingTicketMasterClaim($param) !== null; + } - if(count($ticket_master_data) > 0){ + /** + * Fetch existing ticket_master record matching claim identity keys. + */ + protected function getExistingTicketMasterClaim(array $param): ?array + { + $ticketMaster = new TicketMasterModel(); + $ticket = $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) + ->first(); + + return $ticket ?: null; + } + + /** + * Update existing ticket_master rows (status and/or claim_dump_ref_id). + */ + protected function updateExistingTicketStatuses(array $statusUpdates): bool + { + if (empty($statusUpdates)) { return true; } + $ticketMasterModel = new TicketMasterModel(); + return $ticketMasterModel->updateBatch($statusUpdates, 'id') !== false; + } + + /** + * True when rejected_reason rows include ticket_id links for existing tickets. + */ + protected function hasExistingTicketLinkUpdates(array $rejectedReasonArray): bool + { + foreach ($rejectedReasonArray as $row) { + if (!empty($row['ticket_id'])) { + return true; + } + } + return false; } + /** + * If ticket already exists: + * - update claim_status_id when changed + * - set claim_dump_ref_id on ticket_master when null + * - set ticket_id on TPA dump row when null (via rejected_reason_array) + * + * Returns true when the row was handled as an existing ticket (caller should continue). + */ + protected function handleExistingTicketStatusUpdate( + ?array $existingTicket, + int $newStatusId, + int $dumpRowId, + array &$statusUpdateArray, + array &$rejectedReasonArray + ): bool { + if (empty($existingTicket)) { + return false; + } + + $ticketId = $existingTicket['id']; + $currentStatusId = (int) ($existingTicket['claim_status_id'] ?? 0); + $statusChanged = $currentStatusId !== (int) $newStatusId; + $claimDumpRefIdMissing = empty($existingTicket['claim_dump_ref_id']); + + $ticketUpdate = ['id' => $ticketId]; + $reasons = []; + + if ($statusChanged) { + $ticketUpdate['claim_status_id'] = $newStatusId; + $reasons[] = 'status updated'; + } + + if ($claimDumpRefIdMissing) { + $ticketUpdate['claim_dump_ref_id'] = $dumpRowId; + $reasons[] = 'claim_dump_ref_id linked'; + } + + if (count($ticketUpdate) > 1) { + $statusUpdateArray[] = $ticketUpdate; + } + + if ($statusChanged || $claimDumpRefIdMissing) { + $reason = 'Existing claim ' . implode(' and ', $reasons) . '.'; + } else { + $reason = 'This claim already exists in our system.'; + } + + // Dump rows reaching here already have ticket_id NULL; link them to the existing ticket. + $rejectedReasonArray[] = [ + 'id' => $dumpRowId, + 'master_reject_reason' => $reason, + 'ticket_id' => $ticketId, + ]; + + return true; + } + /** * Dublicate check in the TPA specific table records */ @@ -365,6 +479,32 @@ abstract class BaseTpaClaimImportService ->getResultArray(); } + /** + * Response when no pending dump rows are left for ticket_master mapping. + * Marks already-processed files so cleanup does not delete linked dump rows. + */ + protected function emptyClaimMasterMappingResponse(string $table, int $fileId): array + { + $alreadyProcessed = $this->db->table($table) + ->where('file_id', $fileId) + ->where('is_active', 1) + ->groupStart() + ->where('ticket_id IS NOT NULL', null, false) + ->orWhere('master_reject_reason IS NOT NULL', null, false) + ->groupEnd() + ->countAllResults() > 0; + + if ($alreadyProcessed) { + return [ + 'status' => false, + 'already_processed' => true, + 'message' => 'Claim dump already processed for this file.', + ]; + } + + return ['status' => false, 'message' => 'No data to insert in TICKET MASTER']; + } + /** * Dublicate check in the TPA specific table records */ diff --git a/app/Libraries/TPAClaimsImportServices/FhplClaimImportService.php b/app/Libraries/TPAClaimsImportServices/FhplClaimImportService.php index 653043ef..e436be0a 100644 --- a/app/Libraries/TPAClaimsImportServices/FhplClaimImportService.php +++ b/app/Libraries/TPAClaimsImportServices/FhplClaimImportService.php @@ -308,20 +308,6 @@ class FhplClaimImportService extends BaseTpaClaimImportService $item[$value] = change_date_format($item[$value] ?? null, 'd-M-y', 'Y-m-d'); } - $params = [ - 'admission_date' => $item['admission_date'] ?? null, - 'employee_id' => $item['employee_id'] ?? null, - 'claim_amount' => $item['claim_amount'] ?? null, - 'uhid_no' => $item['uhid_no'] ?? null - ]; - - $is_duplicate = $this->checkDuplicateTpaClaim('claims_dump_fhpl', $params); - - if ($is_duplicate) { - $item = []; - continue; - } - $item['file_id'] = $file_id ?? null; $item['client_id'] = $file_data['client_id'] ?? null; $item['client_policy_id'] = $file_data['client_policy_id'] ?? null; @@ -342,7 +328,7 @@ class FhplClaimImportService extends BaseTpaClaimImportService $tpaClaimDumpData = $this->getTpaClaimDumpData('claims_dump_fhpl', ['file_id' => $file_id]); if (empty($tpaClaimDumpData)) { - return ['status' => false, 'message' => "No data to insert in TICKET MASTER"]; + return $this->emptyClaimMasterMappingResponse('claims_dump_fhpl', (int) $file_id); } @@ -368,6 +354,7 @@ class FhplClaimImportService extends BaseTpaClaimImportService $mapped = []; $rejecetd_reason = []; + $status_update_array = []; foreach ($tpaClaimDumpData as $row) { @@ -378,11 +365,16 @@ class FhplClaimImportService extends BaseTpaClaimImportService 'tpa_no' => $row['uhid_no'] ?? null ]; - $isduplicate = $this->checkDublicateTicketMasterClaim($params); + $newStatusId = $this->checkStatusMapping($this->statusMapping, $row['current_claim_status'] ?? '') ?? 61; + $existingTicket = $this->getExistingTicketMasterClaim($params); - if ($isduplicate) { - $reason = "This claim already exists in our system."; - $rejecetd_reason[] = ["id" => $row['id'], "master_reject_reason" => $reason]; + if ($this->handleExistingTicketStatusUpdate( + $existingTicket, + $newStatusId, + (int) $row['id'], + $status_update_array, + $rejecetd_reason + )) { continue; } @@ -424,7 +416,7 @@ class FhplClaimImportService extends BaseTpaClaimImportService } // Meta fields - $item['claim_status_id'] = $this->checkStatusMapping($this->statusMapping, $row['current_claim_status']) ?? 61; + $item['claim_status_id'] = $newStatusId; $item['file_id'] = $file_id; $item['claim_dump_ref_id'] = $row['id']; $item['claim_dump_date'] = $file_data['claim_dump_date'] ?? null; @@ -438,7 +430,12 @@ class FhplClaimImportService extends BaseTpaClaimImportService $mapped[] = $item; } - return ['status' => true, 'mapped_array' => $mapped, 'rejected_reason_array' => $rejecetd_reason]; + return [ + 'status' => true, + 'mapped_array' => $mapped, + 'rejected_reason_array' => $rejecetd_reason, + 'status_update_array' => $status_update_array, + ]; } catch (\Throwable $th) { diff --git a/app/Libraries/TPAClaimsImportServices/IciciClaimImportService.php b/app/Libraries/TPAClaimsImportServices/IciciClaimImportService.php index 15da3177..b4d61ebd 100644 --- a/app/Libraries/TPAClaimsImportServices/IciciClaimImportService.php +++ b/app/Libraries/TPAClaimsImportServices/IciciClaimImportService.php @@ -223,20 +223,6 @@ class IciciClaimImportService extends BaseTpaClaimImportService $item[$value] = change_date_format($item[$value] ?? null); } - $params = [ - 'doa' => change_date_format($item['doa'] ?? '') ?? null, - 'employee_member_id' => $item['employee_member_id'] ?? null, - 'claimed_amount' => $item['claimed_amount'] ?? null, - 'uhid' => $item['uhid'] ?? null - ]; - - $is_duplicate = $this->checkDuplicateTpaClaim('claims_dump_icici', $params); - - if ($is_duplicate) { - $item = []; - continue; - } - $item['file_id'] = $file_id ?? null; $item['client_id'] = $file_data['client_id'] ?? null; $item['client_policy_id'] = $file_data['client_policy_id'] ?? null; @@ -257,7 +243,7 @@ class IciciClaimImportService extends BaseTpaClaimImportService $tpaClaimDumpData = $this->getTpaClaimDumpData('claims_dump_icici', ['file_id' => $file_id]); if (empty($tpaClaimDumpData)) { - return ['status' => false, 'message' => "No data to insert in TICKET MASTER"]; + return $this->emptyClaimMasterMappingResponse('claims_dump_icici', (int) $file_id); } @@ -283,21 +269,27 @@ class IciciClaimImportService extends BaseTpaClaimImportService $mapped = []; $rejecetd_reason = []; + $status_update_array = []; foreach ($tpaClaimDumpData as $row) { $params = [ 'doa' => change_date_format($row['doa'] ?? '') ?? null, 'emp_code' => $row['employee_member_id'] ?? null, - 'claim_amount' => $row['claim_amount'] ?? null, + 'claim_amount' => $row['claimed_amount'] ?? null, 'tpa_no' => $row['uhid'] ?? null ]; - $isduplicate = $this->checkDublicateTicketMasterClaim($params); + $newStatusId = $this->checkStatusMapping($this->statusMapping, $row['updated_status'] ?? '') ?? 61; + $existingTicket = $this->getExistingTicketMasterClaim($params); - if ($isduplicate) { - $reason = "This claim already exists in our system."; - $rejecetd_reason[] = ["id" => $row['id'], "master_reject_reason" => $reason]; + if ($this->handleExistingTicketStatusUpdate( + $existingTicket, + $newStatusId, + (int) $row['id'], + $status_update_array, + $rejecetd_reason + )) { continue; } @@ -339,7 +331,7 @@ class IciciClaimImportService extends BaseTpaClaimImportService } // Meta fields - $item['claim_status_id'] = $this->checkStatusMapping($this->statusMapping, $row['updated_status']) ?? 61; + $item['claim_status_id'] = $newStatusId; $item['claim_dump_ref_id'] = $row['id']; $item['file_id'] = $file_id; $item['claim_dump_date'] = $file_data['claim_dump_date'] ?? null; @@ -353,7 +345,12 @@ class IciciClaimImportService extends BaseTpaClaimImportService $mapped[] = $item; } - return ['status' => true, 'mapped_array' => $mapped, 'rejected_reason_array' => $rejecetd_reason]; + return [ + 'status' => true, + 'mapped_array' => $mapped, + 'rejected_reason_array' => $rejecetd_reason, + 'status_update_array' => $status_update_array, + ]; } catch (\Throwable $th) { diff --git a/app/Libraries/TPAClaimsImportServices/MediAssistClaimImportService.php b/app/Libraries/TPAClaimsImportServices/MediAssistClaimImportService.php index a6ea7d0c..e2533924 100644 --- a/app/Libraries/TPAClaimsImportServices/MediAssistClaimImportService.php +++ b/app/Libraries/TPAClaimsImportServices/MediAssistClaimImportService.php @@ -256,20 +256,6 @@ class MediAssistClaimImportService extends BaseTpaClaimImportService $item[$dbColumn] = $value; } - $params = [ - 'date_of_admission' => change_date_format($item['date_of_admission'] ?? '') ?? null, - 'pribenef_employee_code' => $item['pribenef_employee_code'] ?? null, - 'claim_amount' => $item['claim_amount'] ?? null, - 'event_id' => $item['event_id'] ?? null - ]; - - $is_duplicate = $this->checkDuplicateTpaClaim('claims_dump_medi_assist', $params); - - if ($is_duplicate) { - $item = []; - continue; - } - $item['file_id'] = $file_id ?? null; $item['client_id'] = $file_data['client_id'] ?? null; $item['client_policy_id'] = $file_data['client_policy_id'] ?? null; @@ -290,7 +276,7 @@ class MediAssistClaimImportService extends BaseTpaClaimImportService $tpaClaimDumpData = $this->getTpaClaimDumpData('claims_dump_medi_assist', ['file_id' => $file_id]); if (empty($tpaClaimDumpData)) { - return ['status' => false, 'message' => "No data to insert in TICKET MASTER"]; + return $this->emptyClaimMasterMappingResponse('claims_dump_medi_assist', (int) $file_id); } @@ -316,6 +302,7 @@ class MediAssistClaimImportService extends BaseTpaClaimImportService $mapped = []; $rejecetd_reason = []; + $status_update_array = []; foreach ($tpaClaimDumpData as $row) { @@ -326,11 +313,16 @@ class MediAssistClaimImportService extends BaseTpaClaimImportService 'tpa_no' => $row['event_id'] ?? null ]; - $isduplicate = $this->checkDublicateTicketMasterClaim($params); + $newStatusId = $this->checkStatusMapping($this->statusMapping, $row['claim_status'] ?? '') ?? 61; + $existingTicket = $this->getExistingTicketMasterClaim($params); - if ($isduplicate) { - $reason = "This claim already exists in our system."; - $rejecetd_reason[] = ["id" => $row['id'], "master_reject_reason" => $reason]; + if ($this->handleExistingTicketStatusUpdate( + $existingTicket, + $newStatusId, + (int) $row['id'], + $status_update_array, + $rejecetd_reason + )) { continue; } @@ -374,7 +366,7 @@ class MediAssistClaimImportService extends BaseTpaClaimImportService // Meta fields $item['claim_dump_ref_id'] = $row['id']; $item['file_id'] = $file_id; - $item['claim_status_id'] = $this->checkStatusMapping($this->statusMapping, $row['claim_status']) ?? 61; + $item['claim_status_id'] = $newStatusId; $item['claim_dump_date'] = $file_data['claim_dump_date'] ?? null; $item['created_by'] = $file_data['created_by'] ?? null; $item['claim_type'] = 1; @@ -386,7 +378,12 @@ class MediAssistClaimImportService extends BaseTpaClaimImportService $mapped[] = $item; } - return ['status' => true, 'mapped_array' => $mapped, 'rejected_reason_array' => $rejecetd_reason]; + return [ + 'status' => true, + 'mapped_array' => $mapped, + 'rejected_reason_array' => $rejecetd_reason, + 'status_update_array' => $status_update_array, + ]; } catch (\Throwable $th) { diff --git a/app/Libraries/TPAClaimsImportServices/RcareClaimImportService.php b/app/Libraries/TPAClaimsImportServices/RcareClaimImportService.php index 0b93f149..646a63e9 100644 --- a/app/Libraries/TPAClaimsImportServices/RcareClaimImportService.php +++ b/app/Libraries/TPAClaimsImportServices/RcareClaimImportService.php @@ -208,20 +208,6 @@ class RcareClaimImportService extends BaseTpaClaimImportService $item[$value] = change_date_format($item[$value] ?? null, 'd-M-y', 'Y-m-d'); } - $params = [ - 'doa_opd_treatment_from' => $item['doa_opd_treatment_from'] ?? null, - 'employee_member_id' => $item['employee_member_id'] ?? null, - 'claimed_amount' => $item['claimed_amount'] ?? null, - 'uhid' => $item['uhid'] ?? null - ]; - - $is_duplicate = $this->checkDuplicateTpaClaim('claims_dump_reliance', $params); - - if ($is_duplicate) { - $item = []; - continue; - } - $item['file_id'] = $file_id ?? null; $item['client_id'] = $file_data['client_id'] ?? null; $item['client_policy_id'] = $file_data['client_policy_id'] ?? null; @@ -242,7 +228,7 @@ class RcareClaimImportService extends BaseTpaClaimImportService $tpaClaimDumpData = $this->getTpaClaimDumpData('claims_dump_reliance', ['file_id' => $file_id]); if (empty($tpaClaimDumpData)) { - return ['status' => false, 'message' => "No data to insert in TICKET MASTER"]; + return $this->emptyClaimMasterMappingResponse('claims_dump_reliance', (int) $file_id); } @@ -268,6 +254,7 @@ class RcareClaimImportService extends BaseTpaClaimImportService $mapped = []; $rejecetd_reason = []; + $status_update_array = []; foreach ($tpaClaimDumpData as $row) { @@ -278,11 +265,16 @@ class RcareClaimImportService extends BaseTpaClaimImportService 'tpa_no' => $row['uhid'] ?? null ]; - $isduplicate = $this->checkDublicateTicketMasterClaim($params); + $newStatusId = $this->checkStatusMapping($this->statusMapping, $row['final_status'] ?? '') ?? 61; + $existingTicket = $this->getExistingTicketMasterClaim($params); - if ($isduplicate) { - $reason = "This claim already exists in our system."; - $rejecetd_reason[] = ["id" => $row['id'], "master_reject_reason" => $reason]; + if ($this->handleExistingTicketStatusUpdate( + $existingTicket, + $newStatusId, + (int) $row['id'], + $status_update_array, + $rejecetd_reason + )) { continue; } @@ -324,7 +316,7 @@ class RcareClaimImportService extends BaseTpaClaimImportService } // Meta fields - $item['claim_status_id'] = $this->checkStatusMapping($this->statusMapping, $row['final_status']) ?? 61; + $item['claim_status_id'] = $newStatusId; $item['file_id'] = $file_id; $item['created_by'] = $file_data['created_by'] ?? null; $item['claim_dump_ref_id'] = $row['id']; @@ -338,7 +330,12 @@ class RcareClaimImportService extends BaseTpaClaimImportService $mapped[] = $item; } - return ['status' => true, 'mapped_array' => $mapped, 'rejected_reason_array' => $rejecetd_reason]; + return [ + 'status' => true, + 'mapped_array' => $mapped, + 'rejected_reason_array' => $rejecetd_reason, + 'status_update_array' => $status_update_array, + ]; } catch (\Throwable $th) { diff --git a/app/Libraries/TPAClaimsImportServices/VidalClaimImportService.php b/app/Libraries/TPAClaimsImportServices/VidalClaimImportService.php index a0876b92..fd628cc9 100644 --- a/app/Libraries/TPAClaimsImportServices/VidalClaimImportService.php +++ b/app/Libraries/TPAClaimsImportServices/VidalClaimImportService.php @@ -455,20 +455,6 @@ class VidalClaimImportService extends BaseTpaClaimImportService $item[$dbColumn] = $value; } - $params = [ - 'date_of_admission' => change_date_format($item['date_of_admission'] ?? '') ?? null, - 'employee_number' => $item['employee_number'] ?? null, - 'claim_amount' => $item['claim_amount'] ?? null, - 'primary_policy_holder_card_id' => $item['primary_policy_holder_card_id'] ?? null - ]; - - $is_duplicate = $this->checkDuplicateTpaClaim('claims_dump_vidal', $params); - - if ($is_duplicate) { - $item = []; - continue; - } - $item['file_id'] = $file_id ?? null; $item['client_id'] = $file_data['client_id'] ?? null; $item['client_policy_id'] = $file_data['client_policy_id'] ?? null; @@ -489,7 +475,7 @@ class VidalClaimImportService extends BaseTpaClaimImportService $tpaClaimDumpData = $this->getTpaClaimDumpData('claims_dump_vidal', ['file_id' => $file_id]); if (empty($tpaClaimDumpData)) { - return ['status' => false, 'message' => "No data to insert in TICKET MASTER"]; + return $this->emptyClaimMasterMappingResponse('claims_dump_vidal', (int) $file_id); } @@ -515,6 +501,7 @@ class VidalClaimImportService extends BaseTpaClaimImportService $mapped = []; $rejecetd_reason = []; + $status_update_array = []; foreach ($tpaClaimDumpData as $row) { @@ -525,11 +512,16 @@ class VidalClaimImportService extends BaseTpaClaimImportService 'tpa_no' => $row['primary_policy_holder_card_id'] ?? null ]; - $isduplicate = $this->checkDublicateTicketMasterClaim($params); + $newStatusId = $this->checkStatusMapping($this->statusMapping, $row['claim_status'] ?? '') ?? 61; + $existingTicket = $this->getExistingTicketMasterClaim($params); - if ($isduplicate) { - $reason = "This claim already exists in our system."; - $rejecetd_reason[] = ["id" => $row['id'], "master_reject_reason" => $reason]; + if ($this->handleExistingTicketStatusUpdate( + $existingTicket, + $newStatusId, + (int) $row['id'], + $status_update_array, + $rejecetd_reason + )) { continue; } @@ -565,7 +557,7 @@ class VidalClaimImportService extends BaseTpaClaimImportService } // Meta fields - $item['claim_status_id'] = $this->checkStatusMapping($this->statusMapping, $row['claim_status']) ?? 61; + $item['claim_status_id'] = $newStatusId; $item['file_id'] = $file_id; $item['claim_dump_ref_id'] = $row['id']; $item['claim_dump_date'] = $file_data['claim_dump_date'] ?? null; @@ -579,7 +571,12 @@ class VidalClaimImportService extends BaseTpaClaimImportService $mapped[] = $item; } - return ['status' => true, 'mapped_array' => $mapped, 'rejected_reason_array' => $rejecetd_reason]; + return [ + 'status' => true, + 'mapped_array' => $mapped, + 'rejected_reason_array' => $rejecetd_reason, + 'status_update_array' => $status_update_array, + ]; } catch (\Throwable $th) {