diff --git a/docs/PROJECT_OVERVIEW.md b/docs/PROJECT_OVERVIEW.md index 0ab8510..a6bd1e2 100644 --- a/docs/PROJECT_OVERVIEW.md +++ b/docs/PROJECT_OVERVIEW.md @@ -59,7 +59,7 @@ - `BookingFingerprintService` - Dirty state detection for edit mode - `TravelDataService` - API integration and caching - `ParticipantCardDataService` - Card display data -- `InsuranceMatchingService` - Insurance eligibility and auto-reassignment +- `InsuranceService` - Consolidated insurance operations (eligibility, type filtering, reassignment) with request-scoped caching - `RoomAssignmentService` - Automatic room assignment ## Critical Patterns @@ -191,7 +191,7 @@ Critical for correct pricing and auto-reassignment: ### Bulk Insurance Booking - Applicant enables bulk → applies to all participants - `BulkInsuranceBookingCondition` hides dependent participant insurance fields -- Uses `InsuranceMatchingService::batchAssignInsuranceToParticipants()` for price tier matching +- Uses `InsuranceService::batchAssignInsuranceToParticipants()` for price tier matching ## Data Flow @@ -241,7 +241,7 @@ Critical for correct pricing and auto-reassignment: - **Insurance IDs**: Always use strings, not integers (e.g., `'100'` not `100`) - **Room properties**: Use `$label` property, not `$name` - **Participant names**: Index 0 expects "Anmelder:in", others expect "Teilnehmer:in N" (1-based) -- **Mock dependencies**: Ensure all constructor dependencies have mocks (especially new ones like `InsuranceLoader`, `InsuranceTypeFilterService`) +- **Mock dependencies**: Ensure all constructor dependencies have mocks. Note: `InsuranceService` is stateless with no dependencies (no mocking required) - **Insurance mutability**: In edit mode, insurances are always readonly (API limitation) ## File Locations diff --git a/src/Service/BookingPriceCalculatorService.php b/src/Service/BookingPriceCalculatorService.php index 2c60d90..f6c1f6f 100644 --- a/src/Service/BookingPriceCalculatorService.php +++ b/src/Service/BookingPriceCalculatorService.php @@ -315,8 +315,10 @@ class BookingPriceCalculatorService * * @return float The total price for the specified participant excluding insurance and non-calculated services */ - public function calculateIndividualParticipantPriceExcludingInsurance(BookingDto $bookingDto, int $participantIndex): float - { + public function calculateIndividualParticipantPriceExcludingInsurance( + BookingDto $bookingDto, + int $participantIndex, + ): float { $participant = $bookingDto->getParticipant($participantIndex); if (null === $participant) { return 0.0; @@ -591,8 +593,12 @@ class BookingPriceCalculatorService * * @return float The total service cost for this participant */ - private function calculateParticipantServiceTotal(ParticipantDto $participant, bool $includeInsurance = true, ?BookingDto $bookingDto = null, bool $onlyInsuranceCalculationServices = false): float - { + private function calculateParticipantServiceTotal( + ParticipantDto $participant, + bool $includeInsurance = true, + ?BookingDto $bookingDto = null, + bool $onlyInsuranceCalculationServices = false, + ): float { $serviceTotal = 0.0; // Single service selections diff --git a/src/Service/InsuranceService.php b/src/Service/InsuranceService.php index bf820ed..3bbbe5d 100644 --- a/src/Service/InsuranceService.php +++ b/src/Service/InsuranceService.php @@ -55,8 +55,12 @@ class InsuranceService * * @return array Filtered array of eligible insurances, sorted by price */ - public function getEligibleInsurances(array $insurances, ParticipantDto $participant, BookingDto $booking, float $travelPrice): array - { + public function getEligibleInsurances( + array $insurances, + ParticipantDto $participant, + BookingDto $booking, + float $travelPrice + ): array { $travelStartDate = $booking->travel->dateFrom; $travelEndDate = $booking->travel->dateTo; @@ -99,8 +103,13 @@ class InsuranceService * * @return Insurance|null The reassigned insurance or null if no suitable match found */ - public function reassignInsuranceForPriceChange(array $availableInsurances, Insurance $currentInsurance, ParticipantDto $participant, BookingDto $booking, float $travelPrice): ?Insurance - { + public function reassignInsuranceForPriceChange( + array $availableInsurances, + Insurance $currentInsurance, + ParticipantDto $participant, + BookingDto $booking, + float $travelPrice + ): ?Insurance { // Group insurances of the same type $sameTypeInsurances = $this->filterByType($availableInsurances, $currentInsurance); @@ -125,8 +134,12 @@ class InsuranceService * * @return array Array indexed by participant index with assigned insurances */ - public function batchAssignInsuranceToParticipants(array $availableInsurances, Insurance $selectedInsurance, BookingDto $booking, array $participantPrices): array - { + public function batchAssignInsuranceToParticipants( + array $availableInsurances, + Insurance $selectedInsurance, + BookingDto $booking, + array $participantPrices + ): array { $assignments = []; // Group insurances of the same type @@ -264,8 +277,11 @@ class InsuranceService return true; } - private function checkAgeConstraints(Insurance $insurance, ParticipantDto $participant, \DateTimeImmutable $travelStartDate): bool - { + private function checkAgeConstraints( + Insurance $insurance, + ParticipantDto $participant, + \DateTimeImmutable $travelStartDate + ): bool { $participantAge = $participant->getAge($travelStartDate); // If no birth date is provided, skip age constraints (field will be hidden via field state conditions) @@ -286,8 +302,11 @@ class InsuranceService return true; } - private function checkTravelDateConstraints(Insurance $insurance, \DateTimeImmutable $travelStartDate, \DateTimeImmutable $travelEndDate): bool - { + private function checkTravelDateConstraints( + Insurance $insurance, + \DateTimeImmutable $travelStartDate, + \DateTimeImmutable $travelEndDate + ): bool { // Check travel start date if (null !== $insurance->travelDateFrom && $travelStartDate < $insurance->travelDateFrom) { return false;