feat: improved mutability checks for personal data in edit or create mode
This commit is contained in:
@@ -69,6 +69,20 @@ class BookingDataProcessor
|
||||
$participantData = ParticipantDto::fromPersonalData($participant);
|
||||
$participantData->index = $index;
|
||||
|
||||
// First participant (applicant): copy address from applicant if participant address is empty
|
||||
// BPN API may return full address only in <anmelder> but minimal/empty address in <teilnehmer id="1">
|
||||
// Only copy if first participant has no street (indicating empty/incomplete address)
|
||||
// This allows applicant and first participant to be different people with different addresses
|
||||
if (0 === $index && null !== $booking->applicant->address) {
|
||||
$isEmpty = null === $participantData->address
|
||||
|| null === $participantData->address->street
|
||||
|| '' === trim($participantData->address->street);
|
||||
|
||||
if ($isEmpty) {
|
||||
$participantData->address = clone $booking->applicant->address;
|
||||
}
|
||||
}
|
||||
|
||||
// Extract service selections from booking and assign to participant DTO
|
||||
$participantData->courses = $booking
|
||||
->getAdditionalServicesForParticipantByGroup($index, Constants::TOKEN_COURSES);
|
||||
@@ -429,13 +443,16 @@ class BookingDataProcessor
|
||||
* Maps insurance to the participant. Adds new insurances to the booking if they don't exist.
|
||||
* Insurance can be either individual or package-based, with automatic price-tier adjustment.
|
||||
*
|
||||
* IMPORTANT: Excludes synthetic "no insurance" option from BPN transmission.
|
||||
*
|
||||
* @param ParticipantDto $participant The participant data from the form
|
||||
* @param Booking $bookingData The booking data object to update
|
||||
* @param Travel $travelData The travel data containing available insurances
|
||||
*/
|
||||
private function processInsurance(ParticipantDto $participant, Booking $bookingData, Travel $travelData): void
|
||||
{
|
||||
if (null === $participant->insurance) {
|
||||
// Skip if no insurance or if participant selected "keine Versicherung gewünscht"
|
||||
if (null === $participant->insurance || $participant->insurance->isNoInsurance()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -760,13 +777,9 @@ class BookingDataProcessor
|
||||
'nationalitaet' => $firstParticipant->nationality ?? '',
|
||||
];
|
||||
|
||||
// Include BPN IDs for linking to existing records (authenticated users)
|
||||
if (null !== $firstParticipant->addressId) {
|
||||
$payload['anmelder']['idadresse'] = $firstParticipant->addressId;
|
||||
}
|
||||
if (null !== $firstParticipant->personId) {
|
||||
$payload['anmelder']['idadresseperson'] = $firstParticipant->personId;
|
||||
}
|
||||
// DO NOT include personId or addressId in create mode
|
||||
// BPN will automatically match existing customers by exact personal data (name, DOB, address)
|
||||
// Including IDs would prevent automatic matching and could cause data inconsistencies
|
||||
|
||||
if (null !== $firstParticipant->dateOfBirth) {
|
||||
$payload['anmelder']['geburtsdatum'] = $firstParticipant->dateOfBirth->format('d.m.Y');
|
||||
@@ -798,13 +811,9 @@ class BookingDataProcessor
|
||||
'nationalitaet' => $participant->nationality ?? '',
|
||||
];
|
||||
|
||||
// Include BPN IDs for linking to existing records (authenticated users)
|
||||
if (null !== $participant->addressId) {
|
||||
$participantData['idadresse'] = $participant->addressId;
|
||||
}
|
||||
if (null !== $participant->personId) {
|
||||
$participantData['idadresseperson'] = $participant->personId;
|
||||
}
|
||||
// DO NOT include personId or addressId in create mode
|
||||
// BPN will automatically match existing customers by exact personal data (name, DOB, address)
|
||||
// Including IDs would prevent automatic matching and could cause data inconsistencies
|
||||
|
||||
if (null !== $participant->dateOfBirth) {
|
||||
$participantData['geburtsdatum'] = $participant->dateOfBirth->format('d.m.Y');
|
||||
@@ -1085,6 +1094,7 @@ class BookingDataProcessor
|
||||
* Collects insurance mappings.
|
||||
*
|
||||
* CRITICAL: Insurance data is only included in CREATE flow, not in UPDATE flow.
|
||||
* IMPORTANT: Excludes synthetic "no insurance" option from BPN transmission.
|
||||
*
|
||||
* @return array<string, array<int>> Map of insurance ID to participant IDs
|
||||
*/
|
||||
@@ -1095,7 +1105,8 @@ class BookingDataProcessor
|
||||
foreach ($bookingDto->participants as $index => $participant) {
|
||||
$participantId = $index + 1;
|
||||
|
||||
if (null !== $participant->insurance) {
|
||||
// Exclude synthetic "keine Versicherung gewünscht" option from BPN XML
|
||||
if (null !== $participant->insurance && false === $participant->insurance->isNoInsurance()) {
|
||||
$insuranceMap[$participant->insurance->id][] = $participantId;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user