option('days'); $sendEmails = $this->option('send-emails'); $dryRun = $this->option('dry-run'); $testEmail = $this->option('test-email'); $orderId = $this->option('order'); $this->info('DHL Tracking Update gestartet'); $this->info("Optionen: --days={$days}, --send-emails=" . ($sendEmails ? 'ja' : 'nein') . ', --dry-run=' . ($dryRun ? 'ja' : 'nein')); if ($testEmail) { $this->info("Test-Modus: E-Mails werden an {$testEmail} gesendet"); } if ($orderId) { $this->info("Filter: Nur Order-ID {$orderId}"); } $this->newLine(); // Hole alle aktiven Sendungen der letzten X Tage $query = DhlShipment::active() ->where('created_at', '>=', now()->subDays($days)) ->whereNotNull('dhl_shipment_no'); // Filter nach Order-ID wenn angegeben if ($orderId) { $query->where('order_id', $orderId); } $shipments = $query->orderBy('created_at', 'desc')->get(); $total = $shipments->count(); $this->info("Gefundene aktive Sendungen: {$total}"); if ($total === 0) { $this->info('Keine Sendungen zum Aktualisieren gefunden.'); return self::SUCCESS; } $bar = $this->output->createProgressBar($total); $bar->start(); $trackingService = new DhlTrackingService; $stats = [ 'updated' => 0, 'failed' => 0, 'emails_sent' => 0, 'skipped' => 0, ]; foreach ($shipments as $shipment) { try { $oldStatus = $shipment->status; if (! $dryRun) { // Tracking aktualisieren $result = $trackingService->updateTracking($shipment, ['auto_retrack' => false]); if ($result['success']) { $shipment->refresh(); $stats['updated']++; // Prüfen ob E-Mail gesendet werden soll if ($sendEmails && $this->shouldSendEmail($shipment, $oldStatus)) { $this->sendTrackingEmail($shipment, $testEmail); $stats['emails_sent']++; } } else { $stats['failed']++; Log::warning('[DHL Cron] Tracking update failed', [ 'shipment_id' => $shipment->id, 'message' => $result['message'] ?? 'Unknown error', ]); } } else { $stats['skipped']++; } } catch (\Exception $e) { $stats['failed']++; Log::error('[DHL Cron] Exception during tracking update', [ 'shipment_id' => $shipment->id, 'error' => $e->getMessage(), ]); } $bar->advance(); } $bar->finish(); $this->newLine(2); // Zusammenfassung $this->info('Zusammenfassung:'); $this->table( ['Metrik', 'Anzahl'], [ ['Gesamt', $total], ['Aktualisiert', $stats['updated']], ['Fehlgeschlagen', $stats['failed']], ['E-Mails gesendet', $stats['emails_sent']], ['Übersprungen (Dry-Run)', $stats['skipped']], ] ); Log::info('[DHL Cron] Tracking update completed', $stats); return self::SUCCESS; } /** * Prüft ob eine E-Mail gesendet werden soll */ private function shouldSendEmail(DhlShipment $shipment, string $oldStatus): bool { // E-Mail nur senden wenn: // 1. Status ist jetzt "in_transit" // 2. Vorheriger Status war NICHT "in_transit" (also Status hat sich geändert) // 3. Noch keine E-Mail gesendet wurde return $shipment->status === 'in_transit' && $oldStatus !== 'in_transit' && ! $shipment->wasTrackingEmailSent() && $shipment->canSendTrackingEmail(); } /** * Sendet die Tracking-E-Mail (mit Unterstützung für mehrere Sendungen pro Bestellung) */ private function sendTrackingEmail(DhlShipment $shipment, ?string $testEmail = null): void { try { $order = $shipment->shoppingOrder; // Determine recipient email: test email > shipment email > shopping user email $recipientEmail = null; if ($testEmail) { $recipientEmail = $testEmail; } elseif (! empty($shipment->email)) { $recipientEmail = $shipment->email; } elseif ($order->shopping_user && ! empty($order->shopping_user->email)) { $recipientEmail = $order->shopping_user->email; } if (! $recipientEmail) { Log::warning('[DHL Cron] Cannot send email - no recipient', [ 'shipment_id' => $shipment->id, ]); return; } // Sammle alle Sendungen für diese Bestellung, die noch keine E-Mail erhalten haben $allShipments = DhlShipment::where('order_id', $order->id) ->where('status', 'in_transit') ->whereNotNull('dhl_shipment_no') ->whereNull('tracking_email_sent_at') ->get(); // Wenn keine Sendungen gefunden, nutze nur die aktuelle if ($allShipments->isEmpty()) { $allShipments = collect([$shipment]); } // Sende E-Mail mit allen Sendungen Mail::to($recipientEmail)->send(new MailDhlTracking($allShipments, $order)); // Markiere alle Sendungen als versendet foreach ($allShipments as $s) { $s->markTrackingEmailSent('auto'); } Log::info('[DHL Cron] Tracking email sent automatically', [ 'shipment_ids' => $allShipments->pluck('id')->toArray(), 'shipments_count' => $allShipments->count(), 'dhl_shipment_nos' => $allShipments->pluck('dhl_shipment_no')->toArray(), 'email' => $recipientEmail, 'is_test' => ! is_null($testEmail), ]); if ($allShipments->count() > 1) { $this->line(" -> E-Mail mit {$allShipments->count()} Sendungen gesendet an: {$recipientEmail}"); } else { $this->line(" -> E-Mail gesendet an: {$recipientEmail}"); } } catch (\Exception $e) { Log::error('[DHL Cron] Failed to send tracking email', [ 'shipment_id' => $shipment->id, 'error' => $e->getMessage(), ]); } } }