feat: proper determination of agency initiated bookings

For booking that are agency initiated (groups) different rules apply
concerning mutability and requirement of personal data and whether the
first participant is the applicant or not. This commit adds logic to
evaluate the agency id assigned to the booking data to decide.
This commit is contained in:
Björn Fromme committed 2026-03-16 12:02:27 +01:00
1 parent f55ed3dc4c
commit e222f448bb
20 files changed
+201 -137

No files matched your search

@@ -0,0 +1,95 @@
<?php
declare(strict_types=1);
namespace App\Form\Service\Condition;
use App\Form\Model\BookingDto;
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.
*
* 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
*
* Non-first participants are never affected by this condition - they return false here
* but may still be read-only via PersonalDataMutabilityCondition in edit mode.
*/
class FirstParticipantReadOnlyCondition implements FieldConditionInterface
{
/**
* Evaluates if personal data fields should be shown as static text for the first participant.
*
* @param BookingDto $bookingDto The booking data
* @param int $participantIndex The index of the participant being evaluated
* @param array<string, mixed> $formData Current form data (unused)
*
* @return bool True if fields should be shown as static text (read-only)
*/
public function evaluate(BookingDto $bookingDto, int $participantIndex, array $formData): bool
{
// This condition only applies to first participant (agency-based read-only)
// 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()) {
return false;
}
// Non-internal agency = first participant = applicant = always read-only
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.
*
* @return string[] Empty array - no field dependencies
*/
public function getDependentFields(): array
{
return [];
}
/**
* Returns a human-readable description of this condition.
*
* @return string Description of the first participant read-only logic
*/
public function getDescription(): string
{
return 'First participant personal data is read-only for non-internal agency bookings with logged-in users';
}
}