wip: insurance booking phase 5

This commit is contained in:
Björn Fromme
2026-03-16 11:59:10 +01:00
parent c67fa18ad3
commit 8af7f0e797
5 changed files with 452 additions and 36 deletions
@@ -0,0 +1,166 @@
<?php
declare(strict_types=1);
namespace App\Form\Service;
use App\BusProNet\Model\Insurance;
use App\Form\Model\BookingDtoInterface;
use App\Form\Service\Abstract\AbstractParticipantFieldHandler;
use App\Service\InsuranceMatchingService;
/**
* Handles processing of the insurance field for booking participants.
*
* This handler manages insurance selections for individual participants in the booking
* creation process. It processes the insurance field from form submissions,
* validates the selection against participant eligibility criteria, and updates
* the participant DTO with the valid insurance selection.
*
* The insurance field depends on dateOfBirth for age-based eligibility calculations
* and uses the InsuranceMatchingService to ensure only eligible insurances can be selected.
*
* Dependencies: dateOfBirth (for age evaluation and insurance eligibility)
*/
class ParticipantInsuranceFieldHandler extends AbstractParticipantFieldHandler
{
public function __construct(
private readonly InsuranceMatchingService $insuranceMatchingService,
) {
}
/**
* Returns the form field name this handler processes.
*
* @return string The field name 'insurance'
*/
public function getFieldName(): string
{
return 'insurance';
}
/**
* Returns the field dependencies for proper processing order.
*
* This handler depends on dateOfBirth for age evaluation and insurance eligibility.
*
* @return string[] Array containing 'dateOfBirth' dependency
*/
public function getDependencies(): array
{
return ['dateOfBirth'];
}
/**
* Determines if this handler should process the field based on submitted data.
*
* For insurance selection fields, we always need to process to handle cases
* where the selection is cleared (field not present in data). This ensures
* the participant DTO is updated with null when no insurance is selected.
*
* @param array<string, mixed> $submittedData The submitted participant form data
* @param int $participantIndex The index of the participant being processed
*
* @return bool Always returns true for insurance selection fields
*/
public function shouldProcess(array $submittedData, int $participantIndex): bool
{
return true; // Always process to handle deselection cases
}
/**
* Processes the insurance field for a specific participant.
*
* This method extracts the insurance selection from submitted form data,
* validates the selection against the participant's eligibility criteria,
* and updates the participant DTO with the valid selection. If the insurance
* is no longer appropriate for the participant, it is automatically cleared.
*
* @param array<string, mixed> $submittedData The submitted participant form data
* @param BookingDtoInterface $bookingDto The booking DTO to update (create or edit)
* @param int $participantIndex The index of the participant being processed
*/
public function processField(array $submittedData, BookingDtoInterface $bookingDto, int $participantIndex): void
{
$participant = $bookingDto->getParticipant($participantIndex);
if (null === $participant) {
return;
}
$insuranceId = $submittedData['insurance'] ?? null;
// Clear insurance if no selection
if (null === $insuranceId || '' === $insuranceId) {
$participant->insurance = null;
return;
}
// Find the selected insurance from available travel insurances
$availableInsurances = $bookingDto->travel->insurances ?? [];
$selectedInsurance = $this->findInsuranceById($availableInsurances, $insuranceId);
if (null === $selectedInsurance) {
$participant->insurance = null;
return;
}
// Validate insurance eligibility for this participant
$eligibleInsurances = $this->insuranceMatchingService->getEligibleInsurances(
[$selectedInsurance],
$participant,
$bookingDto
);
// Set insurance only if it's eligible for this participant
$participant->insurance = !empty($eligibleInsurances) ? $selectedInsurance : null;
}
/**
* Returns field state modifications that should be applied after processing.
*
* Currently no field state modifications are needed for insurance selection.
*
* @param array<string, mixed> $submittedData The submitted participant form data
* @param BookingDtoInterface $bookingDto The booking DTO (potentially modified by processing)
* @param int $participantIndex The participant index being processed
*
* @return array<string, array<string, mixed>> Empty array - no field state modifications
*/
public function getFieldStateModifications(array $submittedData, BookingDtoInterface $bookingDto, int $participantIndex): array
{
return [];
}
/**
* Returns field names whose state is affected by this handler's processing.
*
* Currently no other fields are affected by insurance selection.
*
* @return string[] Empty array - no other fields are affected
*/
public function getAffectedFieldNames(): array
{
return [];
}
/**
* Finds an insurance by ID from the available insurances array.
*
* @param array<Insurance> $insurances Array of available insurances
* @param string|int $insuranceId The insurance ID to find
*
* @return Insurance|null The found insurance or null if not found
*/
private function findInsuranceById(array $insurances, string|int $insuranceId): ?Insurance
{
foreach ($insurances as $insurance) {
if ($insurance->id === $insuranceId || (string) $insurance->id === (string) $insuranceId) {
return $insurance;
}
}
return null;
}
}