$insurances Available insurances to filter * @param ParticipantDto $participant The participant to match insurances for * @param BookingDto $booking The booking context for additional criteria * * @return array Filtered array of eligible insurances */ public function getEligibleInsurances(array $insurances, ParticipantDto $participant, BookingDto $booking): array { // Calculate travel price for this participant $travelPrice = $this->calculateTravelPrice($booking, $participant->index); // Delegate to InsuranceEligibilityService return $this->insuranceEligibilityService->getEligibleInsurances( $insurances, $participant, $booking, $travelPrice ); } /** * Auto-reassigns an insurance to the same type with appropriate price tier. * * This method is used when a participant's individual price changes and their * current insurance is no longer eligible. It finds the same insurance type * (subType + familyInsurance) with the correct price tier. * * @param array $availableInsurances All available insurances * @param Insurance $currentInsurance The currently selected insurance * @param ParticipantDto $participant The participant to reassign for * @param BookingDto $booking The booking context * * @return Insurance|null The reassigned insurance or null if no suitable match found */ public function reassignInsuranceForPriceChange(array $availableInsurances, Insurance $currentInsurance, ParticipantDto $participant, BookingDto $booking): ?Insurance { // Group insurances of the same type $sameTypeInsurances = $this->insuranceTypeFilterService->filterByType($availableInsurances, $currentInsurance); // Get eligible insurances for this participant $eligibleInsurances = $this->getEligibleInsurances($sameTypeInsurances, $participant, $booking); // Return the first eligible insurance (they should all be equivalent for the same type) return !empty($eligibleInsurances) ? array_values($eligibleInsurances)[0] : null; } /** * Batch-assigns insurances of the same type to all participants based on individual pricing. * * FUTURE FEATURE: This method will be used when implementing the "applicant assigns * insurance to all participants" feature. The applicant's selection will be propagated * to all participants with automatic price tier adjustment based on individual prices. * * This method takes the applicant's insurance selection and assigns the same insurance type * (subType + familyInsurance) to all participants, but selects the appropriate price tier * based on each participant's individual travel price. * * @param array $availableInsurances All available insurances * @param Insurance $selectedInsurance The insurance selected by the applicant * @param BookingDto $booking The booking with all participants * * @return array Array indexed by participant index with assigned insurances * * @internal Reserved for future feature implementation */ public function batchAssignInsuranceToParticipants(array $availableInsurances, Insurance $selectedInsurance, BookingDto $booking): array { $assignments = []; // Group insurances of the same type $sameTypeInsurances = $this->insuranceTypeFilterService->filterByType($availableInsurances, $selectedInsurance); // Assign appropriate insurance to each participant foreach ($booking->getParticipants() as $index => $participant) { $eligibleInsurances = $this->getEligibleInsurances($sameTypeInsurances, $participant, $booking); $assignments[$index] = !empty($eligibleInsurances) ? array_values($eligibleInsurances)[0] : null; } return $assignments; } /** * Calculates the total travel price for a participant, excluding insurance prices. * * This method calculates the travel price used for insurance eligibility filtering. * It excludes insurance prices to prevent circular dependency where insurance selection * affects travel price which then affects insurance eligibility. * * @param BookingDto $booking The booking to calculate price for * @param int $participantIndex The participant index to calculate for * * @return float The total travel price for the participant excluding insurance */ private function calculateTravelPrice(BookingDto $booking, int $participantIndex): float { // Use the price calculator to get the participant's individual price excluding insurance return $this->priceCalculatorService->calculateIndividualParticipantPriceExcludingInsurance($booking, $participantIndex); } }