Implemented additional event information

This commit is contained in:
2026-08-12 15:54:00 +02:00
parent 9581176a0c
commit e95de52768
16 changed files with 327 additions and 22 deletions
@@ -63,6 +63,84 @@ class EventParticipantRepository {
return $participants;
}
/**
* Gruppiert die (aktiven) Teilnehmenden nach ihren gewählten Teilnahmeoptionen. Je am Event definierter
* Frage entsteht eine Sektion mit Gruppen „Frage: Option" (in Definition-Reihenfolge); Teilnehmende ohne
* Antwort landen unter „Frage: (keine Angabe)". Ein Teilnehmer erscheint je Frage einmal, kann also über
* mehrere Fragen hinweg in mehreren Gruppen auftauchen. `$filter` liefert nur die eine passende Gruppe
* (für die E-Mail-Auflösung in ByGroupController).
*/
public function groupByParticipationOption(Event $event, Request $request, ?string $filter = null): array
{
$definitions = $event->participation_options ?? [];
$allParticipants = $this->getForList($event, $request);
$groups = [];
foreach ($definitions as $question) {
$questionKey = $question['key'] ?? null;
if ($questionKey === null) {
continue;
}
// Überschrift: bevorzugt der Titel, sonst die (längere) Frage bzw. der Key als Fallback.
$questionLabel = trim((string)($question['title'] ?? '')) !== ''
? $question['title']
: ($question['label'] ?? $questionKey);
$noAnswerKey = $questionLabel . ': (keine Angabe)';
// Vordefinierte Optionen in Reihenfolge: value => Gruppen-Key.
$definedGroupKeys = [];
foreach ($question['options'] ?? [] as $option) {
$definedGroupKeys[$option['value']] = $questionLabel . ': ' . ($option['label'] ?? $option['value']);
}
$collected = [];
foreach ($allParticipants as $participant) {
$answer = null;
foreach ($participant['participationOptions'] ?? [] as $selectedOption) {
if (($selectedOption['questionKey'] ?? null) === $questionKey) {
$answer = $selectedOption;
break;
}
}
if ($answer === null || ($answer['value'] ?? '') === '') {
$collected[$noAnswerKey][] = $participant;
continue;
}
// Bevorzugt die definierte Option; falls sie zwischenzeitlich entfernt wurde, den Snapshot nutzen.
$groupKey = $definedGroupKeys[$answer['value']] ?? ($questionLabel . ': ' . ($answer['valueLabel'] ?? $answer['value']));
$collected[$groupKey][] = $participant;
}
// Ausgabe je Frage: definierte Optionen zuerst (in Reihenfolge), dann Snapshot-Reste, „(keine Angabe)" ans Ende.
foreach ($definedGroupKeys as $groupKey) {
if (!empty($collected[$groupKey])) {
$groups[$groupKey] = $collected[$groupKey];
unset($collected[$groupKey]);
}
}
foreach ($collected as $groupKey => $participants) {
if ($groupKey === $noAnswerKey) {
continue;
}
$groups[$groupKey] = $participants;
}
if (!empty($collected[$noAnswerKey])) {
$groups[$noAnswerKey] = $collected[$noAnswerKey];
}
}
if ($filter !== null) {
return array_key_exists($filter, $groups) ? [$filter => $groups[$filter]] : [];
}
return $groups;
}
public function getSignedOffParticipants(Event $event, Request $request, ?string $filter = null) : array {
$allParticipants = $this->getForList($event, $request, true);
$participants = [];