feat: fill default names for canceled participants in agency bookings
This commit is contained in:
@@ -290,7 +290,11 @@ class BookingDataProcessor
|
||||
}
|
||||
|
||||
$this->serviceProcessor->removeUnusedServices($bookingData);
|
||||
$this->personalDataSynchronizer->updateParticipantPersonalData($formData->participants, $bookingData);
|
||||
$this->personalDataSynchronizer->updateParticipantPersonalData(
|
||||
$formData->participants,
|
||||
$bookingData,
|
||||
$formData->isInternalAgencyBooking()
|
||||
);
|
||||
|
||||
$payload = $this->payloadBuilder->buildBasePayload($bookingData);
|
||||
$this->payloadBuilder->addBankAccountToPayload($payload, $bookingData);
|
||||
|
||||
@@ -33,9 +33,13 @@ class PersonalDataSynchronizer
|
||||
*
|
||||
* @param array<ParticipantDto> $participants The participants array from the form
|
||||
* @param Booking $bookingData The booking data object to update
|
||||
* @param bool $isInternalAgencyBooking Whether to fill default names for canceled participants
|
||||
*/
|
||||
public function updateParticipantPersonalData(array $participants, Booking $bookingData): void
|
||||
{
|
||||
public function updateParticipantPersonalData(
|
||||
array $participants,
|
||||
Booking $bookingData,
|
||||
bool $isInternalAgencyBooking = false
|
||||
): void {
|
||||
// Fill missing mandatory fields on applicant (for company bookings by travel agencies)
|
||||
// This is separate from participants - applicant may be a company while participants are real people
|
||||
$this->fillMissingApplicantFields($bookingData);
|
||||
@@ -43,6 +47,24 @@ class PersonalDataSynchronizer
|
||||
foreach ($participants as $participant) {
|
||||
$bookingData->participants[$participant->index]->firstName = $participant->firstName;
|
||||
$bookingData->participants[$participant->index]->name = $participant->lastName;
|
||||
|
||||
// For internal agency bookings, canceled participants with empty names get default values
|
||||
// since they are read-only in the UI and cannot be fixed by applicants
|
||||
if ($isInternalAgencyBooking) {
|
||||
$status = $bookingData->participantsStatus[$participant->index] ?? null;
|
||||
if ('S' === $status) {
|
||||
$defaultName = sprintf('Teilnehmer:in %d', $participant->index + 1);
|
||||
$personalData = $bookingData->participants[$participant->index];
|
||||
|
||||
if (null === $personalData->firstName || '' === $personalData->firstName) {
|
||||
$personalData->firstName = $defaultName;
|
||||
}
|
||||
if (null === $personalData->name || '' === $personalData->name) {
|
||||
$personalData->name = $defaultName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$bookingData->participants[$participant->index]->dateOfBirth = $participant->dateOfBirth;
|
||||
$bookingData->participants[$participant->index]->gender = $participant->gender;
|
||||
$bookingData->participants[$participant->index]->nationality = $participant->nationality;
|
||||
|
||||
@@ -534,4 +534,123 @@ class BookingDataProcessorTest extends TestCase
|
||||
|
||||
return $pickup;
|
||||
}
|
||||
|
||||
public function testCanceledParticipantEmptyNamesFilledForAgencyBooking(): void
|
||||
{
|
||||
$formData = $this->createFormDataWithCanceledParticipantEmptyNames();
|
||||
|
||||
$this->processor->createUpdateRequestPayload($formData);
|
||||
|
||||
// Canceled participant (index 1) should have default names filled
|
||||
$canceledParticipant = $formData->booking->participants[1];
|
||||
$this->assertEquals('Teilnehmer:in 2', $canceledParticipant->firstName);
|
||||
$this->assertEquals('Teilnehmer:in 2', $canceledParticipant->name);
|
||||
|
||||
// Active participant (index 0) should retain original names from form
|
||||
$activeParticipant = $formData->booking->participants[0];
|
||||
$this->assertEquals('Participant0', $activeParticipant->firstName);
|
||||
$this->assertEquals('LastName', $activeParticipant->name);
|
||||
}
|
||||
|
||||
public function testCanceledParticipantNamesNotFilledForNonAgencyBooking(): void
|
||||
{
|
||||
$formData = $this->createFormDataWithCanceledParticipantEmptyNamesNonAgency();
|
||||
|
||||
$this->processor->createUpdateRequestPayload($formData);
|
||||
|
||||
// Canceled participant should retain empty names (non-agency booking)
|
||||
$canceledParticipant = $formData->booking->participants[1];
|
||||
$this->assertEquals('', $canceledParticipant->firstName);
|
||||
$this->assertEquals('', $canceledParticipant->name);
|
||||
}
|
||||
|
||||
private function createFormDataWithCanceledParticipantEmptyNames(): BookingDto
|
||||
{
|
||||
$bookingDto = new BookingDto($this->createMockTravel(), 1);
|
||||
$bookingDto->booking = $this->createMockBookingWithCanceledParticipantEmptyNames();
|
||||
$bookingDto->agencyCode = '0004'; // Internal agency code to trigger isInternalAgencyBooking()
|
||||
$bookingDto->participants = [
|
||||
$this->createMockParticipantDto(0, 'F'),
|
||||
$this->createMockParticipantDtoWithEmptyNames(1, 'S'),
|
||||
];
|
||||
|
||||
return $bookingDto;
|
||||
}
|
||||
|
||||
private function createFormDataWithCanceledParticipantEmptyNamesNonAgency(): BookingDto
|
||||
{
|
||||
$bookingDto = new BookingDto($this->createMockTravel(), 1);
|
||||
$bookingDto->booking = $this->createMockBookingWithCanceledParticipantEmptyNames();
|
||||
$bookingDto->agencyCode = null; // No agency - not an internal agency booking
|
||||
$bookingDto->participants = [
|
||||
$this->createMockParticipantDto(0, 'F'),
|
||||
$this->createMockParticipantDtoWithEmptyNames(1, 'S'),
|
||||
];
|
||||
|
||||
return $bookingDto;
|
||||
}
|
||||
|
||||
private function createMockBookingWithCanceledParticipantEmptyNames(): Booking
|
||||
{
|
||||
$booking = new Booking();
|
||||
$booking->id = 123;
|
||||
$booking->status = 'ACTIVE';
|
||||
$booking->agencyId = 999;
|
||||
$booking->dateId = 1;
|
||||
$booking->hotelId = 1;
|
||||
$booking->paymentId = '1';
|
||||
$booking->paymentLabel = 'Credit Card';
|
||||
$booking->paymentType = 'CC';
|
||||
$booking->additionalServices = [];
|
||||
$booking->transportationServices = [];
|
||||
$booking->pickupsOutbound = [];
|
||||
$booking->pickupsInbound = [];
|
||||
|
||||
$canceledParticipant = new PersonalData();
|
||||
$canceledParticipant->firstName = '';
|
||||
$canceledParticipant->name = '';
|
||||
$canceledParticipant->dateOfBirth = new \DateTimeImmutable('1990-01-01');
|
||||
$canceledParticipant->gender = 'M';
|
||||
$canceledParticipant->nationality = 'DE';
|
||||
$canceledParticipant->address = new Address();
|
||||
$canceledParticipant->communication = new Communication();
|
||||
|
||||
$booking->participants = [
|
||||
$this->createMockPersonalData('Participant0'),
|
||||
$canceledParticipant,
|
||||
];
|
||||
$booking->participantsStatus = ['F', 'S']; // Second participant is canceled
|
||||
$booking->applicant = $this->createMockPersonalData('Applicant');
|
||||
$booking->bankAccount = null;
|
||||
$booking->rooms = [];
|
||||
|
||||
return $booking;
|
||||
}
|
||||
|
||||
private function createMockParticipantDtoWithEmptyNames(int $index, string $status): ParticipantDto
|
||||
{
|
||||
$participant = new ParticipantDto();
|
||||
$participant->index = $index;
|
||||
$participant->status = $status;
|
||||
$participant->firstName = '';
|
||||
$participant->lastName = '';
|
||||
$participant->dateOfBirth = new \DateTimeImmutable('1990-01-01');
|
||||
$participant->gender = 'M';
|
||||
$participant->nationality = 'DE';
|
||||
$participant->height = '175';
|
||||
$participant->weight = '70';
|
||||
$participant->shoeSize = '40';
|
||||
$participant->email = null;
|
||||
$participant->mobile = null;
|
||||
$participant->courses = [];
|
||||
$participant->additionalServices = [];
|
||||
$participant->skiPass = null;
|
||||
$participant->board = [];
|
||||
$participant->rentals = [];
|
||||
$participant->transportationOutbound = $this->createMockService(1);
|
||||
$participant->transportationInbound = $this->createMockService(2);
|
||||
$participant->pickup = null;
|
||||
|
||||
return $participant;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user