fix: key participant status like the participants they belong to

This commit is contained in:
2026-09-14 15:13:21 +02:00
parent 67c685f6c1
commit a3e8c737de
3 changed files with 146 additions and 4 deletions
@@ -96,7 +96,7 @@ class BookingPayloadBuilder
foreach ($bookingData->participants as $index => $participant) {
$participantPayload = [
'@id' => $index + 1,
'status' => $bookingData->participantsStatus[$index],
'status' => $bookingData->participantsStatus[$index] ?? null,
...$participant->toPayload(),
];
+37 -3
View File
@@ -49,11 +49,13 @@ class BookingParser extends AbstractParser
$booking->applicant = $this->parsePersonalData($node->filterXPath('//anmelder'));
$participantsStatus = $this->getArrayValue($node->filterXPath('//status_teilnehmer'), '/');
$booking->participantsStatus = array_combine(range(0, count($participantsStatus) - 1), $participantsStatus);
$booking->participants = $this->parseParticipants($node->filterXPath('//teilnehmerliste/teilnehmer'));
$booking->participantsStatus = $this->mapParticipantsStatus(
array_keys($booking->participants),
$this->getArrayValue($node->filterXPath('//status_teilnehmer'), '/'),
);
$paymentData = $node->filterXPath('//zahlung');
$booking->paymentId = $this->getAttrOrNullValue($paymentData, 'idzahlungsart');
$booking->paymentLabel = $this->getAttrOrNullValue($paymentData, 'bezeichnung');
@@ -129,6 +131,38 @@ class BookingParser extends AbstractParser
return $participants;
}
/**
* Maps the positional status_teilnehmer list onto the participant keys.
*
* BusPro sends the statuses as a slash-separated list in teilnehmerliste order and
* without ids, while participants are keyed by "BusPro participant id - 1" (see
* parseParticipants()). Zipping the two in document order keeps both arrays on the same
* keys even when the ids are not contiguous from 1, which BookingPayloadBuilder relies
* on when it reads participantsStatus[$index] while iterating participants, and which
* gates editing in ParticipantController::isParticipantCanceled().
*
* Surplus entries on either side are dropped rather than shifting the remaining ones
* onto the wrong participant.
*
* @param list<int> $participantKeys Participant array keys, in document order
* @param list<string> $statusValues Status codes, in document order
*
* @return array<int, string>
*/
private function mapParticipantsStatus(array $participantKeys, array $statusValues): array
{
$count = min(count($participantKeys), count($statusValues));
if (0 === $count) {
return [];
}
return array_combine(
array_slice($participantKeys, 0, $count),
array_slice($statusValues, 0, $count),
);
}
private function parsePersonalData(Crawler $node): PersonalData
{
$personalData = new PersonalData();