mivita/app/Jobs/CancelShipmentJob.php
2026-01-23 17:35:23 +01:00

169 lines
5 KiB
PHP

<?php
namespace App\Jobs;
use Acme\Dhl\Models\DhlShipment;
use Acme\Dhl\Services\ShippingService;
use Acme\Dhl\Support\DhlClient;
use Exception;
use Illuminate\Bus\Queueable as BusQueueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
/**
* Job to cancel DHL shipments asynchronously
*
* This job handles the cancellation of DHL shipments in the background,
* preventing API timeouts and improving user experience.
*/
class CancelShipmentJob implements ShouldQueue
{
use BusQueueable, Dispatchable, InteractsWithQueue, SerializesModels;
/**
* @var DhlShipment
*/
public $dhlShipment;
/**
* @var array
*/
public $options;
/**
* The number of times the job may be attempted.
*
* @var int
*/
public $tries = 3;
/**
* The maximum number of seconds the job can run before timing out.
*
* @var int
*/
public $timeout = 60;
/**
* Create a new job instance.
*
* @param DhlShipment $dhlShipment
* @param array $options
*/
public function __construct(DhlShipment $dhlShipment, array $options = [])
{
$this->dhlShipment = $dhlShipment;
$this->options = $options;
// Set queue name based on priority
if (isset($options['priority']) && $options['priority'] === 'high') {
$this->onQueue('high-priority');
} else {
$this->onQueue('dhl-cancellations');
}
}
/**
* Execute the job.
*/
public function handle(): void
{
try {
Log::info('[DHL Queue] Starting shipment cancellation job', [
'shipment_id' => $this->dhlShipment->id,
'dhl_shipment_no' => $this->dhlShipment->dhl_shipment_no,
'attempt' => $this->attempts(),
]);
// Get DHL configuration
$settingController = new \App\Http\Controllers\SettingController;
$dhlConfig = $settingController->getDhlConfig();
// Create DHL client
$dhlClient = new DhlClient(
$dhlConfig['base_url'],
$dhlConfig['api_key'],
$dhlConfig['username'],
$dhlConfig['password']
);
// Create shipping service
$shippingService = new ShippingService($dhlClient);
// Cancel the shipment
$success = $shippingService->cancelLabel($this->dhlShipment->dhl_shipment_no);
if ($success) {
Log::info('[DHL Queue] Shipment cancelled successfully', [
'shipment_id' => $this->dhlShipment->id,
'dhl_shipment_no' => $this->dhlShipment->dhl_shipment_no,
]);
} else {
throw new Exception('Cancellation returned false');
}
} catch (Exception $e) {
Log::error('[DHL Queue] Shipment cancellation failed', [
'shipment_id' => $this->dhlShipment->id,
'dhl_shipment_no' => $this->dhlShipment->dhl_shipment_no,
'error' => $e->getMessage(),
'attempt' => $this->attempts(),
'max_tries' => $this->tries,
]);
// If this is the final attempt, mark as permanently failed
if ($this->attempts() >= $this->tries) {
Log::error('[DHL Queue] Shipment cancellation permanently failed', [
'shipment_id' => $this->dhlShipment->id,
'error' => $e->getMessage(),
]);
// Update shipment status to indicate cancellation failed
$this->dhlShipment->update([
'status' => 'failed',
]);
}
throw $e; // Re-throw to trigger retry mechanism
}
}
/**
* Handle a job failure.
*
* @param Exception $exception
*/
public function failed(Exception $exception): void
{
Log::error('[DHL Queue] CancelShipmentJob permanently failed', [
'shipment_id' => $this->dhlShipment->id,
'dhl_shipment_no' => $this->dhlShipment->dhl_shipment_no,
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
// Update shipment status to indicate cancellation failed
try {
$this->dhlShipment->update([
'status' => 'failed',
]);
} catch (Exception $e) {
Log::error('[DHL Queue] Could not update shipment status after failure', [
'shipment_id' => $this->dhlShipment->id,
'error' => $e->getMessage(),
]);
}
}
/**
* Determine the time at which the job should timeout.
*
* @return \DateTime
*/
public function retryUntil()
{
return now()->addHour(); // Shorter timeout for cancellations
}
}