'Optional client_policy_id to limit backfill', '--limit' => 'Batch size (default 1000)', ]; public function run(array $params) { $db = db_connect(); if (!$db->tableExists('claim_report')) { CLI::error('Table claim_report does not exist. Run migrations first.'); return EXIT_ERROR; } if (!$db->tableExists('ticket_master')) { CLI::error('Table ticket_master does not exist.'); return EXIT_ERROR; } $policyId = (int) (CLI::getOption('policy') ?? 0); $limit = (int) (CLI::getOption('limit') ?? 1000); if ($limit <= 0) { $limit = 1000; } $offset = 0; $totalInserted = 0; $totalUpdated = 0; $totalSkipped = 0; $now = date('Y-m-d H:i:s'); CLI::write('Backfilling claim_report from ticket_master (dump-sourced claims)...', 'yellow'); while (true) { $builder = $db->table('ticket_master') ->where('is_active', 1) ->groupStart() ->where('claim_dump_ref_id IS NOT NULL', null, false) ->orWhere('file_id IS NOT NULL', null, false) ->groupEnd() ->where("claim_number IS NOT NULL AND TRIM(claim_number) != ''", null, false) ->orderBy('id', 'ASC') ->limit($limit, $offset); if ($policyId > 0) { $builder->where('client_policy_id', $policyId); } $tickets = $builder->get()->getResultArray(); if ($tickets === []) { break; } $rows = []; foreach ($tickets as $tm) { $claimNumber = trim((string) ($tm['claim_number'] ?? '')); $clientPolicyId = (int) ($tm['client_policy_id'] ?? 0); if ($claimNumber === '' || $clientPolicyId <= 0) { $totalSkipped++; continue; } $rows[] = [ 'tpa_id' => $tm['tpa_id'] ?? null, 'client_id' => $tm['client_id'] ?? null, 'client_policy_id' => $clientPolicyId, 'file_id' => $tm['file_id'] ?? null, 'ticket_id' => $tm['id'] ?? null, 'source_table' => null, 'source_row_id' => $tm['claim_dump_ref_id'] ?? null, 'claim_number' => $claimNumber, 'emp_code' => $tm['emp_code'] ?? null, 'tpa_no' => $tm['tpa_no'] ?? null, 'emp_id' => $tm['emp_id'] ?? null, 'insured_emp_id' => $tm['insured_emp_id'] ?? null, 'claim_amount' => $tm['claim_amount'] ?? null, 'approved_amount' => $tm['approved_amount'] ?? null, 'incurred_amount' => $tm['approved_amount'] ?? $tm['claim_amount'] ?? null, 'si_amt' => $tm['si_amt'] ?? null, 'tpa_claim_status' => $tm['tpa_claim_status'] ?? null, 'claim_status_id' => $tm['claim_status_id'] ?? null, 'tpa_claim_type' => $tm['tpa_claim_type'] ?? null, 'tpa_ailments' => $tm['tpa_ailments'] ?? null, 'doa' => $tm['doa'] ?? null, 'dod' => $tm['dod'] ?? null, 'date_of_intimat' => $tm['date_of_intimat'] ?? null, 'settled_date' => $tm['settled_date'] ?? null, 'approved_date' => $tm['approved_date'] ?? null, 'claim_dump_date' => $tm['claim_dump_date'] ?? null, 'hospital_name' => $tm['hospital_name'] ?? null, 'hospital_city' => $tm['hospital_city'] ?? null, 'hospital_state' => $tm['hospital_state'] ?? null, 'hospital_pin_code'=> $tm['hospital_pin_code'] ?? null, 'hospital_address' => $tm['hospital_address'] ?? null, 'gender' => null, 'age' => null, 'relation' => $tm['relationship'] ?? null, 'is_active' => 1, 'created_at' => $now, 'updated_at' => $now, ]; } if ($rows !== []) { $result = $this->upsertRows($db, $rows); if ($result === false) { CLI::error('Upsert failed at offset ' . $offset); return EXIT_ERROR; } $totalInserted += $result['inserted']; $totalUpdated += $result['updated']; } $offset += count($tickets); CLI::write("Processed {$offset} ticket_master rows...", 'green'); if (count($tickets) < $limit) { break; } } CLI::write("Done. inserted≈{$totalInserted}, updated≈{$totalUpdated}, skipped={$totalSkipped}", 'green'); return EXIT_SUCCESS; } /** * @param list> $rows * @return array{inserted:int,updated:int}|false */ private function upsertRows($db, array $rows) { $columns = [ 'tpa_id', 'client_id', 'client_policy_id', 'file_id', 'ticket_id', 'source_table', 'source_row_id', 'claim_number', 'emp_code', 'tpa_no', 'emp_id', 'insured_emp_id', 'claim_amount', 'approved_amount', 'incurred_amount', 'si_amt', 'tpa_claim_status', 'claim_status_id', 'tpa_claim_type', 'tpa_ailments', 'doa', 'dod', 'date_of_intimat', 'settled_date', 'approved_date', 'claim_dump_date', 'hospital_name', 'hospital_city', 'hospital_state', 'hospital_pin_code', 'hospital_address', 'gender', 'age', 'relation', 'is_active', 'created_at', 'updated_at', ]; $updateCols = array_values(array_diff($columns, ['client_policy_id', 'claim_number', 'created_at'])); $inserted = 0; $updated = 0; foreach (array_chunk($rows, 100) as $chunk) { $placeholders = []; $binds = []; foreach ($chunk as $row) { $rowPlaceholders = []; foreach ($columns as $col) { $rowPlaceholders[] = '?'; $binds[] = $row[$col] ?? null; } $placeholders[] = '(' . implode(', ', $rowPlaceholders) . ')'; } $updates = []; foreach ($updateCols as $col) { $updates[] = '`' . $col . '` = VALUES(`' . $col . '`)'; } $sql = 'INSERT INTO `claim_report` (`' . implode('`, `', $columns) . '`) VALUES ' . implode(', ', $placeholders) . ' ON DUPLICATE KEY UPDATE ' . implode(', ', $updates); if ($db->query($sql, $binds) === false) { return false; } $affected = $db->affectedRows(); // MySQL: 1 = insert, 2 = update existing $updated += (int) floor($affected / 2); $inserted += max(0, $affected - (2 * (int) floor($affected / 2))); } return ['inserted' => $inserted, 'updated' => $updated]; } }