27-05-2026 Update DHL Modul v2.0

This commit is contained in:
Kevin 2026-05-27 13:40:38 +00:00
parent 53bdba33cd
commit 036595be94
41 changed files with 3346 additions and 310 deletions

View file

@ -7,9 +7,13 @@ use App\Jobs\CancelShipmentJob;
// Old DHL model replaced with new package model
use App\Jobs\CreateReturnLabelJob;
use App\Mail\MailDhlTracking;
use App\Models\Country;
use App\Models\ShoppingOrder;
use App\Services\DhlAddressValidator;
use App\Services\DhlModalService;
use App\Services\DhlProductResolver;
use App\Services\DhlShipmentService;
use App\Services\DhlShipmentWeightCalculator;
use App\Services\DhlTrackingService;
use Exception;
use Illuminate\Http\JsonResponse;
@ -122,7 +126,12 @@ class DhlShipmentController extends Controller
$query->where('type', $request->get('type'));
}
if ($request->filled('status')) {
$query->where('status', $request->get('status'));
$status = DhlShipment::normalizeStatus($request->get('status'));
if ($status === 'canceled') {
$query->whereIn('status', ['canceled', 'cancelled']);
} else {
$query->where('status', $status);
}
}
if ($request->filled('date_from')) {
$query->whereDate('created_at', '>=', $request->get('date_from'));
@ -181,10 +190,11 @@ class DhlShipmentController extends Controller
'created' => ['class' => 'success', 'text' => 'Erstellt'],
'shipped' => ['class' => 'primary', 'text' => 'Versendet'],
'delivered' => ['class' => 'info', 'text' => 'Zugestellt'],
'cancelled' => ['class' => 'secondary', 'text' => 'Storniert'],
'canceled' => ['class' => 'secondary', 'text' => 'Storniert'],
'failed' => ['class' => 'danger', 'text' => 'Fehler'],
];
$statusInfo = $statusMap[$shipment->status] ?? ['class' => 'light', 'text' => e($shipment->status)];
$status = DhlShipment::normalizeStatus($shipment->status);
$statusInfo = $statusMap[$status] ?? ['class' => 'light', 'text' => e($shipment->status)];
return '<span class="badge badge-'.$statusInfo['class'].'">'.$statusInfo['text'].'</span>';
})
@ -277,6 +287,7 @@ class DhlShipmentController extends Controller
'order_id' => 'required|exists:shopping_orders,id',
'weight' => 'required|numeric|min:0.1|max:31.5',
'product_code' => 'sometimes|string',
'reference' => 'nullable|string|max:35',
'priority' => 'sometimes|string|in:normal,high',
'auto_track' => 'sometimes|boolean',
// Shipping address validation
@ -294,6 +305,10 @@ class DhlShipmentController extends Controller
]);
$order = ShoppingOrder::findOrFail($request->order_id);
$shipmentWeight = max(
(float) $request->weight,
(new DhlShipmentWeightCalculator)->calculate($order)
);
// Check if shipment already exists
/* $existingShipment = DhlShipment::where('shopping_order_id', $order->id)
@ -314,6 +329,7 @@ class DhlShipmentController extends Controller
// Prepare options for shipment creation
$options = [
'product_code' => $request->get('product_code', 'V01PAK'),
'reference' => $request->get('reference'),
'priority' => $request->get('priority', 'normal'),
'auto_track' => $request->get('auto_track', true),
'shipping_address' => $shippingAddress,
@ -323,15 +339,20 @@ class DhlShipmentController extends Controller
// Use DhlShipmentService (handles queue/sync automatically based on config)
$dhlShipmentService = new DhlShipmentService;
$result = $dhlShipmentService->createShipment($order, (float) $request->weight, $options);
$result = $dhlShipmentService->createShipment($order, $shipmentWeight, $options);
Log::info('[DHL Controller] Shipment creation processed', [
'order_id' => $order->id,
'weight' => $request->weight,
'weight' => $shipmentWeight,
'requested_weight' => $request->weight,
'queued' => $result['queued'] ?? false,
'success' => $result['success'] ?? false,
]);
if (! ($result['success'] ?? false)) {
return response()->json($result, ($result['type'] ?? null) === 'dhl_address_validation' ? 422 : 500);
}
return response()->json($result);
} catch (Exception $e) {
Log::error('[DHL Controller] Failed to dispatch shipment creation', [
@ -346,6 +367,81 @@ class DhlShipmentController extends Controller
}
}
public function validateAddress(Request $request, DhlAddressValidator $validator): JsonResponse
{
$country = $request->filled('shipping_country_id')
? Country::find($request->get('shipping_country_id'))
: null;
$resolver = new DhlProductResolver;
$result = $validator->validate(array_merge($request->all(), [
'shipping_country_code' => $country?->code,
]));
$errors = $result['errors'];
$warnings = $result['warnings'];
$product = [
'code' => $request->get('product_code'),
'scope' => null,
'scope_label' => 'Nicht geprüft',
'country_code' => $country?->code,
'country_label' => $country?->getLocated(),
];
if ($country) {
try {
$resolvedProductCode = $resolver->resolveProductCode(
$country->code,
$request->get('product_code'),
config('dhl.default_product', 'V01PAK')
);
$product = [
'code' => $resolvedProductCode,
'scope' => $resolver->getProductScope($resolvedProductCode),
'scope_label' => $resolver->getProductScopeLabel($resolvedProductCode),
'country_code' => $country->code,
'country_label' => $country->getLocated(),
];
} catch (\InvalidArgumentException $e) {
$errors[] = $e->getMessage();
}
}
$status = 'valid';
if ($errors !== []) {
$status = 'error';
} elseif ($warnings !== []) {
$status = 'warning';
}
return response()->json([
'success' => $errors === [],
'status' => $status,
'can_create_label' => $errors === [],
'errors' => array_values(array_unique($errors)),
'warnings' => array_values(array_unique($warnings)),
'message' => $this->addressValidationMessage($status),
'preflight' => [
'product' => $product,
'address' => [
'status' => $result['status'],
'normalized' => $result['normalized'],
'validation_available' => $result['validation_available'],
'validation_level' => $result['validation_level'],
'validation_message' => $result['validation_message'],
],
],
], $errors === [] ? 200 : 422);
}
private function addressValidationMessage(string $status): string
{
return match ($status) {
'valid' => 'Adresse ist formal versandfähig.',
'warning' => 'Adresse ist formal versandfähig, sollte aber vor der Labelerstellung geprüft werden.',
default => 'Adresse ist nicht versandfähig. Bitte korrigieren Sie die markierten Felder.',
};
}
/**
* Display the specified shipment
*/
@ -719,7 +815,7 @@ class DhlShipmentController extends Controller
// Mark all included shipments as sent
foreach ($allShipments as $s) {
$s->markTrackingEmailSent('manual');
$s->markTrackingEmailSent('manual', $recipientEmail, $allShipments);
}
Log::info('[DHL Controller] Tracking email sent', [