206 lines
9.1 KiB
PHP
206 lines
9.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Form\Service;
|
|
|
|
use App\BusProNet\Utility\DirectionMapper;
|
|
use App\Form\Model\BookingDto;
|
|
use App\Form\Service\Abstract\AbstractFieldStateProvider;
|
|
use App\Form\Service\Condition\AdditionalServicesMutabilityCondition;
|
|
use App\Form\Service\Condition\ApplicantCondition;
|
|
use App\Form\Service\Condition\AuthenticatedUserPersonalDataCondition;
|
|
use App\Form\Service\Condition\BookingModeCondition;
|
|
use App\Form\Service\Condition\CompositeCondition;
|
|
use App\Form\Service\Condition\DateOfBirthProvidedCondition;
|
|
use App\Form\Service\Condition\FieldValueCondition;
|
|
use App\Form\Service\Condition\PersonalDataMutabilityCondition;
|
|
use App\Form\Service\Condition\PickupsMutabilityCondition;
|
|
use App\Form\Service\Condition\RentalSelectionCondition;
|
|
use App\Form\Service\Condition\RoomSelectionCondition;
|
|
use App\Form\Service\Condition\ServiceSubTypeCondition;
|
|
use App\Form\Service\Condition\SkiPassSelectionCondition;
|
|
use App\Form\Service\Condition\TransportationServicesMutabilityCondition;
|
|
|
|
/**
|
|
* Field state provider for the booking edit workflow.
|
|
*
|
|
* This service calculates dynamic field states (readonly, disabled, etc.)
|
|
* for participant fields in the edit flow, using edit-specific conditions.
|
|
*
|
|
* It extends the common field state functionality provided by
|
|
* AbstractFieldStateProvider and adds edit-specific field state logic.
|
|
*/
|
|
class EditFieldStateProvider extends AbstractFieldStateProvider
|
|
{
|
|
/**
|
|
* Registers field state conditions for the edit workflow.
|
|
*
|
|
* This method defines the conditional logic for field states in the
|
|
* booking edit process. It makes fields readonly based on mutability flags
|
|
* and applies the same conditional visibility logic as the create flow.
|
|
*/
|
|
protected function registerFieldStateConditions(): void
|
|
{
|
|
// Mutability conditions
|
|
$additionalServicesMutabilityCondition = new AdditionalServicesMutabilityCondition();
|
|
$transportationServicesMutabilityCondition = new TransportationServicesMutabilityCondition();
|
|
$pickupsMutabilityCondition = new PickupsMutabilityCondition();
|
|
|
|
// Personal data protection in edit mode has TWO rules:
|
|
// 1. Applicant with personId (authenticated user) - prevents editing master personal data
|
|
// Only applies to applicant (index 0), not other participants with personId
|
|
// 2. BPN mutability flag (mutable=false) - respects BPN business rules for any participant
|
|
// Hide fields if EITHER condition is true
|
|
$applicantCondition = new ApplicantCondition();
|
|
$authenticatedUserCondition = new AuthenticatedUserPersonalDataCondition();
|
|
$personalDataMutabilityCondition = new PersonalDataMutabilityCondition();
|
|
$personalDataHiddenCondition = CompositeCondition::or(
|
|
CompositeCondition::and($applicantCondition, $authenticatedUserCondition),
|
|
$personalDataMutabilityCondition
|
|
);
|
|
|
|
// Render all personal data fields as static text if authenticated user OR BPN indicates not mutable
|
|
// Using 'static_text' state (not 'hidden') so template renders values as static text
|
|
$personalDataFields = [
|
|
'firstName',
|
|
'lastName',
|
|
'dateOfBirth',
|
|
'gender',
|
|
'nationality',
|
|
'email',
|
|
'mobile',
|
|
];
|
|
foreach ($personalDataFields as $field) {
|
|
$this->fieldStateConditions[$field] = [
|
|
'static_text' => $personalDataHiddenCondition,
|
|
];
|
|
}
|
|
|
|
// Address fields - render as static text if authenticated user OR participant not mutable
|
|
$this->fieldStateConditions['address'] = [
|
|
'static_text' => $personalDataHiddenCondition,
|
|
];
|
|
|
|
// Address subfields - render as static text if authenticated user OR participant not mutable
|
|
$this->fieldStateConditions['address.street'] = [
|
|
'static_text' => $personalDataHiddenCondition,
|
|
];
|
|
|
|
$this->fieldStateConditions['address.postCode'] = [
|
|
'static_text' => $personalDataHiddenCondition,
|
|
];
|
|
|
|
$this->fieldStateConditions['address.city'] = [
|
|
'static_text' => $personalDataHiddenCondition,
|
|
];
|
|
|
|
$this->fieldStateConditions['address.country'] = [
|
|
'static_text' => $personalDataHiddenCondition,
|
|
];
|
|
|
|
// Room assignments are fixed in edit mode - always render as static text
|
|
// The assignedRoomId value passes through unchanged from the loaded booking data
|
|
$this->fieldStateConditions['assignedRoomId'] = [
|
|
'static_text' => new BookingModeCondition(BookingDto::MODE_EDIT),
|
|
];
|
|
|
|
// Show remarks room field only when room with code 'mbz' (single bed) is selected
|
|
$sharedRoomCondition = new RoomSelectionCondition(['mbz']);
|
|
$this->fieldStateConditions['remarksRoom'] = [
|
|
'hidden' => CompositeCondition::not($sharedRoomCondition),
|
|
];
|
|
|
|
// Conditional visibility for service fields (same as create flow)
|
|
$rentalCondition = new RentalSelectionCondition();
|
|
$skiPassCondition = new SkiPassSelectionCondition();
|
|
$dateOfBirthProvidedCondition = new DateOfBirthProvidedCondition();
|
|
|
|
// Hide body dimensions unless rentals are selected
|
|
$this->fieldStateConditions['bodyDimensions'] = [
|
|
'hidden' => CompositeCondition::not($rentalCondition),
|
|
];
|
|
|
|
// Age-dependent service fields - hidden until birth date provided (except for applicant who always has DOB)
|
|
// Also readonly if services not mutable
|
|
// For applicant in edit mode: DOB is always available (patched from booking), so never hide
|
|
$hideUntilDobCondition = CompositeCondition::and(
|
|
CompositeCondition::not($dateOfBirthProvidedCondition),
|
|
CompositeCondition::not(new ApplicantCondition()) // Don't hide for applicant
|
|
);
|
|
|
|
$this->fieldStateConditions['courses'] = [
|
|
'hidden' => $hideUntilDobCondition,
|
|
'readonly' => $additionalServicesMutabilityCondition,
|
|
];
|
|
|
|
$this->fieldStateConditions['additionalServices'] = [
|
|
'hidden' => $hideUntilDobCondition,
|
|
'readonly' => $additionalServicesMutabilityCondition,
|
|
];
|
|
|
|
$this->fieldStateConditions['board'] = [
|
|
'hidden' => $hideUntilDobCondition,
|
|
'readonly' => $additionalServicesMutabilityCondition,
|
|
];
|
|
|
|
// Skipass - hidden until birth date (except applicant), readonly if services not mutable
|
|
$this->fieldStateConditions['skiPass'] = [
|
|
'hidden' => $hideUntilDobCondition,
|
|
'readonly' => $additionalServicesMutabilityCondition,
|
|
];
|
|
|
|
// Rentals - shown only when skipass selected, readonly if services not mutable
|
|
// For applicant: only check skipass, not DOB
|
|
$this->fieldStateConditions['rentals'] = [
|
|
'hidden' => CompositeCondition::or(
|
|
$hideUntilDobCondition,
|
|
CompositeCondition::not($skiPassCondition)
|
|
),
|
|
'readonly' => $additionalServicesMutabilityCondition,
|
|
];
|
|
|
|
// Rental insurance - shown only when rentals selected, readonly if services not mutable
|
|
$this->fieldStateConditions['rentalInsurance'] = [
|
|
'hidden' => CompositeCondition::not($rentalCondition),
|
|
'readonly' => $additionalServicesMutabilityCondition,
|
|
];
|
|
|
|
// Transportation fields - hidden until birth date (except applicant), readonly if transportation not mutable
|
|
$this->fieldStateConditions['transportationOutbound'] = [
|
|
'hidden' => $hideUntilDobCondition,
|
|
'readonly' => $transportationServicesMutabilityCondition,
|
|
];
|
|
|
|
$this->fieldStateConditions['transportationInbound'] = [
|
|
'hidden' => $hideUntilDobCondition,
|
|
'readonly' => $transportationServicesMutabilityCondition,
|
|
];
|
|
|
|
// Pickup field (unified) - shown only when either transportation direction is BUS, readonly if pickups not mutable
|
|
$this->fieldStateConditions['pickup'] = [
|
|
'hidden' => CompositeCondition::not(
|
|
CompositeCondition::or(
|
|
ServiceSubTypeCondition::equals('transportationOutbound', DirectionMapper::SUBTYPE_BUS_API),
|
|
ServiceSubTypeCondition::equals('transportationInbound', DirectionMapper::SUBTYPE_BUS_API)
|
|
)
|
|
),
|
|
'readonly' => $pickupsMutabilityCondition,
|
|
];
|
|
|
|
// Parking - shown only when outbound transportation is PKW, readonly if transportation not mutable
|
|
$this->fieldStateConditions['parking'] = [
|
|
'hidden' => CompositeCondition::not(
|
|
ServiceSubTypeCondition::equals('transportationOutbound', DirectionMapper::SUBTYPE_CAR_API)
|
|
),
|
|
'readonly' => $transportationServicesMutabilityCondition,
|
|
];
|
|
|
|
// License plate - shown only when parking selected, readonly if transportation not mutable
|
|
$this->fieldStateConditions['licensePlate'] = [
|
|
'hidden' => FieldValueCondition::equals('parking', false),
|
|
'readonly' => $transportationServicesMutabilityCondition,
|
|
];
|
|
}
|
|
}
|