option('dry-run'); $userEmail = $this->option('user'); $connectionId = $this->option('connection'); if ($isDryRun) { $this->warn('DRY RUN — no changes will be saved.'); } $query = Account::query() ->whereNull('iban') ->whereNotNull('external_account_id') ->whereNotNull('banking_connection_id') ->whereHas('bankingConnection', fn ($q) => $q->where('provider', BankingProvider::EnableBanking)); if ($connectionId) { $query->where('banking_connection_id', $connectionId); } if ($userEmail) { $user = User::query()->where('email', $userEmail)->first(); if (! $user) { $this->error("User with email '{$userEmail}' not found."); return Command::FAILURE; } $query->where('user_id', $user->id); } $accounts = $query->get(); if ($accounts->isEmpty()) { $this->info('No accounts found with missing IBAN.'); return Command::SUCCESS; } $this->info("Found {$accounts->count()} account(s) with missing IBAN."); $bar = $this->output->createProgressBar($accounts->count()); $bar->start(); $updated = 0; $skipped = 0; $expiredSessions = 0; $failed = 0; foreach ($accounts as $account) { try { $data = $provider->getAccount($account->external_account_id); $iban = $data['account_id']['iban'] ?? null; if (! $iban) { $skipped++; $bar->advance(); continue; } if (! $isDryRun) { $account->update(['iban' => $iban]); } $updated++; } catch (RequestException $e) { if ($e->response->status() === 404) { $expiredSessions++; } else { $this->newLine(); $this->warn("Failed for account {$account->id} ({$account->external_account_id}): {$e->getMessage()}"); $failed++; } } catch (Throwable $e) { $this->newLine(); $this->warn("Failed for account {$account->id} ({$account->external_account_id}): {$e->getMessage()}"); $failed++; } $bar->advance(); } $bar->finish(); $this->newLine(); $verb = $isDryRun ? 'would be updated' : 'updated'; $this->info("IBAN {$verb} for {$updated} account(s). Skipped (no IBAN in API response): {$skipped}. Skipped (expired/revoked session): {$expiredSessions}. Failed: {$failed}."); return $failed > 0 ? Command::FAILURE : Command::SUCCESS; } }