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

@ -0,0 +1,130 @@
<?php
use Acme\Dhl\Exceptions\DhlAddressValidationException;
use Acme\Dhl\Services\ShippingService;
use Acme\Dhl\Support\DhlClient;
function makeDhlPhaseOneShippingService(): ShippingService
{
return new ShippingService(new DhlClient('https://api-sandbox.dhl.com', null, null, null));
}
function validDhlPhaseOneOrderData(string $productCode, string $countryCode = 'DE'): array
{
return [
'order_id' => 123456,
'weight_kg' => 0.5,
'product_code' => $productCode,
'label_format' => 'PDF',
'shipper' => [
'name' => 'mivita care gmbh',
'street' => 'Leinfeld',
'houseNumber' => '2',
'postalCode' => '87755',
'city' => 'Kirchhaslach',
'country' => 'DE',
],
'consignee' => [
'name' => 'Max Mustermann',
'street' => 'Hauptstrasse',
'houseNumber' => '5',
'postalCode' => '10115',
'city' => 'Berlin',
'country' => $countryCode,
],
'reference' => 'ORDER-123456',
];
}
it('accepts DHL Kleinpaket as a product code', function () {
$service = makeDhlPhaseOneShippingService();
$method = new ReflectionMethod($service, 'validateOrderData');
$method->setAccessible(true);
$validated = $method->invoke($service, validDhlPhaseOneOrderData('V62KP'));
expect($validated['product_code'])->toBe('V62KP');
});
it('builds an international DHL parcel payload for Austria', function () {
config([
'dhl.account_numbers.V53PAK' => '63144073555301',
'dhl.legacy.sandbox' => false,
'dhl.legacy.test_mode' => false,
]);
$service = makeDhlPhaseOneShippingService();
$method = new ReflectionMethod($service, 'buildShipmentPayload');
$method->setAccessible(true);
$payload = $method->invoke($service, validDhlPhaseOneOrderData('V53PAK', 'AT'));
expect($payload['shipments'][0]['product'])->toBe('V53PAK')
->and($payload['shipments'][0]['billingNumber'])->toBe('63144073555301')
->and($payload['shipments'][0]['consignee']['country'])->toBe('AUT');
});
it('rejects unsupported countries instead of falling back to Germany', function () {
$service = makeDhlPhaseOneShippingService();
$method = new ReflectionMethod($service, 'buildShipmentPayload');
$method->setAccessible(true);
$method->invoke($service, validDhlPhaseOneOrderData('V53PAK', 'FR'));
})->throws(InvalidArgumentException::class);
it('rejects legacy Warenpost for new labels', function () {
$service = makeDhlPhaseOneShippingService();
$method = new ReflectionMethod($service, 'validateOrderData');
$method->setAccessible(true);
$method->invoke($service, validDhlPhaseOneOrderData('V62WP'));
})->throws(InvalidArgumentException::class);
it('builds a DHL Kleinpaket payload', function () {
config([
'dhl.account_numbers.V62KP' => '63144073556201',
'dhl.legacy.sandbox' => false,
'dhl.legacy.test_mode' => false,
]);
$service = makeDhlPhaseOneShippingService();
$method = new ReflectionMethod($service, 'buildShipmentPayload');
$method->setAccessible(true);
$payload = $method->invoke($service, validDhlPhaseOneOrderData('V62KP'));
expect($payload['shipments'][0]['product'])->toBe('V62KP')
->and($payload['shipments'][0]['billingNumber'])->toBe('63144073556201')
->and($payload['shipments'][0]['refNo'])->toBe('ORDER-123456');
});
it('uses mustEncode only for German consignee addresses', function () {
$service = makeDhlPhaseOneShippingService();
$method = new ReflectionMethod($service, 'shouldUseMustEncode');
$method->setAccessible(true);
expect($method->invoke($service, validDhlPhaseOneOrderData('V01PAK', 'DE') + ['print_only_if_codeable' => true]))->toBeTrue()
->and($method->invoke($service, validDhlPhaseOneOrderData('V53PAK', 'AT') + ['print_only_if_codeable' => true]))->toBeFalse()
->and($method->invoke($service, validDhlPhaseOneOrderData('V01PAK', 'DE') + ['print_only_if_codeable' => false]))->toBeFalse();
});
it('turns non-codeable DHL responses into address validation errors', function () {
$service = makeDhlPhaseOneShippingService();
$method = new ReflectionMethod($service, 'assertSuccessfulShipmentResponse');
$method->setAccessible(true);
$method->invoke($service, [
'status' => [
'statusCode' => 200,
],
'items' => [[
'sstatus' => [
'statusCode' => 400,
'detail' => 'Consignee address is not encodable.',
],
'validationMessages' => [[
'validationMessage' => 'Address is not encodable.',
]],
]],
], true);
})->throws(DhlAddressValidationException::class, 'DHL kann diese Adresse nicht leitcodieren.');