wip: insurance booking
This commit is contained in:
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace App\Form\Service;
|
||||
|
||||
use App\BusProNet\Model\Insurance;
|
||||
use App\Form\Model\BookingCreateDto;
|
||||
use App\Form\Model\BookingDtoInterface;
|
||||
use App\Form\Service\Abstract\AbstractParticipantFieldHandler;
|
||||
use App\Service\InsuranceMatchingService;
|
||||
@@ -13,19 +14,28 @@ 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.
|
||||
* creation process. It processes insurance field from form submissions, validates
|
||||
* selections against participant eligibility criteria, and provides automatic
|
||||
* reassignment when participant pricing changes.
|
||||
*
|
||||
* The insurance field depends on dateOfBirth for age-based eligibility calculations
|
||||
* and uses the InsuranceMatchingService to ensure only eligible insurances can be selected.
|
||||
* Key Features:
|
||||
* - Validates submitted insurance selections against eligibility criteria
|
||||
* - Automatically reassigns insurances when travel price changes make current selection invalid
|
||||
* - Preserves user intent by maintaining same insurance type (subType + familyInsurance)
|
||||
* - Uses InsuranceMatchingService for eligibility filtering and reassignment logic
|
||||
*
|
||||
* Auto-Reassignment Logic:
|
||||
* When a participant's individual travel price changes (e.g., by adding services),
|
||||
* their current insurance may no longer be eligible for the new price range.
|
||||
* Instead of clearing the selection, this handler automatically reassigns
|
||||
* to the same insurance type with the appropriate price tier.
|
||||
*
|
||||
* Dependencies: dateOfBirth (for age evaluation and insurance eligibility)
|
||||
*/
|
||||
class ParticipantInsuranceFieldHandler extends AbstractParticipantFieldHandler
|
||||
{
|
||||
public function __construct(
|
||||
private readonly InsuranceMatchingService $insuranceMatchingService,
|
||||
private readonly InsuranceMatchingService $insuranceMatchingService
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -71,10 +81,9 @@ class ParticipantInsuranceFieldHandler extends AbstractParticipantFieldHandler
|
||||
/**
|
||||
* 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.
|
||||
* This method handles both explicit insurance selection from form data and automatic
|
||||
* reassignment when the participant's travel price changes. It maintains the same
|
||||
* insurance type but adjusts to the appropriate price tier when needed.
|
||||
*
|
||||
* @param array<string, mixed> $submittedData The submitted participant form data
|
||||
* @param BookingDtoInterface $bookingDto The booking DTO to update (create or edit)
|
||||
@@ -83,38 +92,67 @@ class ParticipantInsuranceFieldHandler extends AbstractParticipantFieldHandler
|
||||
public function processField(array $submittedData, BookingDtoInterface $bookingDto, int $participantIndex): void
|
||||
{
|
||||
$participant = $bookingDto->getParticipant($participantIndex);
|
||||
if (null === $participant) {
|
||||
if (null === $participant || !$bookingDto instanceof BookingCreateDto) {
|
||||
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
|
||||
$selectedInsuranceId = $this->getFieldValue($submittedData, $this->getFieldName());
|
||||
$currentInsurance = $participant->insurance;
|
||||
$availableInsurances = $bookingDto->travel->insurances ?? [];
|
||||
$selectedInsurance = $this->findInsuranceById($availableInsurances, $insuranceId);
|
||||
|
||||
if (null === $selectedInsurance) {
|
||||
$participant->insurance = null;
|
||||
// Handle explicit insurance selection from form
|
||||
if (null !== $selectedInsuranceId) {
|
||||
$selectedInsurance = $this->findInsuranceById($availableInsurances, $selectedInsuranceId);
|
||||
|
||||
return;
|
||||
// Check if the selected insurance is still eligible for this participant
|
||||
if (null !== $selectedInsurance) {
|
||||
$eligibleInsurances = $this->insuranceMatchingService->getEligibleInsurances($availableInsurances, $participant, $bookingDto);
|
||||
$isSelectedInsuranceEligible = $this->isInsuranceInList($selectedInsurance, $eligibleInsurances);
|
||||
|
||||
if ($isSelectedInsuranceEligible) {
|
||||
// Insurance is still eligible - use it directly
|
||||
$participant->insurance = $selectedInsurance;
|
||||
return;
|
||||
} else {
|
||||
// Insurance is no longer eligible - try to reassign to same type with new price tier
|
||||
$reassignedInsurance = $this->insuranceMatchingService->reassignInsuranceForPriceChange(
|
||||
$availableInsurances,
|
||||
$selectedInsurance,
|
||||
$participant,
|
||||
$bookingDto
|
||||
);
|
||||
|
||||
$participant->insurance = $reassignedInsurance;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Insurance not found - clear selection
|
||||
$participant->insurance = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate insurance eligibility for this participant
|
||||
$eligibleInsurances = $this->insuranceMatchingService->getEligibleInsurances(
|
||||
[$selectedInsurance],
|
||||
$participant,
|
||||
$bookingDto
|
||||
);
|
||||
// Handle automatic reassignment if participant had an insurance but it's no longer eligible
|
||||
if (null !== $currentInsurance) {
|
||||
// Check if current insurance is still eligible
|
||||
$eligibleInsurances = $this->insuranceMatchingService->getEligibleInsurances($availableInsurances, $participant, $bookingDto);
|
||||
$isCurrentInsuranceStillEligible = $this->isInsuranceInList($currentInsurance, $eligibleInsurances);
|
||||
|
||||
// Set insurance only if it's eligible for this participant
|
||||
$participant->insurance = !empty($eligibleInsurances) ? $selectedInsurance : null;
|
||||
if (!$isCurrentInsuranceStillEligible) {
|
||||
// Try to reassign to same insurance type with appropriate price tier
|
||||
$reassignedInsurance = $this->insuranceMatchingService->reassignInsuranceForPriceChange(
|
||||
$availableInsurances,
|
||||
$currentInsurance,
|
||||
$participant,
|
||||
$bookingDto
|
||||
);
|
||||
|
||||
$participant->insurance = $reassignedInsurance; // null if no suitable match found
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// No insurance selected or reassignment needed - keep current state (may be null)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,4 +201,24 @@ class ParticipantInsuranceFieldHandler extends AbstractParticipantFieldHandler
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a specific insurance exists in a list of insurances.
|
||||
*
|
||||
* @param Insurance $targetInsurance The insurance to find
|
||||
* @param array<Insurance> $insuranceList The list to search in
|
||||
*
|
||||
* @return bool True if the insurance is found in the list
|
||||
*/
|
||||
private function isInsuranceInList(Insurance $targetInsurance, array $insuranceList): bool
|
||||
{
|
||||
foreach ($insuranceList as $insurance) {
|
||||
if ($insurance->id === $targetInsurance->id || (string) $insurance->id === (string) $targetInsurance->id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user