23-01-2026
This commit is contained in:
parent
a939cd51ef
commit
a8b395e20d
248 changed files with 29342 additions and 4805 deletions
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\Country;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Models\ShoppingOrder;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* DHL Modal Service
|
||||
*
|
||||
*
|
||||
* Service class that handles all business logic for the DHL shipment creation modal.
|
||||
* Validates order data, processes addresses, and prepares data for the view.
|
||||
*/
|
||||
|
|
@ -30,10 +30,11 @@ class DhlModalService
|
|||
|
||||
/**
|
||||
* Prepare modal data for DHL shipment creation
|
||||
*
|
||||
* @param mixed $id Order ID or 'new'
|
||||
* @param array $data Additional data from the request
|
||||
*
|
||||
* @param mixed $id Order ID or 'new'
|
||||
* @param array $data Additional data from the request
|
||||
* @return array Prepared data for the view
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function prepareModalData($id, array $data): array
|
||||
|
|
@ -47,19 +48,20 @@ class DhlModalService
|
|||
'errors' => [],
|
||||
'warnings' => [],
|
||||
'existingShipments' => [],
|
||||
'modalMode' => 'search' // 'search', 'create', 'info'
|
||||
'modalMode' => 'search', // 'search', 'create', 'info'
|
||||
];
|
||||
|
||||
// If no order ID or 'new', return empty data for order selection
|
||||
if (!$id || $id === 'new') {
|
||||
if (! $id || $id === 'new') {
|
||||
return $result;
|
||||
}
|
||||
|
||||
try {
|
||||
// Load and validate order
|
||||
$order = $this->loadOrder($id);
|
||||
if (!$order) {
|
||||
if (! $order) {
|
||||
$result['errors'][] = "Bestellung #{$id} wurde nicht gefunden.";
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
|
@ -73,11 +75,11 @@ class DhlModalService
|
|||
$forceCreate = isset($data['force_create']) && $data['force_create'];
|
||||
|
||||
// Determine modal mode based on existing shipments and force_create
|
||||
if (!empty($existingShipments) && !$forceCreate) {
|
||||
if (! empty($existingShipments) && ! $forceCreate) {
|
||||
$result['modalMode'] = 'info';
|
||||
Log::info('[DHL Modal] Order has existing shipments, showing info mode', [
|
||||
'order_id' => $order->id,
|
||||
'shipment_count' => count($existingShipments)
|
||||
'shipment_count' => count($existingShipments),
|
||||
]);
|
||||
} else {
|
||||
$result['modalMode'] = 'create';
|
||||
|
|
@ -90,23 +92,23 @@ class DhlModalService
|
|||
|
||||
// Validate address completeness
|
||||
$addressValidation = $this->validateAddress($result['shippingAddress']);
|
||||
if (!$addressValidation['valid']) {
|
||||
if (! $addressValidation['valid']) {
|
||||
$result['errors'] = array_merge($result['errors'], $addressValidation['errors']);
|
||||
}
|
||||
if (!empty($addressValidation['warnings'])) {
|
||||
if (! empty($addressValidation['warnings'])) {
|
||||
$result['warnings'] = array_merge($result['warnings'], $addressValidation['warnings']);
|
||||
}
|
||||
|
||||
Log::info('[DHL Modal] Prepared modal data for creation', [
|
||||
'order_id' => $order->id,
|
||||
'weight' => $result['orderWeight'],
|
||||
'address_valid' => empty($result['errors'])
|
||||
'address_valid' => empty($result['errors']),
|
||||
]);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Log::error('[DHL Modal] Error preparing modal data', [
|
||||
'order_id' => $id,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
$result['errors'][] = 'Fehler beim Laden der Bestelldaten: ' . $e->getMessage();
|
||||
|
|
@ -117,24 +119,20 @@ class DhlModalService
|
|||
|
||||
/**
|
||||
* Load order with required relationships
|
||||
*
|
||||
* @param mixed $id
|
||||
* @return ShoppingOrder|null
|
||||
*
|
||||
* @param mixed $id
|
||||
*/
|
||||
private function loadOrder($id): ?ShoppingOrder
|
||||
{
|
||||
return ShoppingOrder::with([
|
||||
'shopping_order_items',
|
||||
'shopping_user',
|
||||
'dhlShipments' // Include DHL shipments
|
||||
'dhlShipments', // Include DHL shipments
|
||||
])->find($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get existing DHL shipments for the order
|
||||
*
|
||||
* @param ShoppingOrder $order
|
||||
* @return array
|
||||
*/
|
||||
private function getExistingShipments(ShoppingOrder $order): array
|
||||
{
|
||||
|
|
@ -160,24 +158,23 @@ class DhlModalService
|
|||
'tracking_status_translated' => $shipment->tracking_status ? \Acme\Dhl\Models\DhlShipment::getStatusTranslationFor($shipment->tracking_status) : null,
|
||||
'last_tracked_at' => $shipment->last_tracked_at,
|
||||
'can_cancel' => $shipment->canCancel(),
|
||||
'is_delivered' => $shipment->isDelivered()
|
||||
'is_delivered' => $shipment->isDelivered(),
|
||||
'email' => $shipment->email, // E-Mail für Tracking-E-Mail Button
|
||||
'can_send_email' => $shipment->canSendTrackingEmail(),
|
||||
];
|
||||
})->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate order weight in kg
|
||||
*
|
||||
* @param ShoppingOrder $order
|
||||
* @return float
|
||||
*/
|
||||
private function calculateOrderWeight(ShoppingOrder $order): float
|
||||
{
|
||||
return $order->weight / 1000; //from grams to kg
|
||||
return $order->weight / 1000; // from grams to kg
|
||||
/*
|
||||
// Default fallback weight
|
||||
$defaultWeight = 1.0;
|
||||
|
||||
|
||||
if (!$order->shopping_order_items || $order->shopping_order_items->isEmpty()) {
|
||||
return $defaultWeight;
|
||||
}
|
||||
|
|
@ -209,20 +206,17 @@ class DhlModalService
|
|||
|
||||
/**
|
||||
* Process and parse shipping address from order
|
||||
*
|
||||
* @param ShoppingOrder $order
|
||||
* @return array
|
||||
*/
|
||||
private function processShippingAddress(ShoppingOrder $order): array
|
||||
{
|
||||
$shoppingUser = $order->shopping_user;
|
||||
|
||||
if (!$shoppingUser) {
|
||||
if (! $shoppingUser) {
|
||||
return $this->getEmptyAddress();
|
||||
}
|
||||
|
||||
// Determine if shipping address is different from billing
|
||||
$useShipping = !($shoppingUser->same_as_billing ?? true);
|
||||
$useShipping = ! ($shoppingUser->same_as_billing ?? true);
|
||||
|
||||
// Extract address data
|
||||
$addressData = [
|
||||
|
|
@ -237,6 +231,8 @@ class DhlModalService
|
|||
'phone' => $useShipping ? ($shoppingUser->shipping_phone ?? '') : ($shoppingUser->billing_phone ?? ''),
|
||||
'email' => $shoppingUser->billing_email ?? '',
|
||||
'houseNumber' => '',
|
||||
// DHL Postnummer für Packstation/Paketbox (nur bei Versandadresse)
|
||||
'postnumber' => $useShipping ? ($shoppingUser->shipping_postnumber ?? '') : '',
|
||||
];
|
||||
|
||||
// Parse and separate street name and number
|
||||
|
|
@ -247,14 +243,12 @@ class DhlModalService
|
|||
|
||||
/**
|
||||
* Parse street address and separate street name from house number
|
||||
*
|
||||
* @param array &$addressData
|
||||
*/
|
||||
private function parseStreetAddress(array &$addressData): void
|
||||
{
|
||||
$address = trim($addressData['address']);
|
||||
// If address_2 is empty and address contains both street and number
|
||||
if (!empty($address)) {
|
||||
if (! empty($address)) {
|
||||
// Try to separate street name and house number
|
||||
$patterns = [
|
||||
// Pattern 1: "Musterstraße 123" or "Musterstraße 123a"
|
||||
|
|
@ -262,7 +256,7 @@ class DhlModalService
|
|||
// Pattern 2: "Musterstraße 123-125" or "Musterstraße 123/125"
|
||||
'/^(.+?)\s+(\d+[-\/]\d+[a-zA-Z]?)$/u',
|
||||
// Pattern 3: "123 Musterstraße" (number first)
|
||||
'/^(\d+[a-zA-Z]?)\s+(.+)$/u'
|
||||
'/^(\d+[a-zA-Z]?)\s+(.+)$/u',
|
||||
];
|
||||
|
||||
foreach ($patterns as $index => $pattern) {
|
||||
|
|
@ -288,8 +282,7 @@ class DhlModalService
|
|||
|
||||
/**
|
||||
* Validate address completeness and format
|
||||
*
|
||||
* @param array $address
|
||||
*
|
||||
* @return array Validation result with 'valid', 'errors', and 'warnings' keys
|
||||
*/
|
||||
private function validateAddress(array $address): array
|
||||
|
|
@ -303,7 +296,7 @@ class DhlModalService
|
|||
'lastname' => 'Nachname',
|
||||
'address' => 'Straße',
|
||||
'zipcode' => 'Postleitzahl',
|
||||
'city' => 'Stadt'
|
||||
'city' => 'Stadt',
|
||||
];
|
||||
|
||||
foreach ($requiredFields as $field => $label) {
|
||||
|
|
@ -318,33 +311,31 @@ class DhlModalService
|
|||
}
|
||||
|
||||
// Street number validation
|
||||
if (!empty($address['address']) && empty($address['houseNumber'])) {
|
||||
if (! empty($address['address']) && empty($address['houseNumber'])) {
|
||||
$warnings[] = 'Hausnummer konnte nicht automatisch erkannt werden. Bitte prüfen Sie die Adressangaben.';
|
||||
}
|
||||
|
||||
// Postal code format validation for Germany
|
||||
if (!empty($address['zipcode']) && $address['country'] && $address['country']->code === 'DE') {
|
||||
if (!preg_match('/^\d{5}$/', $address['zipcode'])) {
|
||||
if (! empty($address['zipcode']) && $address['country'] && $address['country']->code === 'DE') {
|
||||
if (! preg_match('/^\d{5}$/', $address['zipcode'])) {
|
||||
$warnings[] = 'Deutsche Postleitzahl sollte 5 Ziffern haben.';
|
||||
}
|
||||
}
|
||||
|
||||
// Country validation
|
||||
if (!$address['country']) {
|
||||
if (! $address['country']) {
|
||||
$errors[] = 'Land konnte nicht ermittelt werden.';
|
||||
}
|
||||
|
||||
return [
|
||||
'valid' => empty($errors),
|
||||
'errors' => $errors,
|
||||
'warnings' => $warnings
|
||||
'warnings' => $warnings,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get empty address template
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getEmptyAddress(): array
|
||||
{
|
||||
|
|
@ -359,12 +350,13 @@ class DhlModalService
|
|||
'country' => null,
|
||||
'phone' => '',
|
||||
'email' => '',
|
||||
'postnumber' => '',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available countries for shipping
|
||||
*
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
private function getAvailableCountries()
|
||||
|
|
@ -374,13 +366,11 @@ class DhlModalService
|
|||
|
||||
/**
|
||||
* Get available DHL product codes from settings
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getAvailableProductCodes(): array
|
||||
{
|
||||
// Get DHL configuration with merged settings
|
||||
$settingController = new \App\Http\Controllers\SettingController();
|
||||
$settingController = new \App\Http\Controllers\SettingController;
|
||||
$dhlConfig = $settingController->getDhlConfig();
|
||||
|
||||
$productCodes = [];
|
||||
|
|
@ -388,19 +378,19 @@ class DhlModalService
|
|||
// Add products based on configured account numbers
|
||||
$accountNumbers = $dhlConfig['account_numbers'] ?? [];
|
||||
|
||||
if (!empty($accountNumbers['V01PAK'])) {
|
||||
if (! empty($accountNumbers['V01PAK'])) {
|
||||
$productCodes['V01PAK'] = 'DHL Paket National';
|
||||
}
|
||||
|
||||
if (!empty($accountNumbers['V53PAK'])) {
|
||||
if (! empty($accountNumbers['V53PAK'])) {
|
||||
$productCodes['V53PAK'] = 'DHL Paket International';
|
||||
}
|
||||
|
||||
if (!empty($accountNumbers['V62WP'])) {
|
||||
if (! empty($accountNumbers['V62WP'])) {
|
||||
$productCodes['V62WP'] = 'DHL Warenpost National';
|
||||
}
|
||||
|
||||
if (!empty($accountNumbers['V07PAK'])) {
|
||||
if (! empty($accountNumbers['V07PAK'])) {
|
||||
$productCodes['V07PAK'] = 'DHL Retoure Online';
|
||||
}
|
||||
|
||||
|
|
@ -409,7 +399,7 @@ class DhlModalService
|
|||
$productCodes = [
|
||||
'V01PAK' => 'DHL Paket National',
|
||||
'V53PAK' => 'DHL Paket International',
|
||||
'V62WP' => 'DHL Warenpost National'
|
||||
'V62WP' => 'DHL Warenpost National',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -418,8 +408,7 @@ class DhlModalService
|
|||
|
||||
/**
|
||||
* Validate shipment parameters before API call
|
||||
*
|
||||
* @param array $shipmentData
|
||||
*
|
||||
* @return array Validation result
|
||||
*/
|
||||
public function validateShipmentData(array $shipmentData): array
|
||||
|
|
@ -438,7 +427,7 @@ class DhlModalService
|
|||
// Product code validation
|
||||
$productCode = $shipmentData['product_code'] ?? '';
|
||||
$availableProducts = array_keys($this->getAvailableProductCodes());
|
||||
if (!in_array($productCode, $availableProducts)) {
|
||||
if (! in_array($productCode, $availableProducts)) {
|
||||
$errors[] = 'Ungültiger Produktcode ausgewählt.';
|
||||
}
|
||||
|
||||
|
|
@ -450,7 +439,7 @@ class DhlModalService
|
|||
'shipping_houseNumber' => 'Hausnummer',
|
||||
'shipping_zipcode' => 'Postleitzahl',
|
||||
'shipping_city' => 'Stadt',
|
||||
'shipping_country_id' => 'Land'
|
||||
'shipping_country_id' => 'Land',
|
||||
];
|
||||
|
||||
foreach ($requiredAddressFields as $field => $label) {
|
||||
|
|
@ -462,20 +451,17 @@ class DhlModalService
|
|||
return [
|
||||
'valid' => empty($errors),
|
||||
'errors' => $errors,
|
||||
'warnings' => $warnings
|
||||
'warnings' => $warnings,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare address data for DHL API
|
||||
*
|
||||
* @param array $formData
|
||||
* @return array
|
||||
*/
|
||||
public function prepareAddressForApi(array $formData): array
|
||||
{
|
||||
$country = null;
|
||||
if (!empty($formData['shipping_country_id'])) {
|
||||
if (! empty($formData['shipping_country_id'])) {
|
||||
$country = Country::find($formData['shipping_country_id']);
|
||||
}
|
||||
|
||||
|
|
@ -491,7 +477,8 @@ class DhlModalService
|
|||
'country_id' => $country?->id,
|
||||
'country' => $country, // Store country object for DhlDataHelper
|
||||
'phone' => trim($formData['shipping_phone'] ?? ''),
|
||||
'email' => trim($formData['shipping_email'] ?? '') // Add email if available
|
||||
'email' => trim($formData['shipping_email'] ?? ''), // Add email if available
|
||||
'postnumber' => trim($formData['shipping_postnumber'] ?? ''), // DHL Postnummer für Packstation/Paketbox
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue