feat: split booking between participants and applicant
addresses #869f2q1vu
This commit is contained in:
1 parent
0ee8fafbe1
commit
ad6e42ab0c
44 files changed
+2024
-316
No files matched your search
@@ -10,15 +10,19 @@ use App\Form\Service\Contract\FieldConditionInterface;
|
||||
/**
|
||||
* Condition that determines if the first participant's personal data should be read-only.
|
||||
*
|
||||
* This condition evaluates read-only state based on agency type and authentication state,
|
||||
* replacing the previous personId-based detection with agency code-based detection.
|
||||
* It fires only where participant[0] IS the booking's applicant, which
|
||||
* BookingDto::isFirstParticipantApplicant() decides: the booking-level choice in create mode,
|
||||
* and anmelder vs. participant[0] person id in edit mode. Internal agency bookings answer
|
||||
* false there, which preserves the behaviour this class used to spell out itself.
|
||||
*
|
||||
* Business Rules:
|
||||
* - CREATE mode (anonymous user): First participant data is editable (user must fill it in)
|
||||
* - CREATE mode (logged-in, non-internal agency): First participant = applicant, data is read-only
|
||||
* - CREATE mode (logged-in, internal agency): First participant ≠ applicant, data is editable
|
||||
* - EDIT mode (internal agency): First participant ≠ applicant, data is editable (mutability applies separately)
|
||||
* - EDIT mode (non-internal agency): First participant = applicant, always read-only
|
||||
* - CREATE mode (logged-in, participant[0] is the applicant): data is prepopulated, read-only
|
||||
* - CREATE mode (applicant does not travel, or internal agency): participant[0] is an ordinary
|
||||
* traveller, data is editable
|
||||
* - EDIT mode (participant[0] is the applicant): always read-only
|
||||
* - EDIT mode (split booking, or internal agency): participant[0] ≠ applicant, editable here
|
||||
* (PersonalDataMutabilityCondition still applies separately)
|
||||
*
|
||||
* Non-first participants are never affected by this condition - they return false here
|
||||
* but may still be read-only via PersonalDataMutabilityCondition in edit mode.
|
||||
@@ -36,45 +40,31 @@ class FirstParticipantReadOnlyCondition implements FieldConditionInterface
|
||||
*/
|
||||
public function evaluate(BookingDto $bookingDto, int $participantIndex, array $formData): bool
|
||||
{
|
||||
// This condition only applies to first participant (agency-based read-only)
|
||||
// This condition only applies to the first participant.
|
||||
// Non-first participants: return false here, but may still be read-only via PersonalDataMutabilityCondition
|
||||
if (0 !== $participantIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$participant = $bookingDto->getParticipant($participantIndex);
|
||||
|
||||
// CREATE mode logic
|
||||
if (BookingDto::MODE_CREATE === $bookingDto->getMode()) {
|
||||
// Anonymous user (no personId) = must fill in data = editable
|
||||
if (null === $participant?->personId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Internal agency = first participant ≠ applicant = editable
|
||||
if ($bookingDto->isInternalAgencyBooking()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Logged-in user with non-internal agency = data prepopulated = read-only
|
||||
return true;
|
||||
}
|
||||
|
||||
// EDIT mode logic
|
||||
// Internal agency = first participant ≠ applicant = editable (mutability check applies separately)
|
||||
if ($bookingDto->isInternalAgencyBooking()) {
|
||||
// participant[0] is a traveller in their own right: nothing to protect here.
|
||||
if (false === $bookingDto->isFirstParticipantApplicant()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Non-internal agency = first participant = applicant = always read-only
|
||||
if (BookingDto::MODE_CREATE === $bookingDto->getMode()) {
|
||||
// Anonymous user (no personId) = must fill in data = editable
|
||||
return null !== $bookingDto->getParticipant($participantIndex)?->personId;
|
||||
}
|
||||
|
||||
// EDIT mode: participant[0] is the applicant, whose record is owned by the account.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns field names that this condition depends on.
|
||||
*
|
||||
* This condition is based on agency code and personId which are set during initialization
|
||||
* and don't change during form interaction, so no field dependencies.
|
||||
* This condition is based on the applicant split and personId, which are set during
|
||||
* initialization and don't change during form interaction, so no field dependencies.
|
||||
*
|
||||
* @return string[] Empty array - no field dependencies
|
||||
*/
|
||||
@@ -90,6 +80,6 @@ class FirstParticipantReadOnlyCondition implements FieldConditionInterface
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'First participant personal data is read-only for non-internal agency bookings with logged-in users';
|
||||
return 'First participant personal data is read-only when they are also the applicant';
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user