option('dry-run'); $this->info('🔄 Syncing non-recurring payment provider subscriptions...'); if ($dryRun) { $this->warn('📋 DRY RUN MODE - No actual updates will be made'); } // Get all active non-recurring payment providers $nonRecurringProviders = PaymentProvider::where('is_active', true) ->where('supports_recurring', false) ->where('supports_one_time', true) ->pluck('name') ->toArray(); $this->info('📋 Non-recurring providers found: '.implode(', ', $nonRecurringProviders)); $totalProcessed = 0; $totalExpired = 0; foreach ($nonRecurringProviders as $providerName) { $this->info("🔍 Processing provider: {$providerName}"); $result = $this->syncProviderSubscriptions($providerName, $dryRun); $totalProcessed += $result['processed']; $totalExpired += $result['expired']; } $this->info('✅ Sync completed!'); $this->info("📊 Total subscriptions processed: {$totalProcessed}"); $this->info("⏰ Total subscriptions expired: {$totalExpired}"); if (! $dryRun && $totalExpired > 0) { $this->info('💡 Tip: Set up a cron job to run this command every few hours:'); $this->info(' */4 * * * * php artisan app:sync-non-recurring-subscriptions'); } } /** * Sync subscriptions for a specific provider */ protected function syncProviderSubscriptions(string $providerName, bool $dryRun): array { $query = Subscription::where('provider', $providerName) ->where('status', '!=', 'expired') ->where('status', '!=', 'cancelled') ->whereNotNull('ends_at'); if ($dryRun) { $subscriptions = $query->get(); $expiredCount = $subscriptions->filter(function ($sub) { return $sub->ends_at->isPast(); })->count(); $this->line(" 📊 Found {$subscriptions->count()} subscriptions"); $this->line(" ⏰ Would expire {$expiredCount} subscriptions"); return [ 'processed' => $subscriptions->count(), 'expired' => $expiredCount, ]; } // Get subscriptions that should be expired $expiredSubscriptions = $query->where('ends_at', '<', now())->get(); $expiredCount = 0; foreach ($expiredSubscriptions as $subscription) { try { $subscription->update([ 'status' => 'expired', 'unified_status' => 'expired', 'updated_at' => now(), ]); $expiredCount++; $this->line(" ✅ Expired subscription #{$subscription->id} (User: {$subscription->user_id})"); Log::info('Non-recurring subscription expired via sync command', [ 'subscription_id' => $subscription->id, 'provider' => $providerName, 'user_id' => $subscription->user_id, 'ends_at' => $subscription->ends_at, 'command' => 'app:sync-non-recurring-subscriptions', ]); } catch (\Exception $e) { $this->error(" ❌ Failed to expire subscription #{$subscription->id}: {$e->getMessage()}"); Log::error('Failed to expire non-recurring subscription', [ 'subscription_id' => $subscription->id, 'provider' => $providerName, 'error' => $e->getMessage(), ]); } } $totalProcessed = $query->count(); if ($expiredCount > 0) { $this->info(" ✅ Expired {$expiredCount} subscriptions for {$providerName}"); } else { $this->info(" â„šī¸ No expired subscriptions found for {$providerName}"); } return [ 'processed' => $totalProcessed, 'expired' => $expiredCount, ]; } }