73 lines
2.2 KiB
PHP
73 lines
2.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Validator\Constraints;
|
|
|
|
use App\BusProNet\Constants;
|
|
use App\Form\Model\BookingDto;
|
|
use Symfony\Component\Validator\Constraint;
|
|
use Symfony\Component\Validator\ConstraintValidator;
|
|
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
|
|
|
/**
|
|
* Validates room selection business rules for bookings.
|
|
*
|
|
* Enforces that at least one room is selected and that baby rooms (BABY code)
|
|
* are only booked in combination with regular rooms, not standalone.
|
|
*/
|
|
class RoomSelectionValidator extends ConstraintValidator
|
|
{
|
|
public function validate(mixed $value, Constraint $constraint): void
|
|
{
|
|
if (!$constraint instanceof RoomSelection) {
|
|
throw new UnexpectedTypeException($constraint, RoomSelection::class);
|
|
}
|
|
|
|
if (!$value instanceof BookingDto) {
|
|
throw new UnexpectedTypeException($value, BookingDto::class);
|
|
}
|
|
|
|
$selectedRooms = $value->getSelectedRooms();
|
|
|
|
// Check that at least one room is selected
|
|
if (0 === count($selectedRooms)) {
|
|
$this->context->buildViolation($constraint->noRoomSelectedMessage)
|
|
->addViolation();
|
|
|
|
return;
|
|
}
|
|
|
|
// Check that not only Baby rooms are selected
|
|
$this->assertNotOnlyBabyRooms($value, $constraint);
|
|
}
|
|
|
|
private function assertNotOnlyBabyRooms(BookingDto $bookingDto, RoomSelection $constraint): void
|
|
{
|
|
$availableRooms = $bookingDto->travel->getAvailableRooms();
|
|
$selectedRooms = $bookingDto->getSelectedRooms();
|
|
|
|
$hasRegularRoom = false;
|
|
$hasBabyRoom = false;
|
|
|
|
foreach ($selectedRooms as $roomSelection) {
|
|
$room = $availableRooms[$roomSelection->id] ?? null;
|
|
|
|
if (null === $room) {
|
|
continue;
|
|
}
|
|
|
|
if (Constants::BABY_ROOM_CODE === $room->code) {
|
|
$hasBabyRoom = true;
|
|
} else {
|
|
$hasRegularRoom = true;
|
|
}
|
|
}
|
|
|
|
if ($hasBabyRoom && false === $hasRegularRoom) {
|
|
$this->context->buildViolation($constraint->onlyBabyRoomsMessage)
|
|
->addViolation();
|
|
}
|
|
}
|
|
}
|