$submittedData The submitted participant form data * @param string $mode The booking mode (BookingDto::MODE_CREATE or MODE_EDIT) * @param int $participantIndex The index of the participant being processed * * @return bool Always returns true for parking selection fields */ public function shouldProcess(array $submittedData, string $mode, int $participantIndex): bool { return true; // Always process for state changes } public function processField(array $submittedData, BookingDto $bookingDto, int $participantIndex): void { $participant = $this->getParticipant($bookingDto, $participantIndex); if (null === $participant) { return; } // Check if parking is applicable (outbound transportation is PKW AND participant is 18+) if (false === $this->isParkingApplicable($participant)) { $participant->parking = false; $participant->parkingService = null; return; } $parkingSelected = $this->getFieldValue($submittedData, $this->getFieldName()); $isParkingSelected = $this->normalizeCheckboxValue($parkingSelected); // Store boolean value for backward compatibility $participant->parking = $isParkingSelected; // Store parking service object for pricing calculation if (true === $isParkingSelected) { $participant->parkingService = $this->findParkingService($bookingDto, $participantIndex); } else { $participant->parkingService = null; } } /** * Checks if parking is applicable based on outbound transportation and age. * * Parking is only applicable when: * 1. Outbound transportation is PKW (arriving by car at destination) * 2. Participant is at least 18 years old (minimum driving age in Germany) * * @param ParticipantDto $participant The participant DTO * * @return bool True if parking is applicable, false otherwise */ private function isParkingApplicable(ParticipantDto $participant): bool { // Must have PKW outbound transportation if (DirectionMapper::SUBTYPE_CAR_API !== $participant->transportationOutbound?->subType) { return false; } // Must be at least minimum driving age $age = $participant->getAge(); if (null === $age || $age < self::MINIMUM_DRIVING_AGE) { return false; } return true; } /** * Finds the parking service from available services. * * Gets the first (and typically only) parking service for pricing calculation. * Returns null if no parking services are available. * * @param BookingDto $bookingDto The booking DTO containing travel data * @param int $participantIndex The participant index for booked services lookup * * @return Service|null The parking service object, or null if not found */ private function findParkingService(BookingDto $bookingDto, int $participantIndex): ?Service { // Get available parking services (includes booked parking in edit mode) $parkingServices = $this->getAvailableServicesWithBooked( $bookingDto, $participantIndex, Constants::TOKEN_PARKING ); if (empty($parkingServices)) { return null; } // Return the first parking service (there's typically only one parking type) return reset($parkingServices); } }