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,89 @@
<?php
namespace App\Services;
use App\Models\ShoppingOrder;
use InvalidArgumentException;
class DhlShipmentWeightCalculator
{
public const DEFAULT_WEIGHT_KG = 1.0;
public const DEFAULT_MAX_WEIGHT_KG = 31.5;
public const PRODUCT_MAX_WEIGHTS_KG = [
'V01PAK' => 31.5,
'V53PAK' => 31.5,
'V62KP' => 1.0,
];
public function calculate(ShoppingOrder $order): float
{
$this->loadOrderItems($order);
$baseWeightGrams = max((int) ($order->weight ?? 0), 0);
$compensationWeightGrams = $this->calculateCompensationWeightGrams($order);
$totalWeightGrams = $baseWeightGrams + $compensationWeightGrams;
if ($totalWeightGrams <= 0) {
return self::DEFAULT_WEIGHT_KG;
}
return $this->roundWeightKg($totalWeightGrams / 1000);
}
public function getMaxWeightKgForProduct(?string $productCode): float
{
$productCode = strtoupper(trim((string) $productCode));
return self::PRODUCT_MAX_WEIGHTS_KG[$productCode] ?? self::DEFAULT_MAX_WEIGHT_KG;
}
public function assertWithinProductLimit(float $weightKg, ?string $productCode): void
{
$maxWeightKg = $this->getMaxWeightKgForProduct($productCode);
if ($weightKg > $maxWeightKg) {
throw new InvalidArgumentException(sprintf(
'Gewicht %.3f kg ueberschreitet das DHL-Maximalgewicht fuer %s (%.1f kg).',
$weightKg,
$productCode ?: 'das gewaehlte Produkt',
$maxWeightKg
));
}
}
private function calculateCompensationWeightGrams(ShoppingOrder $order): int
{
$items = $order->shopping_order_items ?? collect();
$weightGrams = 0;
foreach ($items as $item) {
if ((int) ($item->comp ?? 0) <= 0) {
continue;
}
$productWeight = (int) ($item->product?->weight ?? 0);
if ($productWeight <= 0) {
continue;
}
$quantity = max((int) ($item->qty ?? 1), 1);
$weightGrams += $productWeight * $quantity;
}
return $weightGrams;
}
private function roundWeightKg(float $weightKg): float
{
return round(max($weightKg, 0.1), 3);
}
private function loadOrderItems(ShoppingOrder $order): void
{
if ($order->exists && ! $order->relationLoaded('shopping_order_items')) {
$order->loadMissing('shopping_order_items.product');
}
}
}