feat: bulk insurance booking by applicant
This commit is contained in:
@@ -67,8 +67,9 @@ services:
|
||||
arguments:
|
||||
$choiceListFactory: '@form.choice_list_factory.default'
|
||||
|
||||
# Insurance Field Handler with dependencies
|
||||
# Insurance Field Handlers with dependencies
|
||||
App\Form\Service\ParticipantInsuranceFieldHandler: ~
|
||||
App\Form\Service\ParticipantBulkInsuranceFieldHandler: ~
|
||||
|
||||
# Participant Field Handler Registry - most handlers instantiate dependencies directly, some use services
|
||||
App\Form\Service\ParticipantFieldHandlerRegistry:
|
||||
@@ -91,4 +92,5 @@ services:
|
||||
- 'App\Form\Service\ParticipantRentalInsuranceFieldHandler'
|
||||
- 'App\Form\Service\ParticipantLicensePlateFieldHandler'
|
||||
# Complex handlers with dependencies - use service references
|
||||
- '@App\Form\Service\ParticipantBulkInsuranceFieldHandler'
|
||||
- '@App\Form\Service\ParticipantInsuranceFieldHandler'
|
||||
|
||||
@@ -181,6 +181,7 @@ class BookingCreateParticipantType extends AbstractType
|
||||
'pickupInbound',
|
||||
'parking',
|
||||
'licensePlate',
|
||||
'bulkInsuranceBooking',
|
||||
'insurance',
|
||||
];
|
||||
|
||||
@@ -216,7 +217,7 @@ class BookingCreateParticipantType extends AbstractType
|
||||
$dynamicFields = [
|
||||
'assignedRoomId', 'remarksRoom', 'courses', 'additionalServices', 'board', 'rentals', 'rentalInsurance',
|
||||
'skiPass', 'transportationOutbound', 'transportationInbound', 'pickupOutbound', 'pickupInbound', 'parking',
|
||||
'licensePlate', 'insurance',
|
||||
'licensePlate', 'bulkInsuranceBooking', 'insurance',
|
||||
];
|
||||
foreach ($dynamicFields as $fieldName) {
|
||||
if ($form->has($fieldName)) {
|
||||
@@ -248,6 +249,7 @@ class BookingCreateParticipantType extends AbstractType
|
||||
'pickupInbound' => ChoiceType::class,
|
||||
'parking' => CheckboxType::class,
|
||||
'licensePlate' => TextType::class,
|
||||
'bulkInsuranceBooking' => CheckboxType::class,
|
||||
'insurance' => ChoiceType::class,
|
||||
];
|
||||
|
||||
|
||||
@@ -74,6 +74,9 @@ class ParticipantDto
|
||||
// Selected insurance for this participant (individual insurance selection per participant)
|
||||
public ?Insurance $insurance = null;
|
||||
|
||||
// Bulk insurance booking flag (applicant only: when checked, assigns same insurance type to all participants)
|
||||
public bool $bulkInsuranceBooking = false;
|
||||
|
||||
public static function fromPersonalData(PersonalData $personalData): static
|
||||
{
|
||||
$instance = new static();
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Form\Service\Condition;
|
||||
|
||||
use App\Form\Model\BookingDtoInterface;
|
||||
use App\Form\Service\Contract\FieldConditionInterface;
|
||||
|
||||
/**
|
||||
* Condition that evaluates whether bulk insurance booking is active for dependent participants.
|
||||
*
|
||||
* This condition determines if the applicant (first participant) has enabled bulk insurance
|
||||
* booking for all participants. When active, dependent participants (index > 0) will have
|
||||
* their insurance field replaced with a "wie Anmelder" (same as applicant) message, and the
|
||||
* applicant's insurance selection (or lack thereof) will be automatically applied to all
|
||||
* participants based on their individual travel prices and age constraints.
|
||||
*
|
||||
* The condition is satisfied when:
|
||||
* 1. Evaluating a dependent participant (not the applicant)
|
||||
* 2. The applicant has bulkInsuranceBooking flag set to true
|
||||
*/
|
||||
class BulkInsuranceBookingCondition implements FieldConditionInterface
|
||||
{
|
||||
/**
|
||||
* Evaluates if bulk insurance booking is active for the given participant.
|
||||
*
|
||||
* For the applicant (index 0), always returns false since they control the bulk booking.
|
||||
* For dependent participants, returns true if the applicant has bulk insurance booking enabled,
|
||||
* regardless of whether an insurance is selected (applies to "no insurance" as well).
|
||||
*
|
||||
* @param BookingDtoInterface $bookingDto The current booking data
|
||||
* @param int $participantIndex The index of the participant being evaluated
|
||||
* @param array<string, mixed> $formData Current form data for condition evaluation
|
||||
*
|
||||
* @return bool True if bulk insurance booking is active for this dependent participant
|
||||
*/
|
||||
public function evaluate(BookingDtoInterface $bookingDto, int $participantIndex, array $formData): bool
|
||||
{
|
||||
// Applicant is never affected by bulk insurance booking (they control it)
|
||||
if (0 === $participantIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get applicant data
|
||||
$applicant = $bookingDto->getParticipant(0);
|
||||
if (null === $applicant) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if applicant has bulk insurance booking enabled
|
||||
// No need to check for insurance selection - bulk applies even when no insurance is selected
|
||||
return $this->getBulkInsuranceBookingValue($formData, $applicant);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns field names that this condition depends on.
|
||||
*
|
||||
* This condition depends on the applicant's bulkInsuranceBooking flag.
|
||||
* Any changes to this field should trigger re-evaluation of dependent participant field states.
|
||||
*
|
||||
* @return string[] Array containing field names this condition depends on
|
||||
*/
|
||||
public function getDependentFields(): array
|
||||
{
|
||||
return ['bulkInsuranceBooking'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human-readable description of this condition.
|
||||
*
|
||||
* @return string Description of the bulk insurance booking condition
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Applicant has bulk insurance booking enabled';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bulk insurance booking flag value from form data or participant DTO.
|
||||
*/
|
||||
private function getBulkInsuranceBookingValue(array $formData, object $applicant): bool
|
||||
{
|
||||
// First check form data (for fresh submissions)
|
||||
if (isset($formData['participants'][0]['bulkInsuranceBooking'])) {
|
||||
return (bool) $formData['participants'][0]['bulkInsuranceBooking'];
|
||||
}
|
||||
|
||||
// Fall back to participant DTO
|
||||
if (property_exists($applicant, 'bulkInsuranceBooking')) {
|
||||
return (bool) $applicant->bulkInsuranceBooking;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ namespace App\Form\Service;
|
||||
|
||||
use App\BusProNet\Utility\DirectionMapper;
|
||||
use App\Form\Service\Abstract\AbstractFieldStateProvider;
|
||||
use App\Form\Service\Condition\BulkInsuranceBookingCondition;
|
||||
use App\Form\Service\Condition\CompositeCondition;
|
||||
use App\Form\Service\Condition\DateOfBirthProvidedCondition;
|
||||
use App\Form\Service\Condition\FieldValueCondition;
|
||||
@@ -87,9 +88,38 @@ class CreateFieldStateProvider extends AbstractFieldStateProvider
|
||||
'hidden' => CompositeCondition::not($dateOfBirthProvidedCondition),
|
||||
];
|
||||
|
||||
// Hide insurance field until date of birth is provided
|
||||
// Bulk insurance booking conditions
|
||||
$bulkInsuranceBookingCondition = new BulkInsuranceBookingCondition();
|
||||
|
||||
// Show bulk insurance booking checkbox ONLY for applicant (index 0) and when insurance field is visible
|
||||
$this->fieldStateConditions['bulkInsuranceBooking'] = [
|
||||
'hidden' => CompositeCondition::or(
|
||||
CompositeCondition::not($dateOfBirthProvidedCondition), // Hide until date of birth provided
|
||||
new class() implements \App\Form\Service\Contract\FieldConditionInterface {
|
||||
public function evaluate(\App\Form\Model\BookingDtoInterface $bookingDto, int $participantIndex, array $formData): bool
|
||||
{
|
||||
return $participantIndex > 0; // Hide for all participants except applicant
|
||||
}
|
||||
|
||||
public function getDependentFields(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Participant is not the applicant';
|
||||
}
|
||||
}
|
||||
),
|
||||
];
|
||||
|
||||
// Hide insurance field until date of birth is provided OR when bulk insurance booking is active for dependent participants
|
||||
$this->fieldStateConditions['insurance'] = [
|
||||
'hidden' => CompositeCondition::not($dateOfBirthProvidedCondition),
|
||||
'hidden' => CompositeCondition::or(
|
||||
CompositeCondition::not($dateOfBirthProvidedCondition),
|
||||
$bulkInsuranceBookingCondition
|
||||
),
|
||||
];
|
||||
|
||||
// Room-specific field conditions
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -405,6 +405,17 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
'required' => false,
|
||||
];
|
||||
|
||||
// Bulk insurance booking checkbox (applicant only - controls insurance assignment for all participants)
|
||||
$this->fieldOptionProviders['bulkInsuranceBooking'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Für alle Teilnehmer buchen',
|
||||
'required' => false,
|
||||
'attr' => [
|
||||
'hx-post' => $this->urlGenerator->generate('app_booking_create_step_2_refresh'),
|
||||
'hx-swap' => 'none',
|
||||
'hx-trigger' => 'change',
|
||||
],
|
||||
];
|
||||
|
||||
// Insurance field provider - provides age and eligibility filtered insurances for participants
|
||||
$this->fieldOptionProviders['insurance'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Reiseversicherung',
|
||||
|
||||
@@ -82,13 +82,22 @@ class ParticipantInsuranceFieldHandler extends AbstractParticipantFieldHandler
|
||||
* where the selection is cleared (field not present in data). This ensures
|
||||
* the participant DTO is updated with null when no insurance is selected.
|
||||
*
|
||||
* However, when bulk insurance booking is active for a dependent participant,
|
||||
* we skip processing to prevent overwriting the insurance assigned by the
|
||||
* bulk insurance handler.
|
||||
*
|
||||
* @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
|
||||
* @return bool True if processing should occur, false if bulk insurance handles it
|
||||
*/
|
||||
public function shouldProcess(array $submittedData, int $participantIndex): bool
|
||||
{
|
||||
// Skip processing for dependent participants when bulk insurance booking is active
|
||||
if ($participantIndex > 0 && $this->isBulkInsuranceBookingActive($submittedData)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true; // Always process to handle deselection cases
|
||||
}
|
||||
|
||||
@@ -258,4 +267,35 @@ class ParticipantInsuranceFieldHandler extends AbstractParticipantFieldHandler
|
||||
{
|
||||
return (string) $currentInsurance->id === (string) $selectedInsuranceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if bulk insurance booking is active for dependent participants.
|
||||
*
|
||||
* Bulk insurance is active when the applicant has enabled the bulkInsuranceBooking
|
||||
* flag and has selected an insurance.
|
||||
*
|
||||
* @param array<string, mixed> $submittedData The submitted form data
|
||||
*
|
||||
* @return bool True if bulk insurance booking is active
|
||||
*/
|
||||
private function isBulkInsuranceBookingActive(array $submittedData): bool
|
||||
{
|
||||
// Check if applicant data exists
|
||||
if (!isset($submittedData['participants'][0])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$applicantData = $submittedData['participants'][0];
|
||||
|
||||
// Check if bulk insurance booking is enabled
|
||||
$bulkInsuranceBooking = $applicantData['bulkInsuranceBooking'] ?? false;
|
||||
if (false === (bool) $bulkInsuranceBooking) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if applicant has selected an insurance
|
||||
$applicantInsurance = $applicantData['insurance'] ?? null;
|
||||
|
||||
return null !== $applicantInsurance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,8 +63,8 @@ class InsuranceMatchingService
|
||||
*/
|
||||
public function reassignInsuranceForPriceChange(array $availableInsurances, Insurance $currentInsurance, ParticipantDto $participant, BookingCreateDto $booking): ?Insurance
|
||||
{
|
||||
// Group insurances of the same type (subType + familyInsurance)
|
||||
$sameTypeInsurances = $this->filterInsurancesByType($availableInsurances, $currentInsurance->subType, $currentInsurance->familyInsurance);
|
||||
// Group insurances of the same type
|
||||
$sameTypeInsurances = $this->filterInsurancesByType($availableInsurances, $currentInsurance);
|
||||
|
||||
// Get eligible insurances for this participant
|
||||
$eligibleInsurances = $this->getEligibleInsurances($sameTypeInsurances, $participant, $booking);
|
||||
@@ -96,8 +96,8 @@ class InsuranceMatchingService
|
||||
{
|
||||
$assignments = [];
|
||||
|
||||
// Group insurances of the same type (subType + familyInsurance)
|
||||
$sameTypeInsurances = $this->filterInsurancesByType($availableInsurances, $selectedInsurance->subType, $selectedInsurance->familyInsurance);
|
||||
// Group insurances of the same type
|
||||
$sameTypeInsurances = $this->filterInsurancesByType($availableInsurances, $selectedInsurance);
|
||||
|
||||
// Assign appropriate insurance to each participant
|
||||
foreach ($booking->getParticipants() as $index => $participant) {
|
||||
@@ -329,22 +329,39 @@ class InsuranceMatchingService
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters insurances by type (subType and familyInsurance combination).
|
||||
* Filters insurances by type based on label (for packages) or subType (for individual insurances).
|
||||
*
|
||||
* This method groups insurances of the same type together for reassignment or batch assignment.
|
||||
* Insurance type is defined as the combination of subType (RRV, PAK, OHN) and familyInsurance flag.
|
||||
* Insurance type matching strategy:
|
||||
* - **Packages**: Match by label + familyInsurance (packages with same label are different price tiers)
|
||||
* - **Individual insurances**: Match by subType + familyInsurance
|
||||
*
|
||||
* @param array<Insurance> $insurances All available insurances to filter
|
||||
* @param string|null $subType The insurance subType to match (e.g., 'RRV', 'PAK')
|
||||
* @param bool $familyInsurance Whether to match family or individual insurances
|
||||
* Example: "Reise-Rücktritt + Selbstbehaltübernahme" at €10, €14, €26 are the same type,
|
||||
* but different from "Reiseschutz Platin Auto/Bahn/Bus (Europa) + Selbstbehaltübernahme".
|
||||
*
|
||||
* @param array<Insurance> $insurances All available insurances to filter
|
||||
* @param Insurance $referenceInsurance The insurance to match against
|
||||
*
|
||||
* @return array<Insurance> Filtered insurances of the same type
|
||||
*/
|
||||
private function filterInsurancesByType(array $insurances, ?string $subType, bool $familyInsurance): array
|
||||
private function filterInsurancesByType(array $insurances, Insurance $referenceInsurance): array
|
||||
{
|
||||
// For packages, match by label (packages with same label are different price tiers of same type)
|
||||
if (true === $referenceInsurance->package) {
|
||||
return array_filter(
|
||||
$insurances,
|
||||
fn (Insurance $insurance) => true === $insurance->package
|
||||
&& $insurance->label === $referenceInsurance->label
|
||||
&& $insurance->familyInsurance === $referenceInsurance->familyInsurance
|
||||
);
|
||||
}
|
||||
|
||||
// For individual insurances, match by subType
|
||||
return array_filter(
|
||||
$insurances,
|
||||
fn (Insurance $insurance) => $insurance->subType === $subType && $insurance->familyInsurance === $familyInsurance
|
||||
fn (Insurance $insurance) => false === $insurance->package
|
||||
&& $insurance->subType === $referenceInsurance->subType
|
||||
&& $insurance->familyInsurance === $referenceInsurance->familyInsurance
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,14 +183,49 @@
|
||||
'hx-swap': 'none'
|
||||
}
|
||||
}) }}
|
||||
|
||||
{{ _self.service_field(participant, 'insurance', 'Reiseversicherung', {
|
||||
'attr': {
|
||||
'hx-trigger': 'change',
|
||||
'hx-post': path('app_booking_create_step_2_refresh'),
|
||||
'hx-swap': 'none'
|
||||
}
|
||||
}) }}
|
||||
|
||||
{# Insurance field OR assigned insurance display for dependent participants #}
|
||||
{% set participantData = participant.vars.data %}
|
||||
{% set showBulkInsurance = loop.index > 1 and form.vars.data.participants[0].bulkInsuranceBooking %}
|
||||
|
||||
{% if showBulkInsurance %}
|
||||
<fieldset class="mb-1">
|
||||
<legend class="font-semibold mb-1">Reiseversicherung</legend>
|
||||
<div class="text-sm text-gray-600">
|
||||
{% if participantData.insurance %}
|
||||
{{ participantData.insurance.label }}
|
||||
{% if participantData.insurance.price and participantData.insurance.price > 0 %}
|
||||
<span class="text-gray-500">(€{{ participantData.insurance.price|number_format(2, ',', '.') }})</span>
|
||||
{% endif %}
|
||||
<span class="italic text-gray-500 ml-2">– wie Anmelder</span>
|
||||
{% else %}
|
||||
<span class="italic">wie Anmelder</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</fieldset>
|
||||
{% else %}
|
||||
<fieldset class="mb-1">
|
||||
<legend class="font-semibold mb-1">Reiseversicherung</legend>
|
||||
|
||||
{# Bulk insurance booking checkbox (applicant only) #}
|
||||
{% if participant.bulkInsuranceBooking is defined %}
|
||||
{{ form_row(participant.bulkInsuranceBooking) }}
|
||||
{% endif %}
|
||||
|
||||
{% if participant.insurance is defined %}
|
||||
{{ form_row(participant.insurance, {
|
||||
'attr': {
|
||||
'hx-trigger': 'change',
|
||||
'hx-post': path('app_booking_create_step_2_refresh'),
|
||||
'hx-swap': 'none'
|
||||
},
|
||||
'label': false
|
||||
}) }}
|
||||
{% else %}
|
||||
<div class="text-sm text-gray-500">Nicht wählbar</div>
|
||||
{% endif %}
|
||||
</fieldset>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{# Transportation Services Section #}
|
||||
|
||||
Reference in New Issue
Block a user