response = new UpdateParticipantResponse(); $p = clone($this->request->participant); $p->firstname = $this->request->firstname; $p->lastname = $this->request->lastname; $p->nickname = $this->request->nickname; $p->address_1 = $this->request->address_1; $p->address_2 = $this->request->address_2; $p->postcode = $this->request->postcode; $p->city = $this->request->city; $p->local_group = $this->request->localgroup; $p->birthday = DateTime::createFromFormat('Y-m-d', $this->request->birthday); $p->email_1 = $this->request->email_1; $p->phone_1 = $this->request->phone_1; $p->contact_person = $this->request->contact_person; $p->email_2 = $this->request->email_2; $p->phone_2 = $this->request->phone_2; $p->arrival_date = DateTime::createFromFormat('Y-m-d', $this->request->arrival); $p->departure_date = DateTime::createFromFormat('Y-m-d', $this->request->departure); $p->participation_type = $this->request->participationType; $p->eating_habit = $this->request->eatingHabit; $p->payment_method = $this->request->paymentMethod; $p->allergies = $this->request->allergies; $p->intolerances = $this->request->intolerances; $p->medications = $this->request->medications; $p->first_aid_permission = $this->request->extendedFirstAid; $p->swimming_permission = $this->request->swimmingPermission; $p->tetanus_vaccination = $this->request->tetanusVaccination !== null ? DateTime::createFromFormat('Y-m-d', $this->request->tetanusVaccination) : null; $p->notes = $this->request->notes; $p->amount_paid = Amount::fromString($this->request->amountPaid); $p->amount = Amount::fromString($this->request->amountExpected); $p->efz_status = $this->request->cocStatus; if ( MissingPaymentProvider::calculateMissingPayment(amountPaid: $p->amount_paid, amountToPay: $p->amount)->getAmount() !== MissingPaymentProvider::calculateMissingPayment(amountPaid: $this->request->participant->amount_paid, amountToPay: $this->request->participant->amount)->getAmount() ) { $this->handleAmountChanges($p); } if ( $p->efz_status !== $this->request->participant->efz_status ) { $this->handleCocStatusChange($p); } $p->save(); if ($this->request->participationOptions !== null) { $this->syncParticipationOptions($p); } if ($this->request->selectedAddons !== null) { $this->syncAddons($p); } $this->response->success = true; $this->response->participant = $p; return $this->response; } /** * Ersetzt die zugeordneten Zusätze (Event-Addons) anhand der Auswahl. Bewusst **ohne Preis/Betrag** * (amount 0): der Teilnahmebeitrag wird in den Details ohnehin manuell gesetzt. Es wird nur der Titel als * Snapshot gespeichert, damit die Zuordnung sichtbar bleibt. */ private function syncAddons(EventParticipant $participant): void { $participant->selectedAddons()->delete(); $selection = $this->request->selectedAddons ?? []; foreach ($participant->event?->addons ?? [] as $addon) { $key = $addon['key'] ?? null; if ($key === null || empty($selection[$key])) { continue; } $participant->selectedAddons()->create([ 'tenant' => $participant->tenant, 'event_id' => $participant->event_id, 'addon_key' => $key, 'title' => $addon['title'] ?? $key, 'price' => 0, 'flat' => (bool)($addon['flat'] ?? false), 'days' => 0, 'amount' => 0, ]); } } /** * Ersetzt die zugeordneten Teilnahmeoptionen anhand der übergebenen Antworten. Nachträgliche Zuordnung im * Back-Office ist lückenlos möglich: nur gegen die Event-Definition gültige Antworten werden gespeichert, * leere/entfallene Antworten werden abgeräumt. Frage-/Options-Label werden als Snapshot mitgeschrieben. */ private function syncParticipationOptions(EventParticipant $participant): void { $participant->selectedOptions()->delete(); $answers = $this->request->participationOptions ?? []; foreach ($participant->event?->participation_options ?? [] as $question) { $key = $question['key'] ?? null; if ($key === null) { continue; } $value = $answers[$key] ?? null; if ($value === null || $value === '') { continue; } $option = null; foreach ($question['options'] ?? [] as $candidate) { if (($candidate['value'] ?? null) === $value) { $option = $candidate; break; } } if ($option === null) { continue; } $label = trim((string)($question['label'] ?? '')); $participant->selectedOptions()->create([ 'tenant' => $participant->tenant, 'event_id' => $participant->event_id, 'question_key' => $key, 'question_label' => $label !== '' ? $label : ($question['title'] ?? $key), 'value' => $value, 'value_label' => $option['label'] ?? $value, ]); } } private function handleAmountChanges(EventParticipant $participant) { $this->response->amountPaid = $participant->amount_paid; $this->response->amountExpected = $participant->amount; $amountToPay = MissingPaymentProvider::calculateMissingPayment( amountPaid: $participant->amount_paid, amountToPay: $participant->amount, ); switch (true) { case $amountToPay->getAmount() > 0: Mail::to($participant->email_1)->send(new ParticipantPaymentMissingPaymentMail( participant: $participant, )); if ($participant->email_2 !== null) { Mail::to($participant->email_2)->send(new ParticipantPaymentMissingPaymentMail( participant: $participant, )); } break; case $amountToPay->getAmount() < 0: Mail::to($participant->email_1)->send(new ParticipantPaymentOverpaidMail( participant: $participant, )); if ($participant->email_2 !== null) { Mail::to($participant->email_2)->send(new ParticipantPaymentOverpaidMail( participant: $participant, )); } break; default: Mail::to($participant->email_1)->send(new ParticipantPaymentPaidMail( participant: $participant, )); if ($participant->email_2 !== null) { Mail::to($participant->email_2)->send(new ParticipantPaymentPaidMail( participant: $participant, )); } } } private function handleCocStatusChange(EventParticipant $participant) { $this->response->cocStatus = $participant->efzStatus()->first(); switch ($participant->efzStatus()->first()->slug) { case EfzStatus::EFZ_STATUS_CHECKED_VALID: case EfzStatus::EFZ_STATUS_NOT_REQUIRED: Mail::to($participant->email_1)->send(new ParticipantCocCompleteMail( participant: $participant, )); break; case EfzStatus::EFZ_STATUS_CHECKED_INVALID: Mail::to($participant->email_1)->send(new ParticipantCocInvalidMail( participant: $participant, )); break; } } }