20-02-2026
This commit is contained in:
parent
a8b395e20d
commit
a00c42e770
252 changed files with 28785 additions and 8907 deletions
|
|
@ -52,7 +52,6 @@ class DhlShipmentController extends Controller
|
|||
// Get DHL configuration with admin settings
|
||||
$settingController = new \App\Http\Controllers\SettingController;
|
||||
$dhlConfig = $settingController->getDhlConfig();
|
||||
|
||||
// Create DhlClient with merged configuration
|
||||
$dhlClient = new \Acme\Dhl\Support\DhlClient(
|
||||
$dhlConfig['base_url'],
|
||||
|
|
@ -67,7 +66,7 @@ class DhlShipmentController extends Controller
|
|||
if ($connectionTest) {
|
||||
$result = [
|
||||
'success' => true,
|
||||
'message' => 'DHL API Verbindung erfolgreich getestet!',
|
||||
'message' => 'DHL API Verbindung erfolgreich getestet! '.config('dhl.config_source').' '.$dhlConfig['base_url'],
|
||||
'details' => [
|
||||
'base_url' => $dhlConfig['base_url'],
|
||||
'using_admin_config' => ! empty($dhlConfig['api_key']),
|
||||
|
|
@ -88,7 +87,7 @@ class DhlShipmentController extends Controller
|
|||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'DHL API Test fehlgeschlagen: ' . $e->getMessage(),
|
||||
'message' => 'DHL API Test fehlgeschlagen: '.$e->getMessage(),
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
|
@ -148,12 +147,13 @@ class DhlShipmentController extends Controller
|
|||
|
||||
return DataTables::eloquent($query)
|
||||
->addColumn('checkbox', function ($shipment) {
|
||||
return '<label class="custom-control custom-checkbox mb-0"><input type="checkbox" class="custom-control-input shipment-checkbox" value="' . $shipment->id . '"><span class="custom-control-label"></span></label>';
|
||||
return '<label class="custom-control custom-checkbox mb-0"><input type="checkbox" class="custom-control-input shipment-checkbox" value="'.$shipment->id.'"><span class="custom-control-label"></span></label>';
|
||||
})
|
||||
->editColumn('id', function ($shipment) {
|
||||
$class = $shipment->type === 'return' ? 'text-warning font-weight-bold' : 'text-primary font-weight-semibold';
|
||||
$icon = $shipment->type === 'return' ? '<i class="fas fa-undo mr-1"></i>' : '';
|
||||
return '<a href="' . route('admin.dhl.show', $shipment) . '" class="' . $class . '">' . $icon . '#' . $shipment->id . '</a>';
|
||||
|
||||
return '<a href="'.route('admin.dhl.show', $shipment).'" class="'.$class.'">'.$icon.'#'.$shipment->id.'</a>';
|
||||
})
|
||||
->addColumn('type', function ($shipment) {
|
||||
if ($shipment->type == 'outbound') {
|
||||
|
|
@ -164,16 +164,16 @@ class DhlShipmentController extends Controller
|
|||
})
|
||||
->addColumn('order', function ($shipment) {
|
||||
if ($shipment->order_id) {
|
||||
return '<a href="' . route('admin_sales_customers_detail', $shipment->order_id) . '" class="text-primary">#' . $shipment->order_id . '</a>';
|
||||
return '<a href="'.route('admin_sales_customers_detail', $shipment->order_id).'" class="text-primary">#'.$shipment->order_id.'</a>';
|
||||
}
|
||||
|
||||
return '<span class="text-muted">N/A</span>';
|
||||
})
|
||||
->addColumn('customer', function ($shipment) {
|
||||
return $shipment->firstname . ' ' . $shipment->lastname;
|
||||
return $shipment->firstname.' '.$shipment->lastname;
|
||||
})
|
||||
->editColumn('dhl_shipment_no', function ($shipment) {
|
||||
return $shipment->dhl_shipment_no ? '<code class="text-success">' . e($shipment->dhl_shipment_no) . '</code>' : '<span class="text-muted">-</span>';
|
||||
return $shipment->dhl_shipment_no ? '<code class="text-success">'.e($shipment->dhl_shipment_no).'</code>' : '<span class="text-muted">-</span>';
|
||||
})
|
||||
->addColumn('status', function ($shipment) {
|
||||
$statusMap = [
|
||||
|
|
@ -186,43 +186,43 @@ class DhlShipmentController extends Controller
|
|||
];
|
||||
$statusInfo = $statusMap[$shipment->status] ?? ['class' => 'light', 'text' => e($shipment->status)];
|
||||
|
||||
return '<span class="badge badge-' . $statusInfo['class'] . '">' . $statusInfo['text'] . '</span>';
|
||||
return '<span class="badge badge-'.$statusInfo['class'].'">'.$statusInfo['text'].'</span>';
|
||||
})
|
||||
->addColumn('tracking_status', function ($shipment) {
|
||||
if ($shipment->tracking_status) {
|
||||
return '<small class="text-muted">' . e($shipment->tracking_status) . '</small>' .
|
||||
($shipment->last_tracked_at ? '<br><small class="text-muted">' . $shipment->last_tracked_at->format('d.m.Y H:i') . '</small>' : '');
|
||||
return '<small class="text-muted">'.e($shipment->tracking_status).'</small>'.
|
||||
($shipment->last_tracked_at ? '<br><small class="text-muted">'.$shipment->last_tracked_at->format('d.m.Y H:i').'</small>' : '');
|
||||
}
|
||||
|
||||
return '<span class="text-muted">-</span>';
|
||||
})
|
||||
->editColumn('weight_kg', function ($shipment) {
|
||||
return number_format($shipment->weight_kg, 2) . ' kg';
|
||||
return number_format($shipment->weight_kg, 2).' kg';
|
||||
})
|
||||
->editColumn('created_at', function ($shipment) {
|
||||
return $shipment->created_at->format('d.m.Y H:i');
|
||||
})
|
||||
->addColumn('actions', function ($shipment) {
|
||||
$buttons = '<div class="btn-group" role="group">';
|
||||
$buttons .= '<a href="' . route('admin.dhl.show', $shipment) . '" class="btn btn-sm btn-outline-primary" data-toggle="tooltip" title="Details anzeigen"><i class="fas fa-eye"></i></a>';
|
||||
$buttons .= '<a href="'.route('admin.dhl.show', $shipment).'" class="btn btn-sm btn-outline-primary" data-toggle="tooltip" title="Details anzeigen"><i class="fas fa-eye"></i></a>';
|
||||
if ($shipment->label_path) {
|
||||
$buttons .= '<a href="' . route('admin.dhl.download-label', $shipment) . '" class="btn btn-sm btn-outline-success" data-toggle="tooltip" title="Label herunterladen"><i class="fas fa-download"></i></a>';
|
||||
$buttons .= '<a href="'.route('admin.dhl.download-label', $shipment).'" class="btn btn-sm btn-outline-success" data-toggle="tooltip" title="Label herunterladen"><i class="fas fa-download"></i></a>';
|
||||
}
|
||||
// Email button
|
||||
if ($shipment->dhl_shipment_no && $shipment->canSendTrackingEmail()) {
|
||||
$emailTitle = $shipment->wasTrackingEmailSent()
|
||||
? 'Tracking-E-Mail erneut senden (gesendet: ' . $shipment->tracking_email_sent_at->format('d.m.Y H:i') . ')'
|
||||
? 'Tracking-E-Mail erneut senden (gesendet: '.$shipment->tracking_email_sent_at->format('d.m.Y H:i').')'
|
||||
: 'Tracking-E-Mail senden';
|
||||
$emailClass = $shipment->wasTrackingEmailSent() ? 'btn-success' : 'btn-outline-info';
|
||||
$buttons .= '<button type="button" class="btn btn-sm ' . $emailClass . ' send-tracking-email-btn" data-shipment-id="' . $shipment->id . '" data-toggle="tooltip" title="' . $emailTitle . '"><i class="fas fa-envelope"></i></button>';
|
||||
$buttons .= '<button type="button" class="btn btn-sm '.$emailClass.' send-tracking-email-btn" data-shipment-id="'.$shipment->id.'" data-toggle="tooltip" title="'.$emailTitle.'"><i class="fas fa-envelope"></i></button>';
|
||||
}
|
||||
// Cancel button
|
||||
if ($shipment->canCancel()) {
|
||||
$buttons .= '<button type="button" class="btn btn-sm btn-outline-danger cancel-shipment-btn" data-shipment-id="' . $shipment->id . '" data-toggle="tooltip" title="Sendung stornieren"><i class="fas fa-ban"></i></button>';
|
||||
$buttons .= '<button type="button" class="btn btn-sm btn-outline-danger cancel-shipment-btn" data-shipment-id="'.$shipment->id.'" data-toggle="tooltip" title="Sendung stornieren"><i class="fas fa-ban"></i></button>';
|
||||
}
|
||||
// Return label button
|
||||
// Return label button (for outbound shipments without existing return)
|
||||
if ($shipment->type == 'outbound' && ! $shipment->returns()->count()) {
|
||||
$buttons .= '<button type="button" class="btn btn-sm btn-outline-info create-return-btn" data-shipment-id="' . $shipment->id . '" data-toggle="tooltip" title="Retourenlabel erstellen"><i class="fas fa-undo"></i></button>';
|
||||
$buttons .= '<button type="button" class="btn btn-sm btn-outline-info create-return-btn" data-shipment-id="'.$shipment->id.'" data-toggle="tooltip" title="Retourenlabel erstellen"><i class="fas fa-undo"></i></button>';
|
||||
}
|
||||
$buttons .= '</div>';
|
||||
|
||||
|
|
@ -268,7 +268,7 @@ class DhlShipmentController extends Controller
|
|||
if (! $validationResult['valid']) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validierungsfehler: ' . implode(', ', $validationResult['errors']),
|
||||
'message' => 'Validierungsfehler: '.implode(', ', $validationResult['errors']),
|
||||
], 422);
|
||||
}
|
||||
|
||||
|
|
@ -341,7 +341,7 @@ class DhlShipmentController extends Controller
|
|||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Fehler beim Erstellen der Sendung: ' . $e->getMessage(),
|
||||
'message' => 'Fehler beim Erstellen der Sendung: '.$e->getMessage(),
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
|
@ -351,7 +351,11 @@ class DhlShipmentController extends Controller
|
|||
*/
|
||||
public function show(DhlShipment $shipment): View
|
||||
{
|
||||
$shipment->load(['shoppingOrder.shopping_user', 'relatedShipment']);
|
||||
$shipment->load([
|
||||
'shoppingOrder.shopping_user',
|
||||
'relatedShipment',
|
||||
'trackingEvents' => fn ($q) => $q->orderBy('event_time', 'desc'),
|
||||
]);
|
||||
|
||||
return view('admin.dhl.show', compact('shipment'));
|
||||
}
|
||||
|
|
@ -394,7 +398,7 @@ class DhlShipmentController extends Controller
|
|||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Fehler beim Stornieren der Sendung: ' . $e->getMessage(),
|
||||
'message' => 'Fehler beim Stornieren der Sendung: '.$e->getMessage(),
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
|
@ -426,7 +430,7 @@ class DhlShipmentController extends Controller
|
|||
}
|
||||
|
||||
// Check DHL_USE_QUEUE configuration
|
||||
$settingController = new SettingController();
|
||||
$settingController = new SettingController;
|
||||
$dhlConfig = $settingController->getDhlConfig();
|
||||
$useQueue = $dhlConfig['use_queue'] ?? false;
|
||||
|
||||
|
|
@ -462,11 +466,59 @@ class DhlShipmentController extends Controller
|
|||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Fehler beim Erstellen des Retourenlabels: ' . $e->getMessage(),
|
||||
'message' => 'Fehler beim Erstellen des Retourenlabels: '.$e->getMessage(),
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get billing address for return label (used when original delivery was to Packstation)
|
||||
*/
|
||||
private function getBillingAddressForReturn($shippingUser, array $recipient): array
|
||||
{
|
||||
if (! $shippingUser) {
|
||||
Log::warning('[DHL Controller] No shipping user found, using recipient data', [
|
||||
'recipient' => $recipient,
|
||||
]);
|
||||
|
||||
// Fallback: use recipient data but without Packstation fields
|
||||
return [
|
||||
'name' => trim(($recipient['firstname'] ?? '').' '.($recipient['lastname'] ?? '')),
|
||||
'name2' => $recipient['company'] ?? '',
|
||||
'street' => 'Adresse fehlt',
|
||||
'houseNumber' => '',
|
||||
'postalCode' => $recipient['postalCode'] ?? '',
|
||||
'city' => $recipient['city'] ?? '',
|
||||
'country' => $recipient['country'] ?? 'DEU',
|
||||
'email' => $recipient['email'] ?? '',
|
||||
'phone' => $recipient['phone'] ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
// Parse billing address to extract street and house number
|
||||
$billingAddress = trim($shippingUser->billing_address ?? '');
|
||||
$street = $billingAddress;
|
||||
$houseNumber = '';
|
||||
|
||||
// Try to extract house number from address
|
||||
if (preg_match('/^(.+?)\s+(\d+[a-zA-Z]?[-\/\d]*)$/u', $billingAddress, $matches)) {
|
||||
$street = trim($matches[1]);
|
||||
$houseNumber = trim($matches[2]);
|
||||
}
|
||||
|
||||
return [
|
||||
'name' => trim(($shippingUser->billing_firstname ?? '').' '.($shippingUser->billing_lastname ?? '')),
|
||||
'name2' => $shippingUser->billing_company ?? '',
|
||||
'street' => $street,
|
||||
'houseNumber' => $houseNumber,
|
||||
'postalCode' => $shippingUser->billing_zipcode ?? '',
|
||||
'city' => $shippingUser->billing_city ?? '',
|
||||
'country' => $shippingUser->billing_country?->code ?? 'DEU',
|
||||
'email' => $shippingUser->billing_email ?? '',
|
||||
'phone' => $shippingUser->billing_phone ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create return label synchronously
|
||||
*/
|
||||
|
|
@ -478,7 +530,7 @@ class DhlShipmentController extends Controller
|
|||
]);
|
||||
|
||||
// Get DHL configuration
|
||||
$settingController = new SettingController();
|
||||
$settingController = new SettingController;
|
||||
$dhlConfig = $settingController->getDhlConfig();
|
||||
|
||||
// Initialize DHL client
|
||||
|
|
@ -496,15 +548,22 @@ class DhlShipmentController extends Controller
|
|||
$order = $shipment->shoppingOrder;
|
||||
$recipient = $shipment->recipient ?? [];
|
||||
|
||||
$returnData = [
|
||||
'order_id' => $order->id,
|
||||
'original_shipment_id' => $shipment->id,
|
||||
'weight_kg' => $shipment->weight_kg,
|
||||
'label_format' => $shipment->label_format ?? 'PDF',
|
||||
// Check if this is a Packstation delivery - use billing address as return sender
|
||||
$hasPostNumber = ! empty($recipient['postnumber'] ?? $recipient['postNumber'] ?? '');
|
||||
|
||||
// Shipper: Customer sends back to us (swap addresses)
|
||||
'shipper' => [
|
||||
'name' => trim(($recipient['firstname'] ?? '') . ' ' . ($recipient['lastname'] ?? '')),
|
||||
if ($hasPostNumber) {
|
||||
Log::info('[DHL Controller] Packstation detected - using billing address for return sender', [
|
||||
'shipment_id' => $shipment->id,
|
||||
'order_id' => $order->id,
|
||||
]);
|
||||
|
||||
// Load billing address from order
|
||||
$shippingUser = $order->shopping_user;
|
||||
$shipperAddress = $this->getBillingAddressForReturn($shippingUser, $recipient);
|
||||
} else {
|
||||
// Use original recipient address (normal delivery)
|
||||
$shipperAddress = [
|
||||
'name' => trim(($recipient['firstname'] ?? '').' '.($recipient['lastname'] ?? '')),
|
||||
'name2' => $recipient['company'] ?? '',
|
||||
'street' => $recipient['street'] ?? '',
|
||||
'houseNumber' => $recipient['houseNumber'] ?? '',
|
||||
|
|
@ -513,7 +572,17 @@ class DhlShipmentController extends Controller
|
|||
'country' => $recipient['country'] ?? 'DEU',
|
||||
'email' => $recipient['email'] ?? '',
|
||||
'phone' => $recipient['phone'] ?? '',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
$returnData = [
|
||||
'order_id' => $order->id,
|
||||
'original_shipment_id' => $shipment->id,
|
||||
'weight_kg' => $shipment->weight_kg,
|
||||
'label_format' => $shipment->label_format ?? 'PDF',
|
||||
|
||||
// Shipper: Customer sends back to us (using billing address for Packstation)
|
||||
'shipper' => $shipperAddress,
|
||||
|
||||
// Consignee: Our warehouse
|
||||
'consignee' => [
|
||||
|
|
@ -551,7 +620,7 @@ class DhlShipmentController extends Controller
|
|||
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => 'Fehler beim Erstellen des Retourenlabels: ' . $e->getMessage(),
|
||||
'message' => 'Fehler beim Erstellen des Retourenlabels: '.$e->getMessage(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -589,7 +658,7 @@ class DhlShipmentController extends Controller
|
|||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Fehler beim Aktualisieren der Tracking-Informationen: ' . $e->getMessage(),
|
||||
'message' => 'Fehler beim Aktualisieren der Tracking-Informationen: '.$e->getMessage(),
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
|
@ -679,7 +748,7 @@ class DhlShipmentController extends Controller
|
|||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Fehler beim Senden der Tracking-E-Mail: ' . $e->getMessage(),
|
||||
'message' => 'Fehler beim Senden der Tracking-E-Mail: '.$e->getMessage(),
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
|
@ -721,7 +790,7 @@ class DhlShipmentController extends Controller
|
|||
private function generateLabelFilename(DhlShipment $shipment): string
|
||||
{
|
||||
// Load order with customer data
|
||||
$customerName = $shipment->firstname . '_' . $shipment->lastname;
|
||||
$customerName = $shipment->firstname.'_'.$shipment->lastname;
|
||||
if ($shipment->company) {
|
||||
$customerName = $shipment->company;
|
||||
}
|
||||
|
|
@ -747,7 +816,7 @@ class DhlShipmentController extends Controller
|
|||
|
||||
// Ensure filename is not too long (max 255 characters)
|
||||
if (strlen($filename) > 255) {
|
||||
$maxCustomerLength = 255 - strlen('DHL--' . $shipmentNumber . '-' . $date . '.pdf');
|
||||
$maxCustomerLength = 255 - strlen('DHL--'.$shipmentNumber.'-'.$date.'.pdf');
|
||||
$customerName = substr($customerName, 0, max(10, $maxCustomerLength));
|
||||
$filename = sprintf(
|
||||
'DHL-%s-%s-%s.pdf',
|
||||
|
|
@ -802,7 +871,7 @@ class DhlShipmentController extends Controller
|
|||
if ($trackingResult['success']) {
|
||||
$processed++;
|
||||
} else {
|
||||
$errors[] = "Sendung #{$shipment->id}: " . $trackingResult['message'];
|
||||
$errors[] = "Sendung #{$shipment->id}: ".$trackingResult['message'];
|
||||
}
|
||||
} else {
|
||||
$errors[] = "Sendung #{$shipment->id} hat keine DHL-Sendungsnummer.";
|
||||
|
|
@ -823,7 +892,7 @@ class DhlShipmentController extends Controller
|
|||
break;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$errors[] = "Fehler bei Sendung {$shipmentId}: " . $e->getMessage();
|
||||
$errors[] = "Fehler bei Sendung {$shipmentId}: ".$e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -852,7 +921,7 @@ class DhlShipmentController extends Controller
|
|||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Fehler bei der Stapelverarbeitung: ' . $e->getMessage(),
|
||||
'message' => 'Fehler bei der Stapelverarbeitung: '.$e->getMessage(),
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
|
@ -917,8 +986,8 @@ class DhlShipmentController extends Controller
|
|||
{
|
||||
try {
|
||||
$zip = new ZipArchive;
|
||||
$zipFilename = 'dhl_labels_' . date('Y-m-d_H-i-s') . '.zip';
|
||||
$zipPath = storage_path('app/temp/' . $zipFilename);
|
||||
$zipFilename = 'dhl_labels_'.date('Y-m-d_H-i-s').'.zip';
|
||||
$zipPath = storage_path('app/temp/'.$zipFilename);
|
||||
|
||||
// Ensure temp directory exists
|
||||
if (! file_exists(storage_path('app/temp'))) {
|
||||
|
|
@ -963,7 +1032,7 @@ class DhlShipmentController extends Controller
|
|||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Fehler beim Erstellen der ZIP-Datei: ' . $e->getMessage(),
|
||||
'message' => 'Fehler beim Erstellen der ZIP-Datei: '.$e->getMessage(),
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue