From 9e9ea0cfd547a73c303cd52daaf6abd4d44bf7f2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thomas=20G=C3=BCnrher?=
Date: Sun, 4 Oct 2026 14:36:15 +0200
Subject: [PATCH] Fixed bug selecting eating habits
---
.../Event/Actions/SignUp/SignUpCommand.php | 21 +++-
.../Event/Controllers/SignupController.php | 2 +-
.../SignUpForm/composables/useSignupForm.js | 8 +-
tests/Feature/InvoiceNumberingTest.php | 3 +-
tests/Feature/SignUpEatingHabitTest.php | 111 ++++++++++++++++++
tests/Feature/SignUpPaymentOptionsTest.php | 7 +-
version | 2 +-
7 files changed, 142 insertions(+), 12 deletions(-)
create mode 100644 tests/Feature/SignUpEatingHabitTest.php
diff --git a/app/Domains/Event/Actions/SignUp/SignUpCommand.php b/app/Domains/Event/Actions/SignUp/SignUpCommand.php
index e764bca..467c197 100644
--- a/app/Domains/Event/Actions/SignUp/SignUpCommand.php
+++ b/app/Domains/Event/Actions/SignUp/SignUpCommand.php
@@ -37,11 +37,7 @@ class SignUpCommand {
return $response;
}
- $eatingHabit = match ($this->request->eating_habit) {
- 'vegan' => EatingHabit::EATING_HABIT_VEGAN,
- 'vegetarian' => EatingHabit::EATING_HABIT_VEGETARIAN,
- default => EatingHabit::EATING_HABIT_OMNIVOR,
- };
+ $eatingHabit = $this->resolveEatingHabit();
$participantAge = new Age($this->request->birthday);
@@ -111,6 +107,21 @@ class SignUpCommand {
return $response;
}
+ /**
+ * Ernährungsweise auflösen. Übernommen wird nur ein Slug, den die Veranstaltung anbietet; ohne Angabe (z. B. bei
+ * der Kurzanmeldung) oder bei einem nicht angebotenen Wert gilt "Omnivor".
+ */
+ private function resolveEatingHabit(): string
+ {
+ $slug = $this->request->eating_habit;
+
+ if ($slug !== '' && $this->request->event->eatingHabits()->where('slug', $slug)->exists()) {
+ return $slug;
+ }
+
+ return EatingHabit::EATING_HABIT_OMNIVOR;
+ }
+
/**
* Badeerlaubnis auflösen. Volljährige brauchen keine Erlaubnis. Für Minderjährige gilt die getroffene Auswahl;
* fehlt sie -- weil die Veranstaltung die Badeerlaubnis gar nicht abfragt oder keine Wahl getroffen wurde --,
diff --git a/app/Domains/Event/Controllers/SignupController.php b/app/Domains/Event/Controllers/SignupController.php
index fa644f0..be6667c 100644
--- a/app/Domains/Event/Controllers/SignupController.php
+++ b/app/Domains/Event/Controllers/SignupController.php
@@ -143,7 +143,7 @@ class SignupController extends CommonController {
$registrationData['intolerances'],
$registrationData['medikamente'],
$tetanusVaccination,
- $registrationData['essgewohnheit'],
+ $registrationData['eatingHabit'] ?? '',
$registrationData['badeerlaubnis'],
$registrationData['first_aid'],
$registrationData['foto']['socialmedia'],
diff --git a/app/Domains/Event/Views/Partials/SignUpForm/composables/useSignupForm.js b/app/Domains/Event/Views/Partials/SignUpForm/composables/useSignupForm.js
index 18e5ada..8e4260b 100644
--- a/app/Domains/Event/Views/Partials/SignUpForm/composables/useSignupForm.js
+++ b/app/Domains/Event/Views/Partials/SignUpForm/composables/useSignupForm.js
@@ -13,8 +13,13 @@ export function useSignupForm(event, participantData) {
// Für die Aktion freigeschaltete Zahlungsmethoden; ist genau eine aktiv, wird sie vorausgewählt.
const activeMethods = (event.paymentMethods ?? []).filter(m => m.active)
+ // Vorbelegung mit der Ernährungsweise aus dem Profil, sofern die Veranstaltung sie anbietet, sonst die erste Option.
+ const eatingHabitSlugs = (event.eatingHabits ?? []).map(h => h.data.slug)
+
const formData = reactive({
- eatingHabit: 'EATING_HABIT_VEGAN',
+ eatingHabit: eatingHabitSlugs.includes(participantData.eating_habit)
+ ? participantData.eating_habit
+ : (eatingHabitSlugs[0] ?? ''),
paymentMethod: activeMethods.length === 1 ? activeMethods[0].slug : null,
paymentOptions: {},
// Antworten auf die event-spezifischen Teilnahmeoptionen: { [question.key]: option.value }
@@ -53,7 +58,6 @@ export function useSignupForm(event, participantData) {
intolerances: participantData.intolerances ?? '',
medikamente: participantData.medications ?? '',
tetanusVaccination: participantData.tetanusVaccination ?? '',
- essgewohnheit: 'vegetarian',
anmerkungen: '',
summary_information_correct: false,
summary_accept_terms: false,
diff --git a/tests/Feature/InvoiceNumberingTest.php b/tests/Feature/InvoiceNumberingTest.php
index 9dd7b14..522ef64 100644
--- a/tests/Feature/InvoiceNumberingTest.php
+++ b/tests/Feature/InvoiceNumberingTest.php
@@ -40,6 +40,7 @@ class InvoiceNumberingTest extends TestCase
DB::table('participation_fee_types')->insert(['slug' => 'fixed', 'name' => 'Fix']);
EatingHabit::create(['slug' => EatingHabit::EATING_HABIT_VEGAN, 'name' => 'Vegan']);
EatingHabit::create(['slug' => EatingHabit::EATING_HABIT_VEGETARIAN, 'name' => 'Vegetarisch']);
+ EatingHabit::create(['slug' => EatingHabit::EATING_HABIT_OMNIVOR, 'name' => 'Omnivor']);
ParticipationType::create(['slug' => ParticipationType::PARTICIPATION_TYPE_PARTICIPANT, 'name' => 'Teilnehmende']);
PaymentMethod::create(['slug' => PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION]);
EfzStatus::create(['slug' => EfzStatus::EFZ_STATUS_NOT_CHECKED, 'name' => 'Nicht geprüft']);
@@ -167,7 +168,7 @@ class InvoiceNumberingTest extends TestCase
$event, null, $firstname, 'Muster', null, ParticipationType::PARTICIPATION_TYPE_PARTICIPANT,
$this->wildeMoehre, new DateTime('2000-01-01'), 'Weg 1', null, '00000', 'Stadt',
strtolower($firstname) . '@example.com', '123', null, null, null, null, null, null, null,
- 'vegan', null, null, false, false, false, false, false,
+ '', null, null, false, false, false, false, false,
new DateTime('2026-07-16'), new DateTime('2026-07-16'), 0, 0, null,
new Amount(50.0, 'Euro'), PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION,
))->execute();
diff --git a/tests/Feature/SignUpEatingHabitTest.php b/tests/Feature/SignUpEatingHabitTest.php
new file mode 100644
index 0000000..0cb8246
--- /dev/null
+++ b/tests/Feature/SignUpEatingHabitTest.php
@@ -0,0 +1,111 @@
+tenant = Tenant::create([
+ 'slug' => 'tv', 'name' => 'Test', 'email' => 't@example.com', 'email_finance' => 'f@example.com',
+ 'url' => 'test.local', 'account_name' => 'Test e.V.', 'account_iban' => 'DE00', 'account_bic' => 'XY',
+ 'city' => 'Stadt', 'postcode' => '00000', 'is_active_local_group' => true, 'has_active_instance' => true,
+ ]);
+ app()->instance('tenant', $this->tenant);
+
+ PaymentMethod::create(['slug' => PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION]);
+ DB::table('participation_fee_types')->insert(['slug' => 'FIXED', 'name' => 'Fixed', 'created_at' => now(), 'updated_at' => now()]);
+ ParticipationType::create(['slug' => ParticipationType::PARTICIPATION_TYPE_PARTICIPANT, 'name' => 'Teilnehmende']);
+ EfzStatus::create(['slug' => EfzStatus::EFZ_STATUS_NOT_CHECKED, 'name' => 'Nicht geprüft']);
+ EfzStatus::create(['slug' => EfzStatus::EFZ_STATUS_NOT_REQUIRED, 'name' => 'Nicht erforderlich']);
+ SwimmingPermission::create(['slug' => SwimmingPermission::SWIMMING_PERMISSION_ALLOWED, 'name' => 'Darf baden', 'short' => 'Erteilt']);
+ FirstAidPermission::create(['slug' => FirstAidPermission::FIRST_AID_PERMISSION_ALLOWED, 'name' => 'Zugestimmt', 'description' => '']);
+ EatingHabit::create(['slug' => EatingHabit::EATING_HABIT_VEGAN, 'name' => 'Vegan']);
+ EatingHabit::create(['slug' => EatingHabit::EATING_HABIT_VEGETARIAN, 'name' => 'Vegetarisch']);
+ EatingHabit::create(['slug' => EatingHabit::EATING_HABIT_OMNIVOR, 'name' => 'Omnivor']);
+ }
+
+ private function createEvent(array $eatingHabitSlugs): Event
+ {
+ $event = Event::create([
+ 'tenant' => $this->tenant->slug, 'name' => 'Event', 'identifier' => 'evt-1', 'location' => 'Ort',
+ 'postal_code' => '00000', 'email' => 'e@example.com', 'start_date' => '2026-08-01', 'end_date' => '2026-08-05',
+ 'early_bird_end' => '2026-07-01', 'registration_final_end' => '2026-07-20', 'early_bird_end_amount_increase' => 0,
+ 'account_owner' => 'Owner', 'account_iban' => 'DE00', 'participation_fee_type' => 'FIXED',
+ 'pay_per_day' => false, 'pay_direct' => false,
+ ]);
+ $event->eatingHabits()->attach(EatingHabit::whereIn('slug', $eatingHabitSlugs)->pluck('id')->all());
+
+ return $event;
+ }
+
+ private function signUp(Event $event, string $eatingHabit): string
+ {
+ $request = new SignUpRequest(
+ $event, null, 'Hans', 'Muster', null, ParticipationType::PARTICIPATION_TYPE_PARTICIPANT,
+ $this->tenant, new \DateTime('2000-01-01'), 'Weg 1', null, '00000', 'Stadt',
+ 'h@example.com', '123', null, null, null, null, null, null, null,
+ $eatingHabit, null, null, false, false, false, false, false,
+ new \DateTime('2026-08-01'), new \DateTime('2026-08-05'), 0, 0, null,
+ new Amount(50.0, ' Euro'), PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION, [],
+ );
+
+ $response = new SignUpCommand($request)->execute();
+ $this->assertTrue($response->success);
+
+ return $response->participant->fresh()->eating_habit;
+ }
+
+ public function test_chosen_vegan_is_stored(): void
+ {
+ $event = $this->createEvent([EatingHabit::EATING_HABIT_VEGAN, EatingHabit::EATING_HABIT_VEGETARIAN]);
+
+ $this->assertSame(EatingHabit::EATING_HABIT_VEGAN, $this->signUp($event, EatingHabit::EATING_HABIT_VEGAN));
+ }
+
+ public function test_chosen_vegetarian_is_stored(): void
+ {
+ $event = $this->createEvent([EatingHabit::EATING_HABIT_VEGAN, EatingHabit::EATING_HABIT_VEGETARIAN]);
+
+ $this->assertSame(EatingHabit::EATING_HABIT_VEGETARIAN, $this->signUp($event, EatingHabit::EATING_HABIT_VEGETARIAN));
+ }
+
+ public function test_habit_not_offered_by_event_falls_back_to_omnivor(): void
+ {
+ $event = $this->createEvent([EatingHabit::EATING_HABIT_VEGETARIAN]);
+
+ $this->assertSame(EatingHabit::EATING_HABIT_OMNIVOR, $this->signUp($event, EatingHabit::EATING_HABIT_VEGAN));
+ }
+
+ public function test_empty_habit_falls_back_to_omnivor(): void
+ {
+ $event = $this->createEvent([EatingHabit::EATING_HABIT_VEGAN]);
+
+ $this->assertSame(EatingHabit::EATING_HABIT_OMNIVOR, $this->signUp($event, ''));
+ }
+}
diff --git a/tests/Feature/SignUpPaymentOptionsTest.php b/tests/Feature/SignUpPaymentOptionsTest.php
index 1a8ab47..1466f6c 100644
--- a/tests/Feature/SignUpPaymentOptionsTest.php
+++ b/tests/Feature/SignUpPaymentOptionsTest.php
@@ -48,13 +48,16 @@ class SignUpPaymentOptionsTest extends TestCase
private function createEvent(): Event
{
- return Event::create([
+ $event = Event::create([
'tenant' => $this->tenant->slug, 'name' => 'Event', 'identifier' => 'evt-1', 'location' => 'Ort',
'postal_code' => '00000', 'email' => 'e@example.com', 'start_date' => '2026-08-01', 'end_date' => '2026-08-05',
'early_bird_end' => '2026-07-01', 'registration_final_end' => '2026-07-20', 'early_bird_end_amount_increase' => 0,
'account_owner' => 'Owner', 'account_iban' => 'DE00', 'participation_fee_type' => 'FIXED',
'pay_per_day' => false, 'pay_direct' => false,
]);
+ $event->eatingHabits()->attach(EatingHabit::where('slug', EatingHabit::EATING_HABIT_VEGAN)->first()->id);
+
+ return $event;
}
private function signUpRequest(Event $event, array $paymentOptions): SignUpRequest
@@ -63,7 +66,7 @@ class SignUpPaymentOptionsTest extends TestCase
$event, null, 'Hans', 'Muster', null, ParticipationType::PARTICIPATION_TYPE_PARTICIPANT,
$this->tenant, new \DateTime('2000-01-01'), 'Weg 1', null, '00000', 'Stadt',
'h@example.com', '123', null, null, null, null, null, null, null,
- 'vegan', null, null, false, false, false, false, false,
+ EatingHabit::EATING_HABIT_VEGAN, null, null, false, false, false, false, false,
new \DateTime('2026-08-01'), new \DateTime('2026-08-05'), 0, 0, null,
new Amount(50.0, ' Euro'), PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION, $paymentOptions,
);
diff --git a/version b/version
index 0216ba3..8540cb1 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-4.10.2
+4.10.3