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
199
app/Services/DhlProductResolver.php
Normal file
199
app/Services/DhlProductResolver.php
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Setting;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class DhlProductResolver
|
||||
{
|
||||
public const DOMESTIC_COUNTRY = 'DE';
|
||||
|
||||
public const DOMESTIC_PRODUCT_CODES = ['V01PAK', 'V62KP'];
|
||||
|
||||
public const INTERNATIONAL_PRODUCT_CODE = 'V53PAK';
|
||||
|
||||
public const DEFAULT_INTERNATIONAL_COUNTRIES = ['AT', 'ES'];
|
||||
|
||||
public const DHL_COUNTRY_CODES = [
|
||||
'DE' => 'DEU',
|
||||
'AT' => 'AUT',
|
||||
'ES' => 'ESP',
|
||||
'CH' => 'CHE',
|
||||
'US' => 'USA',
|
||||
'GB' => 'GBR',
|
||||
'FR' => 'FRA',
|
||||
'IT' => 'ITA',
|
||||
'NL' => 'NLD',
|
||||
'BE' => 'BEL',
|
||||
'PL' => 'POL',
|
||||
'CZ' => 'CZE',
|
||||
'DK' => 'DNK',
|
||||
'SE' => 'SWE',
|
||||
'NO' => 'NOR',
|
||||
];
|
||||
|
||||
/**
|
||||
* @return array{country_code: string, dhl_country_code: string, product_code: string}
|
||||
*/
|
||||
public function resolveForShipment(string $destinationCountryCode, ?string $requestedProductCode = null, ?string $defaultProductCode = null): array
|
||||
{
|
||||
$countryCode = $this->normalizeCountryCode($destinationCountryCode);
|
||||
$productCode = $this->resolveProductCode($countryCode, $requestedProductCode, $defaultProductCode);
|
||||
|
||||
return [
|
||||
'country_code' => $countryCode,
|
||||
'dhl_country_code' => $this->toDhlCountryCode($countryCode),
|
||||
'product_code' => $productCode,
|
||||
];
|
||||
}
|
||||
|
||||
public function resolveProductCode(string $destinationCountryCode, ?string $requestedProductCode = null, ?string $defaultProductCode = null): string
|
||||
{
|
||||
$countryCode = $this->normalizeCountryCode($destinationCountryCode);
|
||||
$hasRequestedProduct = $requestedProductCode !== null && trim($requestedProductCode) !== '';
|
||||
$productCode = $this->normalizeProductCode($requestedProductCode ?: $defaultProductCode);
|
||||
|
||||
if ($countryCode === self::DOMESTIC_COUNTRY) {
|
||||
$productCode = $productCode ?: 'V01PAK';
|
||||
|
||||
if (! in_array($productCode, self::DOMESTIC_PRODUCT_CODES, true)) {
|
||||
throw new InvalidArgumentException("Produkt {$productCode} ist fuer DHL-Versand nach Deutschland nicht erlaubt.");
|
||||
}
|
||||
|
||||
return $productCode;
|
||||
}
|
||||
|
||||
if (! in_array($countryCode, $this->getSupportedInternationalCountries(), true)) {
|
||||
throw new InvalidArgumentException("DHL-Versand in das Zielland {$countryCode} ist aktuell nicht freigegeben.");
|
||||
}
|
||||
|
||||
if (! $productCode || (! $hasRequestedProduct && in_array($productCode, self::DOMESTIC_PRODUCT_CODES, true))) {
|
||||
return self::INTERNATIONAL_PRODUCT_CODE;
|
||||
}
|
||||
|
||||
if ($productCode !== self::INTERNATIONAL_PRODUCT_CODE) {
|
||||
throw new InvalidArgumentException("Produkt {$productCode} ist fuer DHL-Versand in das Zielland {$countryCode} nicht erlaubt.");
|
||||
}
|
||||
|
||||
return $productCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getProductSuggestionsByCountry(): array
|
||||
{
|
||||
return array_fill_keys($this->getSupportedInternationalCountries(), self::INTERNATIONAL_PRODUCT_CODE)
|
||||
+ [self::DOMESTIC_COUNTRY => 'V01PAK'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getAllowedProductCodesForCountry(string $destinationCountryCode): array
|
||||
{
|
||||
$countryCode = $this->normalizeCountryCode($destinationCountryCode);
|
||||
|
||||
if ($countryCode === self::DOMESTIC_COUNTRY) {
|
||||
return self::DOMESTIC_PRODUCT_CODES;
|
||||
}
|
||||
|
||||
if (in_array($countryCode, $this->getSupportedInternationalCountries(), true)) {
|
||||
return [self::INTERNATIONAL_PRODUCT_CODE];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public function toDhlCountryCode(string $countryCode): string
|
||||
{
|
||||
$countryCode = $this->normalizeCountryCode($countryCode);
|
||||
|
||||
return self::DHL_COUNTRY_CODES[$countryCode];
|
||||
}
|
||||
|
||||
public function assertBillingNumber(string $productCode, ?string $billingNumber): string
|
||||
{
|
||||
if ($billingNumber === null || trim($billingNumber) === '') {
|
||||
throw new InvalidArgumentException("Keine DHL-Abrechnungsnummer fuer Produkt {$productCode} konfiguriert.");
|
||||
}
|
||||
|
||||
return $billingNumber;
|
||||
}
|
||||
|
||||
public function getProductScope(string $productCode): string
|
||||
{
|
||||
$productCode = $this->normalizeProductCode($productCode);
|
||||
|
||||
return $productCode === self::INTERNATIONAL_PRODUCT_CODE ? 'international' : 'national';
|
||||
}
|
||||
|
||||
public function getProductScopeLabel(string $productCode): string
|
||||
{
|
||||
return $this->getProductScope($productCode) === 'international'
|
||||
? 'DHL Paket International'
|
||||
: 'DHL Paket National';
|
||||
}
|
||||
|
||||
public function normalizeCountryCode(string $countryCode): string
|
||||
{
|
||||
$countryCode = strtoupper(trim($countryCode));
|
||||
|
||||
if ($countryCode === '') {
|
||||
throw new InvalidArgumentException('DHL-Zielland fehlt.');
|
||||
}
|
||||
|
||||
if (strlen($countryCode) === 3) {
|
||||
$countryCode = array_search($countryCode, self::DHL_COUNTRY_CODES, true) ?: $countryCode;
|
||||
}
|
||||
|
||||
if (! array_key_exists($countryCode, self::DHL_COUNTRY_CODES)) {
|
||||
throw new InvalidArgumentException("DHL-Laendercode {$countryCode} wird nicht unterstuetzt.");
|
||||
}
|
||||
|
||||
return $countryCode;
|
||||
}
|
||||
|
||||
public function normalizeProductCode(?string $productCode): ?string
|
||||
{
|
||||
if ($productCode === null || trim($productCode) === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return strtoupper(trim($productCode));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getSupportedInternationalCountries(): array
|
||||
{
|
||||
$useEnvPriority = config('dhl.config_source') === 'env';
|
||||
$configCountries = config('dhl.international_countries', self::DEFAULT_INTERNATIONAL_COUNTRIES);
|
||||
$countries = $configCountries;
|
||||
|
||||
if (! $useEnvPriority) {
|
||||
$countries = Setting::getContentBySlug('dhl_international_countries') ?: $configCountries;
|
||||
}
|
||||
|
||||
return self::normalizeCountryCodeList(is_array($countries) ? $countries : []);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public static function normalizeCountryCodeList(array $countryCodes): array
|
||||
{
|
||||
$countryCodes = array_map(
|
||||
static fn ($countryCode): string => strtoupper(trim((string) $countryCode)),
|
||||
$countryCodes
|
||||
);
|
||||
|
||||
return array_values(array_filter(array_unique($countryCodes), static function (string $countryCode): bool {
|
||||
return $countryCode !== ''
|
||||
&& $countryCode !== self::DOMESTIC_COUNTRY
|
||||
&& array_key_exists($countryCode, self::DHL_COUNTRY_CODES);
|
||||
}));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue