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

202 lines
6.8 KiB
PHP

<?php
namespace App\Jobs;
use Acme\Dhl\Models\DhlShipment;
use Acme\Dhl\Services\ReturnsService;
use Acme\Dhl\Support\DhlClient;
use App\Http\Controllers\SettingController;
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 create DHL return labels asynchronously
*
* This job handles the creation of DHL return labels in the background,
* preventing API timeouts and improving user experience.
*/
class CreateReturnLabelJob implements ShouldQueue
{
use BusQueueable, Dispatchable, InteractsWithQueue, SerializesModels;
/**
* @var DhlShipment
*/
public $originalShipment;
/**
* @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 = 120;
/**
* Create a new job instance.
*
* @param DhlShipment $originalShipment
* @param array $options
*/
public function __construct(DhlShipment $originalShipment, array $options = [])
{
$this->originalShipment = $originalShipment;
$this->options = $options;
// Set queue name based on priority
if (isset($options['priority']) && $options['priority'] === 'high') {
$this->onQueue('high-priority');
} else {
$this->onQueue('dhl-returns');
}
}
/**
* Execute the job.
*/
public function handle(): void
{
try {
Log::info('[DHL Queue] Starting return label creation job', [
'original_shipment_id' => $this->originalShipment->id,
'original_shipment_number' => $this->originalShipment->dhl_shipment_no,
'attempt' => $this->attempts(),
]);
// Get DHL configuration
$settingController = new SettingController();
$dhlConfig = $settingController->getDhlConfig();
// Initialize DHL client
$dhlClient = new DhlClient(
$dhlConfig['base_url'],
$dhlConfig['api_key'],
$dhlConfig['username'],
$dhlConfig['password']
);
// Use ReturnsService instead of ShippingService
$returnsService = new ReturnsService($dhlClient);
// Prepare return label data from original shipment
$returnData = $this->prepareReturnLabelData($dhlConfig);
Log::info('[DHL Queue] Prepared return data', [
'returnData' => $returnData,
]);
// Create the return label using ReturnsService (with automatic fallback)
$result = $returnsService->createReturn($returnData);
Log::info('[DHL Queue] Return label created successfully', [
'original_shipment_id' => $this->originalShipment->id,
'return_shipment_number' => $result['returnNumber'] ?? 'N/A',
]);
} catch (Exception $e) {
Log::error('[DHL Queue] Return label creation failed', [
'original_shipment_id' => $this->originalShipment->id,
'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] Return label creation permanently failed', [
'original_shipment_id' => $this->originalShipment->id,
'error' => $e->getMessage(),
]);
}
throw $e; // Re-throw to trigger retry mechanism
}
}
/**
* Prepare return label data based on original shipment
*/
private function prepareReturnLabelData(array $dhlConfig): array
{
$order = $this->originalShipment->shoppingOrder;
$recipient = $this->originalShipment->recipient ?? [];
return [
'order_id' => $order->id,
'original_shipment_id' => $this->originalShipment->id,
'weight_kg' => $this->originalShipment->weight_kg,
'label_format' => $this->originalShipment->label_format ?? 'PDF',
// Shipper: Customer sends back to us (swap addresses)
'shipper' => [
'name' => trim(($recipient['firstname'] ?? '') . ' ' . ($recipient['lastname'] ?? '')),
'name2' => $recipient['company'] ?? '',
'street' => $recipient['street'] ?? '',
'houseNumber' => $recipient['houseNumber'] ?? '',
'postalCode' => $recipient['postalCode'] ?? '',
'city' => $recipient['city'] ?? '',
'country' => $recipient['country'] ?? 'DEU',
'email' => $recipient['email'] ?? '',
'phone' => $recipient['phone'] ?? '',
],
// Consignee: Our warehouse (from settings)
'consignee' => [
'name' => $dhlConfig['sender']['company'] ?? 'mivita care gmbh',
'name2' => $dhlConfig['sender']['name'] ?? '',
'street' => $dhlConfig['sender']['street'] ?? 'Leinfeld',
'houseNumber' => $dhlConfig['sender']['house_number'] ?? '2',
'postalCode' => $dhlConfig['sender']['postalCode'] ?? '87755',
'city' => $dhlConfig['sender']['city'] ?? 'Kirchhaslach',
'country' => $dhlConfig['sender']['country'] ?? 'DEU',
'email' => $dhlConfig['sender']['email'] ?? 'versand@mivita.care',
'phone' => $dhlConfig['sender']['phone'] ?? '+49 123 456789',
],
];
}
/**
* Handle a job failure.
*
* @param Exception $exception
*/
public function failed(Exception $exception): void
{
Log::error('[DHL Queue] CreateReturnLabelJob permanently failed', [
'original_shipment_id' => $this->originalShipment->id,
'original_shipment_number' => $this->originalShipment->dhl_shipment_no,
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
// You could implement additional failure handling here:
// - Send notification to admin
// - Create manual task for staff to handle return label creation
// - Update original shipment to mark return label creation failed
}
/**
* Determine the time at which the job should timeout.
*
* @return \DateTime
*/
public function retryUntil()
{
return now()->addHours(2);
}
}