122 lines
4.2 KiB
PHP
122 lines
4.2 KiB
PHP
<?php
|
|
|
|
use Illuminate\Foundation\Inspiring;
|
|
use Illuminate\Support\Facades\Artisan;
|
|
use Illuminate\Support\Facades\Schedule;
|
|
use App\Services\LiveSqlImportService;
|
|
use App\Services\Billing\PaypalWebhookProcessor;
|
|
use App\Services\Billing\PayPalPlanSyncService;
|
|
use App\Models\Order;
|
|
use App\Models\Payment;
|
|
use App\Models\Subscription;
|
|
use App\Models\WebhookEvent;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use App\Mail\TestMailketing;
|
|
|
|
Artisan::command('inspire', function () {
|
|
$this->comment(Inspiring::quote());
|
|
})->purpose('Display an inspiring quote');
|
|
|
|
Artisan::command('dewemoji:import-live-sql {path : Absolute path to dewemojiAPI_DB.sql} {--truncate : Truncate target tables first} {--batch=500 : Insert batch size}', function () {
|
|
$path = (string) $this->argument('path');
|
|
$truncate = (bool) $this->option('truncate');
|
|
$batch = (int) $this->option('batch');
|
|
|
|
$importer = app(LiveSqlImportService::class);
|
|
$importer->import($path, $truncate, $batch, $this->output);
|
|
})->purpose('Import live SQL dump into the current database');
|
|
|
|
Artisan::command('dewemoji:webhooks:process {--limit=100 : Max events to process} {--status=pending,received : Comma-separated statuses}', function () {
|
|
$limit = (int) $this->option('limit');
|
|
$statuses = array_filter(array_map('trim', explode(',', (string) $this->option('status'))));
|
|
|
|
if (empty($statuses)) {
|
|
$this->error('No statuses provided.');
|
|
return 1;
|
|
}
|
|
|
|
$processor = app(PaypalWebhookProcessor::class);
|
|
|
|
$events = WebhookEvent::query()
|
|
->whereIn('status', $statuses)
|
|
->orderBy('id')
|
|
->limit($limit)
|
|
->get();
|
|
|
|
$processed = 0;
|
|
$failed = 0;
|
|
|
|
foreach ($events as $event) {
|
|
try {
|
|
if ($event->provider === 'paypal') {
|
|
$processor->process((string) ($event->event_type ?? ''), $event->payload ?? []);
|
|
}
|
|
$event->update([
|
|
'status' => 'processed',
|
|
'processed_at' => now(),
|
|
'error' => null,
|
|
]);
|
|
$processed++;
|
|
} catch (\Throwable $e) {
|
|
$event->update([
|
|
'status' => 'error',
|
|
'processed_at' => now(),
|
|
'error' => $e->getMessage(),
|
|
]);
|
|
$failed++;
|
|
}
|
|
}
|
|
|
|
$this->info("Processed {$processed} events, failed {$failed}.");
|
|
return 0;
|
|
})->purpose('Process pending webhook events');
|
|
|
|
Schedule::command('dewemoji:webhooks:process --limit=200')->everyMinute()->withoutOverlapping();
|
|
|
|
Artisan::command('paypal:sync-plans {--mode=both : sandbox|live|both}', function () {
|
|
$mode = (string) $this->option('mode');
|
|
$service = app(PayPalPlanSyncService::class);
|
|
|
|
$runMode = match ($mode) {
|
|
'sandbox' => ['sandbox'],
|
|
'live' => ['live'],
|
|
default => ['sandbox', 'live'],
|
|
};
|
|
|
|
foreach ($runMode as $env) {
|
|
$this->info("Syncing PayPal plans: {$env}");
|
|
$result = $service->sync($env);
|
|
$this->line("Created: {$result['created']} · Updated: {$result['updated']} · Deactivated: {$result['deactivated']} · Skipped: {$result['skipped']}");
|
|
}
|
|
})->purpose('Create/rotate PayPal plans based on pricing plans');
|
|
|
|
Artisan::command('mailketing:test {email : Recipient email address}', function () {
|
|
$email = (string) $this->argument('email');
|
|
|
|
try {
|
|
Mail::to($email)->send(new TestMailketing());
|
|
$this->info("Mailketing test email sent to {$email}.");
|
|
return 0;
|
|
} catch (\Throwable $e) {
|
|
$this->error('Mailketing test failed: '.$e->getMessage());
|
|
return 1;
|
|
}
|
|
})->purpose('Send a Mailketing API test email');
|
|
|
|
Artisan::command('dewemoji:normalize-statuses', function () {
|
|
$subs = Subscription::query()
|
|
->where('status', 'cancelled')
|
|
->update(['status' => 'canceled']);
|
|
|
|
$orders = Order::query()
|
|
->where('status', 'cancelled')
|
|
->update(['status' => 'canceled']);
|
|
|
|
$payments = Payment::query()
|
|
->where('status', 'cancelled')
|
|
->update(['status' => 'canceled']);
|
|
|
|
$this->info("Normalized statuses: subscriptions={$subs}, orders={$orders}, payments={$payments}");
|
|
return 0;
|
|
})->purpose('Normalize legacy cancelled status spelling to canceled');
|