$invoiceData = [ 'subscription_id' => $localSubscription->id, 'payment_id' => $payment->id, 'invoice_start_date' => $startDate->toDateTimeString(), 'invoice_end_date' => $endDate->toDateTimeString(), 'membership_id' => $localSubscription->membership_id, 'key' => $key ]; if (!$isDryRun) { Invoice::create($invoiceData); } $invoicesToCreate[] = array_merge($invoiceData, ['user_id' => $user->id]); } } } // C. Delete Stray Invoices (payment_id is NULL) $strayCount = Invoice::whereNull('payment_id') ->where('subscription_id', $localSubscription->id) ->count(); if ($strayCount > 0) { $userIsImpacted = true; $strayInvoicesToDelete += $strayCount; if (!$isDryRun) { Invoice::whereNull('payment_id')->where('subscription_id', $localSubscription->id)->delete(); } } } if ($userIsImpacted) { $impactedUsers[] = [ 'user_id' => $user->id, 'name' => $user->name, 'email' => $user->email, ]; } } catch (\Exception $e) { $syncErrors[] = "User #{$user->id} ({$user->email}): " . $e->getMessage(); } $progressBar->advance(); } $progressBar->setMessage('Completed'); $progressBar->finish(); $this->newLine(2); if (!$isDryRun) { DB::commit(); } // Summary Tables $this->info("--- SYNCHRONIZATION SUMMARY ---"); $this->table( ['Metric', 'Count'], [ ['Users Evaluated', count($users)], ['Total Impacted Users', count($impactedUsers)], ['Subscriptions Updated', count($updatedSubscriptions)], ['Invoices ' . ($isDryRun ? 'To Create' : 'Created'), count($invoicesToCreate)], ['Stray Invoices ' . ($isDryRun ? 'To Delete' : 'Deleted'), $strayInvoicesToDelete], ['Errors Encountered', count($syncErrors)] ] ); if (count($updatedSubscriptions) > 0) { $this->newLine(); $this->info("--- SUBSCRIPTION END DATE CORRECTIONS ---"); $this->table( ['Sub ID', 'User ID', 'Old End Date', 'New End Date', 'Paid Cycles'], $updatedSubscriptions ); } if (count($impactedUsers) > 0) { $this->newLine(); $this->info("--- IMPACTED USERS ---"); $this->table( ['User ID', 'Name', 'Email'], $impactedUsers ); } if (count($syncErrors) > 0) { $this->newLine(); $this->error("--- ERRORS ---"); foreach ($syncErrors as $error) { $this->line("• " . $error); } } $this->newLine(); if ($isDryRun) { $this->comment("Dry run finished. Run without --dry-run to commit these changes."); } else { $this->info("Invoice and subscription sync completed successfully."); } return Command::SUCCESS; } }