From 96c53cc17369a531cf6651d11680cedd85fce386 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Wed, 24 Sep 2025 12:58:42 +0200 Subject: [PATCH] feat: functionality to determine family status of a booking --- src/Form/Model/BookingCreateDto.php | 34 +++++++++++++++++++++++++++++ src/Form/Model/ParticipantDto.php | 19 ++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/src/Form/Model/BookingCreateDto.php b/src/Form/Model/BookingCreateDto.php index 3a5265a..771dfd1 100644 --- a/src/Form/Model/BookingCreateDto.php +++ b/src/Form/Model/BookingCreateDto.php @@ -51,6 +51,40 @@ class BookingCreateDto implements BookingDtoInterface return $this->participants[$index] ?? null; } + /** + * Determines if this is a family booking based on participant age distribution. + * + * A family booking is defined as: + * - 1-2 participants aged 18 or older (adults) + * - At least 1 participant aged 20 or younger (young people/children) + * + * @return bool True if this qualifies as a family booking + */ + public function isFamilyBooking(): bool + { + $adults = 0; // Count of participants >= 18 years + $youngPeople = 0; // Count of participants <= 20 years + + foreach ($this->participants as $participant) { + $age = $participant->getAge(); + + if (null === $age) { + continue; // Skip participants without birth date + } + + if ($age >= 18) { + ++$adults; + } + + if ($age <= 20) { + ++$youngPeople; + } + } + + // Check family booking criteria + return ($adults >= 1 && $adults <= 2) && ($youngPeople >= 1); + } + #[Assert\Callback(callback: 'validateRoomSelection', groups: ['booking_create_step_1'])] public function validateRoomSelection(ExecutionContextInterface $context): void { diff --git a/src/Form/Model/ParticipantDto.php b/src/Form/Model/ParticipantDto.php index f74cc15..dfb04c2 100644 --- a/src/Form/Model/ParticipantDto.php +++ b/src/Form/Model/ParticipantDto.php @@ -106,4 +106,23 @@ class ParticipantDto { return 'O' === $this->status; } + + /** + * Calculates the participant's current age in complete years. + * + * Uses the same logic as existing age evaluators in the system + * for consistency across age-related calculations. + * + * @return int|null The calculated age in complete years, or null if no birth date + */ + public function getAge(): ?int + { + if (null === $this->dateOfBirth) { + return null; + } + + $today = new \DateTimeImmutable(); + + return $this->dateOfBirth->diff($today)->y; + } }