Notification messages for user feedback */ public array $notifications = []; public function __construct() { $this->address = new Address(); } public static function fromPersonalData(PersonalData $personalData): static { $instance = new static(); $instance->status = $personalData->status; $instance->addressId = $personalData->addressId; $instance->personId = $personalData->personId; $instance->mutable = $personalData->mutable; $instance->firstName = $personalData->firstName; $instance->lastName = $personalData->name; $instance->gender = $personalData->gender; $instance->nationality = $personalData->nationality; $instance->email = $personalData->communication?->email; $instance->mobile = $personalData->communication?->mobile; $instance->dateOfBirth = $personalData->dateOfBirth; $instance->height = $personalData->height; $instance->weight = $personalData->weight; $instance->shoeSize = $personalData->shoeSize; return $instance; } public function isApplicant(): bool { return 0 === $this->index; } public function isCanceled(): bool { return 'S' === $this->status; } public function isOption(): bool { return 'O' === $this->status; } /** * Calculates the participant's age in complete years. * * Uses the same logic as existing age evaluators in the system * for consistency across age-related calculations. * * @param \DateTimeImmutable|null $referenceDate The date to calculate age at (defaults to current date) * * @return int|null The calculated age in complete years, or null if no birth date */ public function getAge(?\DateTimeImmutable $referenceDate = null): ?int { if (null === $this->dateOfBirth) { return null; } $referenceDate = $referenceDate ?? new \DateTimeImmutable(); return $this->dateOfBirth->diff($referenceDate)->y; } /** * Checks if the participant has selected an insurance. * * @return bool True if an insurance is selected */ public function hasInsurance(): bool { return null !== $this->insurance; } /** * Gets the insurance label for display purposes. * * @return string|null The insurance label or null if no insurance selected */ public function getInsuranceLabel(): ?string { return $this->insurance?->label; } /** * Gets the insurance price for pricing calculations. * * @return float The insurance price (0.0 if no insurance selected) */ public function getInsurancePrice(): float { return $this->insurance?->price ?? 0.0; } /** * Adds a notification message for user feedback. * * @param string $type The notification type (info, warning, success) * @param string $message The notification message */ public function addNotification(string $type, string $message): void { $this->notifications[] = [ 'type' => $type, 'message' => $message, ]; } }