feat: bulk insurance booking by applicant
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Form\Service;
|
||||
|
||||
use App\Form\Model\BookingCreateDto;
|
||||
use App\Form\Model\BookingDtoInterface;
|
||||
use App\Form\Service\Abstract\AbstractParticipantFieldHandler;
|
||||
use App\Service\InsuranceMatchingService;
|
||||
|
||||
/**
|
||||
* Handles bulk insurance booking for the applicant (first participant).
|
||||
*
|
||||
* When the applicant enables bulk insurance booking, their selected insurance type
|
||||
* (subType + familyInsurance) is automatically assigned to all participants with
|
||||
* automatic price tier adjustment based on each participant's individual travel price.
|
||||
*
|
||||
* This handler processes the bulkInsuranceBooking checkbox state and triggers
|
||||
* insurance assignment to dependent participants when enabled.
|
||||
*
|
||||
* Dependencies: insurance (applicant must have insurance selected before enabling bulk)
|
||||
*/
|
||||
class ParticipantBulkInsuranceFieldHandler extends AbstractParticipantFieldHandler
|
||||
{
|
||||
public function __construct(
|
||||
private readonly InsuranceMatchingService $insuranceMatchingService,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getFieldName(): string
|
||||
{
|
||||
return 'bulkInsuranceBooking';
|
||||
}
|
||||
|
||||
public function getDependencies(): array
|
||||
{
|
||||
// Depends on insurance field to ensure insurance is selected before bulk assignment
|
||||
return ['insurance'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this handler should process the field.
|
||||
*
|
||||
* Only process for the applicant (index 0). Dependent participants don't have
|
||||
* the bulkInsuranceBooking checkbox - their insurance is controlled by the handler.
|
||||
*
|
||||
* @param array<string, mixed> $submittedData The submitted participant form data
|
||||
* @param int $participantIndex The index of the participant being processed
|
||||
*
|
||||
* @return bool True if this is the applicant, false otherwise
|
||||
*/
|
||||
public function shouldProcess(array $submittedData, int $participantIndex): bool
|
||||
{
|
||||
return 0 === $participantIndex; // Only process for applicant
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the bulk insurance booking checkbox for the applicant.
|
||||
*
|
||||
* When bulk insurance is enabled and applicant has insurance selected,
|
||||
* assigns the same insurance type to all participants based on their
|
||||
* individual pricing and eligibility criteria.
|
||||
*
|
||||
* @param array<string, mixed> $submittedData The submitted participant form data
|
||||
* @param BookingDtoInterface $bookingDto The booking DTO to update
|
||||
* @param int $participantIndex The index of the participant (must be 0)
|
||||
*/
|
||||
public function processField(array $submittedData, BookingDtoInterface $bookingDto, int $participantIndex): void
|
||||
{
|
||||
$participant = $this->getParticipant($bookingDto, $participantIndex);
|
||||
if (null === $participant || !$bookingDto instanceof BookingCreateDto) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get checkbox value from submitted data
|
||||
$bulkInsuranceBooking = $this->getFieldValue($submittedData, $this->getFieldName());
|
||||
$isBulkEnabled = (bool) $bulkInsuranceBooking;
|
||||
|
||||
// Store checkbox state
|
||||
$participant->bulkInsuranceBooking = $isBulkEnabled;
|
||||
|
||||
// If bulk insurance is enabled and applicant has insurance, assign to all participants
|
||||
if (true === $isBulkEnabled && null !== $participant->insurance) {
|
||||
$this->applyBulkInsuranceToAllParticipants($bookingDto, $participant->insurance);
|
||||
}
|
||||
|
||||
// If bulk insurance is disabled, clear dependent participants' insurances
|
||||
if (false === $isBulkEnabled) {
|
||||
$this->clearDependentParticipantsInsurance($bookingDto);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the applicant's insurance type to all participants with automatic price tier adjustment.
|
||||
*
|
||||
* Uses InsuranceMatchingService to find the appropriate price tier for each participant
|
||||
* based on their individual travel price and eligibility criteria.
|
||||
*
|
||||
* @param BookingCreateDto $bookingDto The booking DTO with all participants
|
||||
* @param object $applicantInsurance The insurance selected by the applicant
|
||||
*/
|
||||
private function applyBulkInsuranceToAllParticipants(BookingCreateDto $bookingDto, object $applicantInsurance): void
|
||||
{
|
||||
$availableInsurances = $bookingDto->travel->insurances ?? [];
|
||||
|
||||
// Get insurance assignments for all participants
|
||||
$assignments = $this->insuranceMatchingService->batchAssignInsuranceToParticipants(
|
||||
$availableInsurances,
|
||||
$applicantInsurance,
|
||||
$bookingDto
|
||||
);
|
||||
|
||||
// Apply assignments to participants (skip applicant index 0, they keep their selection)
|
||||
foreach ($assignments as $index => $insurance) {
|
||||
if (0 === $index) {
|
||||
continue; // Skip applicant
|
||||
}
|
||||
|
||||
$participant = $bookingDto->getParticipant($index);
|
||||
if (null !== $participant) {
|
||||
$participant->insurance = $insurance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears insurance selections for dependent participants when bulk booking is disabled.
|
||||
*
|
||||
* @param BookingCreateDto $bookingDto The booking DTO with all participants
|
||||
*/
|
||||
private function clearDependentParticipantsInsurance(BookingCreateDto $bookingDto): void
|
||||
{
|
||||
foreach ($bookingDto->getParticipants() as $index => $participant) {
|
||||
if (0 === $index) {
|
||||
continue; // Skip applicant
|
||||
}
|
||||
|
||||
$participant->insurance = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user