27-05-2026 Update DHL Modul v2.0
This commit is contained in:
parent
53bdba33cd
commit
036595be94
41 changed files with 3346 additions and 310 deletions
|
|
@ -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', [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue