fix: validation error indication on cards

This commit is contained in:
Björn Fromme
2026-03-16 11:59:11 +01:00
parent 89979d6ce4
commit 03ac430be4
6 changed files with 208 additions and 17 deletions
+64 -2
View File
@@ -5,6 +5,8 @@ declare(strict_types=1);
namespace App\Service;
use App\Form\Model\BookingDto;
use App\Form\Model\ParticipantEditDto;
use Symfony\Component\Validator\Validator\ValidatorInterface;
/**
* Extracts card display data for participants in card-based booking flows.
@@ -16,13 +18,14 @@ class ParticipantCardDataService
{
public function __construct(
private readonly BookingPriceCalculatorService $priceCalculator,
private readonly ValidatorInterface $validator,
) {
}
/**
* Get card data for a single participant.
*
* @return array{name: string, roomName: string, price: string}
* @return array{name: string, roomName: string, price: string, isCanceled: bool}
*/
public function getCardData(BookingDto $bookingDto, int $index): array
{
@@ -41,17 +44,21 @@ class ParticipantCardDataService
// Calculate and format individual price
$price = $this->getFormattedPrice($bookingDto, $index);
// Check if participant is canceled
$isCanceled = $participant->isCanceled();
return [
'name' => $name,
'roomName' => $roomName,
'price' => $price,
'isCanceled' => $isCanceled,
];
}
/**
* Get card data for all participants.
*
* @return array<int, array{name: string, roomName: string, price: string}>
* @return array<int, array{name: string, roomName: string, price: string, isCanceled: bool}>
*/
public function getAllCardsData(BookingDto $bookingDto): array
{
@@ -121,4 +128,59 @@ class ParticipantCardDataService
return number_format($price, 2, ',', '.').' €';
}
/**
* Get card data for a single participant with validation state.
*
* @return array{name: string, roomName: string, price: string, isCanceled: bool, isValid: bool, errorMessages: array<string>}
*/
public function getCardDataWithValidation(BookingDto $bookingDto, int $index, array $validationGroups): array
{
$participant = $bookingDto->participants[$index] ?? null;
if (null === $participant) {
throw new \InvalidArgumentException(sprintf('Participant at index %d does not exist', $index));
}
// Get basic card data
$cardData = $this->getCardData($bookingDto, $index);
// Wrap participant for validation
$wrapper = new ParticipantEditDto(
participant: $participant,
bookingContext: $bookingDto,
);
// Validate the wrapper DTO
$violations = $this->validator->validate($wrapper, null, $validationGroups);
// Extract validation state
$isValid = 0 === count($violations);
$errorMessages = [];
foreach ($violations as $violation) {
$errorMessages[] = $violation->getMessage();
}
return array_merge($cardData, [
'isValid' => $isValid,
'errorMessages' => $errorMessages,
]);
}
/**
* Get card data for all participants with validation state.
*
* @return array<int, array{name: string, roomName: string, price: string, isCanceled: bool, isValid: bool, errorMessages: array<string>}>
*/
public function getAllCardsDataWithValidation(BookingDto $bookingDto, array $validationGroups): array
{
$cardsData = [];
foreach ($bookingDto->participants as $index => $participant) {
$cardsData[$index] = $this->getCardDataWithValidation($bookingDto, $index, $validationGroups);
}
return $cardsData;
}
}