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
89
app/Services/DhlShipmentWeightCalculator.php
Normal file
89
app/Services/DhlShipmentWeightCalculator.php
Normal 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');
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue