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]); PaymentMethod::create(['slug' => PaymentMethod::PAYMENT_NOT_DEFINED]); 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']); 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_OMNIVOR, 'name' => 'Omnivor']); } private function createEventWithTransfer(array $config): 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, ]); AvailablePaymentMethod::create([ 'tenant' => $this->tenant->slug, 'slug' => PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION, 'name' => 'Überweisung', 'active' => true, 'configuration' => $config, ]); EventPaymentMethods::create([ 'event_id' => $event->id, 'slug' => PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION, 'configuration' => $config, ]); return $event; } private function createParticipant(Event $event, float $amount, string $paymentMethod = PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION): EventParticipant { return EventParticipant::create([ 'tenant' => $this->tenant->slug, 'event_id' => $event->id, 'identifier' => 'p-1', 'firstname' => 'Hans', 'lastname' => 'Muster', 'participation_type' => ParticipationType::PARTICIPATION_TYPE_PARTICIPANT, 'birthday' => '2000-01-01', 'address_1' => 'Weg 1', 'postcode' => '00000', 'city' => 'Stadt', 'email_1' => 'h@example.com', 'phone_1' => '123', 'arrival_date' => '2026-08-01', 'departure_date' => '2026-08-05', 'arrival_eating' => 0, 'departure_eating' => 0, 'amount' => $amount, 'payment_purpose' => 'Event - Beitrag Hans Muster', 'efz_status' => EfzStatus::EFZ_STATUS_NOT_CHECKED, 'payment_method' => $paymentMethod, 'swimming_permission' => SwimmingPermission::SWIMMING_PERMISSION_ALLOWED, 'first_aid_permission' => FirstAidPermission::FIRST_AID_PERMISSION_ALLOWED, 'eating_habit' => EatingHabit::EATING_HABIT_OMNIVOR, ]); } public function test_transfer_module_produces_giro_code(): void { $event = $this->createEventWithTransfer(['account_owner' => 'Kasse', 'iban' => 'DE-EVENT']); $participant = $this->createParticipant($event, 50.0); $module = $participant->paymentModule(); $this->assertInstanceOf(ProvidesGiroCode::class, $module); $giro = $module->giroCode($participant, $participant->paymentConfiguration()); $this->assertNotNull($giro); $this->assertNotSame('', $giro); } public function test_cash_module_provides_no_giro_code(): void { $event = $this->createEventWithTransfer(['account_owner' => 'Kasse', 'iban' => 'DE-EVENT']); $participant = $this->createParticipant($event, 50.0, PaymentMethod::PAYMENT_NOT_DEFINED); $this->assertNotInstanceOf(ProvidesGiroCode::class, $participant->paymentModule()); } public function test_payment_configuration_resolves_event_pivot_config(): void { $event = $this->createEventWithTransfer(['account_owner' => 'Kasse', 'iban' => 'DE-EVENT']); $participant = $this->createParticipant($event, 50.0); $config = $participant->paymentConfiguration(); $this->assertSame('DE-EVENT', $config['iban']); $this->assertSame('Kasse', $config['account_owner']); } public function test_payment_summary_builds_lines_from_resolved_config(): void { $event = $this->createEventWithTransfer(['account_owner' => 'Kasse', 'iban' => 'DE-EVENT']); $participant = $this->createParticipant($event, 50.0); $summary = $participant->paymentSummary(); $this->assertTrue($summary->hasPaymentInformation); $this->assertTrue($summary->showGiroCode); $byLabel = []; foreach ($summary->lines as $line) { $byLabel[$line['label']] = $line['value']; } $this->assertSame('DE-EVENT', $byLabel['IBAN']); } public function test_resource_exposes_payment_summary(): void { $event = $this->createEventWithTransfer(['account_owner' => 'Kasse', 'iban' => 'DE-EVENT']); $participant = $this->createParticipant($event, 50.0); $array = $participant->toResource()->toArray(request()); $this->assertTrue($array['paymentSummary']['hasPaymentInformation']); $this->assertTrue($array['paymentSummary']['showGiroCode']); } }