feat: refactor participant card DTOs and labels
This commit is contained in:
@@ -5,6 +5,8 @@ declare(strict_types=1);
|
||||
namespace App\Service;
|
||||
|
||||
use App\Form\Model\BookingDto;
|
||||
use App\Form\Model\ParticipantCardDataDto;
|
||||
use App\Form\Model\ParticipantCardPriceDto;
|
||||
use App\Form\Model\ParticipantEditDto;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
|
||||
@@ -25,9 +27,9 @@ class ParticipantCardDataService
|
||||
/**
|
||||
* Get card data for a single participant.
|
||||
*
|
||||
* @return array{name: string, email: string, roomName: string, price: string, isCanceled: bool}
|
||||
* @return ParticipantCardDataDto
|
||||
*/
|
||||
public function getCardData(BookingDto $bookingDto, int $index): array
|
||||
public function getCardData(BookingDto $bookingDto, int $index): ParticipantCardDataDto
|
||||
{
|
||||
$participant = $bookingDto->participants[$index] ?? null;
|
||||
|
||||
@@ -44,31 +46,31 @@ class ParticipantCardDataService
|
||||
// Extract room name
|
||||
$roomName = $this->getRoomName($bookingDto, $participant);
|
||||
|
||||
// Calculate and format individual price
|
||||
$price = $this->getFormattedPrice($bookingDto, $index);
|
||||
// Calculate pricing state for display
|
||||
$priceData = $this->getPriceData($bookingDto, $index);
|
||||
|
||||
// Check if participant is canceled
|
||||
$isCanceled = $participant->isCanceled();
|
||||
|
||||
return [
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'roomName' => $roomName,
|
||||
'price' => $price,
|
||||
'isCanceled' => $isCanceled,
|
||||
];
|
||||
return new ParticipantCardDataDto(
|
||||
name: $name,
|
||||
email: $email,
|
||||
roomName: $roomName,
|
||||
price: $priceData,
|
||||
isCanceled: $isCanceled,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get card data for all participants.
|
||||
*
|
||||
* @return array<int, array{name: string, email: string, roomName: string, price: string, isCanceled: bool}>
|
||||
* @return array<int, ParticipantCardDataDto>
|
||||
*/
|
||||
public function getAllCardsData(BookingDto $bookingDto): array
|
||||
{
|
||||
$cardsData = [];
|
||||
|
||||
foreach ($bookingDto->participants as $index => $participant) {
|
||||
foreach ($bookingDto->participants as $index => $_participant) {
|
||||
$cardsData[$index] = $this->getCardData($bookingDto, $index);
|
||||
}
|
||||
|
||||
@@ -118,12 +120,14 @@ class ParticipantCardDataService
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate and format individual participant price.
|
||||
* Calculate individual participant price display state.
|
||||
*
|
||||
* Returns a dash (-) when the price is zero and no room is assigned,
|
||||
* Returns a dash marker when the price is zero and no room is assigned,
|
||||
* indicating incomplete configuration rather than a zero-cost booking.
|
||||
*
|
||||
* @return ParticipantCardPriceDto
|
||||
*/
|
||||
private function getFormattedPrice(BookingDto $bookingDto, int $index): string
|
||||
private function getPriceData(BookingDto $bookingDto, int $index): ParticipantCardPriceDto
|
||||
{
|
||||
// Check if canceled (only possible in edit mode when booking property is set)
|
||||
$isCanceled = ($bookingDto->booking?->participantsStatus[$index] ?? null) === 'S';
|
||||
@@ -131,7 +135,7 @@ class ParticipantCardDataService
|
||||
if (true === $isCanceled) {
|
||||
// Calculate surcharge total for canceled participant
|
||||
if (null === $bookingDto->booking) {
|
||||
return '-';
|
||||
return new ParticipantCardPriceDto(null, true);
|
||||
}
|
||||
|
||||
$surcharges = $bookingDto->booking->getSurchargesForParticipant($index);
|
||||
@@ -143,10 +147,10 @@ class ParticipantCardDataService
|
||||
|
||||
// Show nothing if no surcharges, otherwise show "x,xx € Stornokosten"
|
||||
if (0.0 === $surchargeTotal) {
|
||||
return '-';
|
||||
return new ParticipantCardPriceDto(null, true);
|
||||
}
|
||||
|
||||
return number_format($surchargeTotal, 2, ',', '.').' € Stornokosten';
|
||||
return new ParticipantCardPriceDto($surchargeTotal, false);
|
||||
}
|
||||
|
||||
// For active participants: existing price calculation logic
|
||||
@@ -157,18 +161,18 @@ class ParticipantCardDataService
|
||||
// Display dash when price is zero and no room assigned (incomplete configuration)
|
||||
$participant = $bookingDto->participants[$index] ?? null;
|
||||
if (0.0 === $price && (null === $participant || null === $participant->assignedRoomId)) {
|
||||
return '-';
|
||||
return new ParticipantCardPriceDto(null, true);
|
||||
}
|
||||
|
||||
return number_format($price, 2, ',', '.').' €';
|
||||
return new ParticipantCardPriceDto($price, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get card data for a single participant with validation state.
|
||||
*
|
||||
* @return array{name: string, email: string, roomName: string, price: string, isCanceled: bool, isValid: bool, errorMessages: array<string>}
|
||||
* @return ParticipantCardDataDto
|
||||
*/
|
||||
public function getCardDataWithValidation(BookingDto $bookingDto, int $index): array
|
||||
public function getCardDataWithValidation(BookingDto $bookingDto, int $index): ParticipantCardDataDto
|
||||
{
|
||||
$participant = $bookingDto->participants[$index] ?? null;
|
||||
|
||||
@@ -199,22 +203,19 @@ class ParticipantCardDataService
|
||||
$errorMessages[] = $violation->getMessage();
|
||||
}
|
||||
|
||||
return array_merge($cardData, [
|
||||
'isValid' => $isValid,
|
||||
'errorMessages' => $errorMessages,
|
||||
]);
|
||||
return $cardData->withValidation($isValid, $errorMessages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get card data for all participants with validation state.
|
||||
*
|
||||
* @return array<int, array{name: string, email: string, roomName: string, price: string, isCanceled: bool, isValid: bool, errorMessages: array<string>}>
|
||||
* @return array<int, ParticipantCardDataDto>
|
||||
*/
|
||||
public function getAllCardsDataWithValidation(BookingDto $bookingDto): array
|
||||
{
|
||||
$cardsData = [];
|
||||
|
||||
foreach ($bookingDto->participants as $index => $participant) {
|
||||
foreach ($bookingDto->participants as $index => $_participant) {
|
||||
$cardsData[$index] = $this->getCardDataWithValidation($bookingDto, $index);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\BusProNet\Model\Service;
|
||||
|
||||
/**
|
||||
* Formats service labels for form and UI display.
|
||||
*/
|
||||
final class ServiceLabelFormatter
|
||||
{
|
||||
public function formatServiceLabel(Service $service): string
|
||||
{
|
||||
$label = $service->label ?? '';
|
||||
|
||||
if (null === $service->price) {
|
||||
return $label;
|
||||
}
|
||||
|
||||
if (0.0 === $service->price) {
|
||||
return sprintf('%s (inkl.)', $label);
|
||||
}
|
||||
|
||||
if ($service->price < 0) {
|
||||
return sprintf('%s (-%s€ Rabatt)', $label, number_format(abs($service->price), 2, ',', '.'));
|
||||
}
|
||||
|
||||
return sprintf('%s (€%s)', $label, number_format($service->price, 2, ',', '.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, Service> $services
|
||||
*/
|
||||
public function formatServiceLabelForServices(string $fallbackLabel, array $services): string
|
||||
{
|
||||
$service = reset($services);
|
||||
if (false === $service) {
|
||||
return $fallbackLabel;
|
||||
}
|
||||
|
||||
if (!($service instanceof Service)) {
|
||||
return $fallbackLabel;
|
||||
}
|
||||
|
||||
return $this->formatServiceLabel($service);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user