dhlShipment = $dhlShipment; $this->options = $options; // Set queue name - tracking is usually lower priority $this->onQueue('dhl-tracking'); } /** * Execute the job. */ public function handle(): void { try { Log::info('[DHL Queue] Starting shipment tracking job', [ 'shipment_id' => $this->dhlShipment->id, 'tracking_number' => $this->dhlShipment->tracking_number, 'attempt' => $this->attempts(), ]); $dhlService = new DhlApiService(); // Get tracking details $trackingDetails = $dhlService->getTrackingDetails($this->dhlShipment); Log::info('[DHL Queue] Shipment tracking updated successfully', [ 'shipment_id' => $this->dhlShipment->id, 'tracking_status' => $trackingDetails['status'] ?? 'unknown', 'events_count' => isset($trackingDetails['events']) ? count($trackingDetails['events']) : 0, ]); // Schedule next tracking update if shipment is still in transit if (isset($this->options['auto_retrack']) && $this->options['auto_retrack']) { $status = $trackingDetails['status'] ?? ''; if ($this->shouldContinueTracking($status)) { // Schedule next tracking in 2-6 hours based on current status $nextTrackingDelay = $this->getNextTrackingDelay($status); TrackShipmentJob::dispatch($this->dhlShipment, $this->options) ->delay(now()->addMinutes($nextTrackingDelay)); Log::info('[DHL Queue] Next tracking job scheduled', [ 'shipment_id' => $this->dhlShipment->id, 'delay_minutes' => $nextTrackingDelay, ]); } } } catch (Exception $e) { Log::warning('[DHL Queue] Shipment tracking failed', [ 'shipment_id' => $this->dhlShipment->id, 'tracking_number' => $this->dhlShipment->tracking_number, 'error' => $e->getMessage(), 'attempt' => $this->attempts(), 'max_tries' => $this->tries, ]); // For tracking, we don't necessarily need to fail hard if ($this->attempts() >= $this->tries) { Log::warning('[DHL Queue] Shipment tracking permanently failed', [ 'shipment_id' => $this->dhlShipment->id, 'error' => $e->getMessage(), ]); // Don't re-throw for final attempt - just log and continue return; } throw $e; // Re-throw to trigger retry mechanism } } /** * Handle a job failure. * * @param Exception $exception */ public function failed(Exception $exception): void { Log::warning('[DHL Queue] TrackShipmentJob permanently failed', [ 'shipment_id' => $this->dhlShipment->id, 'tracking_number' => $this->dhlShipment->tracking_number, 'error' => $exception->getMessage(), ]); // Tracking failures are less critical - just log them } /** * Determine if we should continue tracking this shipment * * @param string $status * @return bool */ private function shouldContinueTracking(string $status): bool { $finalStates = [ 'delivered', 'delivered_to_recipient', 'delivered_to_pickup_location', 'returned_to_sender', 'cancelled', 'lost', ]; return !in_array(strtolower($status), $finalStates); } /** * Get delay for next tracking update based on current status * * @param string $status * @return int Minutes until next tracking */ private function getNextTrackingDelay(string $status): int { switch (strtolower($status)) { case 'picked_up': case 'in_transit': return 120; // 2 hours for active shipments case 'out_for_delivery': return 60; // 1 hour when out for delivery case 'exception': case 'failed_attempt': return 240; // 4 hours for problem shipments default: return 180; // 3 hours default } } /** * Determine the time at which the job should timeout. * * @return \DateTime */ public function retryUntil() { return now()->addMinutes(30); // Short timeout for tracking } }