diff --git a/app/Resources/EventResource.php b/app/Resources/EventResource.php index c4858ff..4f22fc7 100644 --- a/app/Resources/EventResource.php +++ b/app/Resources/EventResource.php @@ -239,8 +239,8 @@ class EventResource extends JsonResource{ } public function getMultiplier() : float { - $earlyBirdEnd = $this->event->early_bird_end; - if ($earlyBirdEnd > now()) { + // Der Frühbucherpreis gilt einschließlich des ganzen Stichtags. + if (now() <= $this->event->early_bird_end->copy()->endOfDay()) { return 1; } diff --git a/app/Tasks/CloseEvent.php b/app/Tasks/CloseEvent.php index 575578d..e43b9a2 100644 --- a/app/Tasks/CloseEvent.php +++ b/app/Tasks/CloseEvent.php @@ -12,7 +12,8 @@ class CloseEvent implements CronTask { $eventRepository = new EventRepository(); /** @var Event $event */ foreach ($eventRepository->getAvailable(false) as $event) { - if ($event->registration_final_end <= $now ) { + // Der Anmeldeschluss gilt einschließlich des ganzen Tages: bis 23:59:59 darf man sich anmelden. + if ($now > $event->registration_final_end->copy()->endOfDay()) { $event->registration_allowed = false; $event->save(); } diff --git a/tests/Feature/EventDeadlineTest.php b/tests/Feature/EventDeadlineTest.php new file mode 100644 index 0000000..a6d0121 --- /dev/null +++ b/tests/Feature/EventDeadlineTest.php @@ -0,0 +1,109 @@ +tenant = Tenant::create([ + 'slug' => 'tv', + 'name' => 'Test', + 'email' => 't@example.com', + 'email_finance' => 'finance@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); + + DB::table('participation_fee_types')->insert(['slug' => 'fixed', 'name' => 'Fix']); + } + + public function test_am_anmeldeschluss_um_2359_bleibt_die_anmeldung_offen(): void + { + $event = $this->makeEvent(); + + $this->travelTo(new DateTime('2026-09-11 23:59:00')); + new CloseEvent()->handle(); + + $this->assertTrue($event->fresh()->registration_allowed); + } + + public function test_am_folgetag_schliesst_der_cron_die_anmeldung(): void + { + $event = $this->makeEvent(); + + $this->travelTo(new DateTime('2026-09-12 00:10:00')); + new CloseEvent()->handle(); + + $this->assertFalse($event->fresh()->registration_allowed); + } + + public function test_am_early_bird_stichtag_um_2359_gilt_der_fruehbucherpreis(): void + { + $event = $this->makeEvent(); + + $this->travelTo(new DateTime('2026-09-11 23:59:00')); + + $this->assertEqualsWithDelta(1.0, new EventResource($event)->getMultiplier(), 0.0001); + } + + public function test_am_tag_nach_dem_early_bird_stichtag_gilt_der_aufschlag(): void + { + $event = $this->makeEvent(); + + $this->travelTo(new DateTime('2026-09-12 00:00:01')); + + $this->assertEqualsWithDelta(1.2, new EventResource($event)->getMultiplier(), 0.0001); + } + + private function makeEvent(): Event + { + return Event::create([ + 'tenant' => $this->tenant->slug, + 'name' => 'Event', + 'identifier' => 'evt-' . uniqid(), + 'location' => 'Ort', + 'postal_code' => '00000', + 'email' => 'e@example.com', + 'start_date' => '2026-09-20', + 'end_date' => '2026-09-25', + 'early_bird_end' => '2026-09-11', + 'registration_final_end' => '2026-09-11', + 'early_bird_end_amount_increase' => 20, + 'registration_allowed' => true, + 'account_owner' => 'Owner', + 'account_iban' => 'DE00', + 'participation_fee_type' => 'fixed', + 'pay_per_day' => false, + 'pay_direct' => false, + ]); + } +}