<?php
 namespace App\Console\Commands; use App\Models\InvoiceBillingJob; use App\Modules\Billing\BillingModuleFactory; use App\Modules\Billing\BillingResponse; use App\Services\Billing\InvoicePdfStorage; use App\Services\Billing\LegalInvoiceFinalizer; use Illuminate\Console\Command; use Illuminate\Support\Facades\Log; class PollLegalInvoicesCommand extends Command { protected $signature = 'billing:poll-legal-invoices {--limit=50 : İşlenecek maksimum iş sayısı}'; protected $description = 'Asenkron gönderilmiş (submitted) yasal faturaların onay durumunu sorgula'; public function handle(LegalInvoiceFinalizer $finalizer, InvoicePdfStorage $pdfStore): int { if (! setting('billing_poll_legal_invoices', false)) { $this->info('Yasal fatura poll kapalı (billing_poll_legal_invoices). Atlanıyor.'); return self::SUCCESS; } $maxAttempts = (int) setting('billing_poll_max_attempts', 12); $limit = (int) $this->option('limit'); $jobs = InvoiceBillingJob::where('status', InvoiceBillingJob::STATUS_SUBMITTED) ->with(['billingModule', 'invoice']) ->orderBy('created_at', 'asc') ->limit($limit) ->get(); if ($jobs->isEmpty()) { $this->info('Onay bekleyen (submitted) iş yok.'); return self::SUCCESS; } $errorCount = 0; foreach ($jobs as $job) { try { $this->pollJob($job, $finalizer, $pdfStore, $maxAttempts); } catch (\Throwable $e) { $errorCount++; Log::warning('PollLegalInvoices: iş sorgulanamadı (submitted bırakıldı): '.$e->getMessage(), [ 'job_id' => $job->id, 'invoice_id' => $job->invoice_id, ]); } } return $errorCount > 0 ? self::FAILURE : self::SUCCESS; } protected function pollJob( InvoiceBillingJob $job, LegalInvoiceFinalizer $finalizer, InvoicePdfStorage $pdfStore, int $maxAttempts, ): void { $module = $job->billingModule; $invoice = $job->invoice; if (! $module || ! $invoice) { $job->update([ 'status' => InvoiceBillingJob::STATUS_FAILED, 'error_message' => 'Missing module or invoice', 'processed_at' => now(), ]); return; } $moduleInstance = BillingModuleFactory::createFromModel($module); $raw = $moduleInstance->checkInvoiceStatus((string) $job->external_id, []); $resp = $raw instanceof BillingResponse ? $raw : BillingResponse::fromArray((array) $raw); switch ($resp->status) { case 'approved': $finalizer->finalizeSuccess($job, $invoice, $resp, $pdfStore, 'PollLegalInvoices'); break; case 'rejected': $finalizer->finalizeFailure($job, $invoice, $resp); break; case 'pending': default: $attempts = (int) $job->retry_count + 1; if ($attempts >= $maxAttempts) { $timeout = new BillingResponse( success: false, message: "Yasal fatura onay poll'ü {$maxAttempts} denemede sonuçlanmadı (timeout)", raw: $resp->raw, ); $finalizer->finalizeFailure($job, $invoice, $timeout); } else { $job->update(['retry_count' => $attempts]); } break; } } } 