86 lines
2.4 KiB
PHP
86 lines
2.4 KiB
PHP
<?php
|
|
|
|
namespace App\Domains\Event\Actions\SetEventAddons;
|
|
|
|
use App\ValueObjects\Amount;
|
|
use Illuminate\Support\Str;
|
|
|
|
class SetEventAddonsCommand
|
|
{
|
|
public function __construct(private SetEventAddonsRequest $request)
|
|
{
|
|
}
|
|
|
|
public function execute(): SetEventAddonsResponse
|
|
{
|
|
$response = new SetEventAddonsResponse();
|
|
|
|
$this->request->event->addons = $this->normalize($this->request->addons);
|
|
$this->request->event->save();
|
|
|
|
$response->success = true;
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* Normalisiert die rohe Addon-Definition: trimmt Titel/Beschreibung, parst den Preis (≥ 0), erzwingt den
|
|
* Titel als Pflichtfeld und generiert stabile Keys (Bestandsschutz für bereits gespeicherte Buchungen).
|
|
*
|
|
* @param array<int, array<string, mixed>> $addons
|
|
* @return array<int, array{key: string, title: string, description: string, price: float, flat: bool}>
|
|
*/
|
|
private function normalize(array $addons): array
|
|
{
|
|
$normalized = [];
|
|
$usedKeys = [];
|
|
|
|
foreach ($addons as $addon) {
|
|
$title = trim((string)($addon['title'] ?? ''));
|
|
if ($title === '') {
|
|
continue;
|
|
}
|
|
|
|
$price = Amount::fromString((string)($addon['price'] ?? '0'))->getAmount();
|
|
if ($price < 0) {
|
|
$price = 0.0;
|
|
}
|
|
|
|
$key = $this->uniqueSlug((string)($addon['key'] ?? ''), $title, $usedKeys);
|
|
$usedKeys[] = $key;
|
|
|
|
$normalized[] = [
|
|
'key' => $key,
|
|
'title' => $title,
|
|
'description' => trim((string)($addon['description'] ?? '')),
|
|
'price' => round($price, 2),
|
|
'flat' => (bool)($addon['flat'] ?? false),
|
|
];
|
|
}
|
|
|
|
return $normalized;
|
|
}
|
|
|
|
/**
|
|
* Liefert einen eindeutigen Slug: bevorzugt den bestehenden Wert, sonst aus dem Titel abgeleitet;
|
|
* Kollisionen werden durchnummeriert.
|
|
*
|
|
* @param array<int, string> $used
|
|
*/
|
|
private function uniqueSlug(string $existing, string $title, array $used): string
|
|
{
|
|
$base = $existing !== '' ? $existing : Str::slug($title);
|
|
if ($base === '') {
|
|
$base = 'addon';
|
|
}
|
|
|
|
$candidate = $base;
|
|
$suffix = 2;
|
|
while (in_array($candidate, $used, true)) {
|
|
$candidate = $base . '-' . $suffix;
|
|
$suffix++;
|
|
}
|
|
|
|
return $candidate;
|
|
}
|
|
}
|