previousHttpHost = $_SERVER['HTTP_HOST'] ?? null; $_SERVER['HTTP_HOST'] = config('domains.domains.crm.host'); $this->refreshApplication(); $this->artisan('migrate'); }); afterEach(function () { if ($this->previousHttpHost === null) { unset($_SERVER['HTTP_HOST']); } else { $_SERVER['HTTP_HOST'] = $this->previousHttpHost; } }); function payoutAdmin(): User { $account = UserAccount::create(['first_name' => 'Ad', 'last_name' => 'Min']); return User::forceCreate([ 'email' => 'admin-'.uniqid('', true).'@example.com', 'password' => bcrypt('secret'), 'lang' => 'de', 'admin' => 2, 'account_id' => $account->id, 'payment_account' => now()->addYear(), ]); } function challengePayload(array $overrides = []): array { return array_merge([ 'name' => 'Recruiting-Challenge Okt-Jan', 'qualification_start' => '01.10.2026', 'qualification_end' => '31.01.2027', 'calculation_end' => '28.02.2027', 'points_partner_onetime' => 1, 'points_abo_onetime' => 0, 'min_direct_partners' => 0, 'min_customer_abos' => 0, 'max_winners' => 3, 'amount_per_partner' => '50', 'bonus_rank_1' => '300', 'bonus_rank_2' => '200', 'bonus_rank_3' => '', 'include_sales_points' => '0', 'status' => 1, ], $overrides); } it('speichert Praemienfelder und den Umsatzpunkte-Schalter beim Anlegen', function () { $this->actingAs(payoutAdmin()); $this->post(route('admin_incentive_store'), challengePayload())->assertRedirect(route('admin_incentives')); $incentive = Incentive::where('name', 'Recruiting-Challenge Okt-Jan')->firstOrFail(); expect((float) $incentive->amount_per_partner)->toBe(50.0) ->and($incentive->rankBonuses())->toBe([1 => 300.0, 2 => 200.0]) ->and($incentive->bonus_rank_3)->toBeNull() ->and($incentive->includesSalesPoints())->toBeFalse() ->and($incentive->hasCashPayout())->toBeTrue(); }); it('setzt leere Betragsfelder beim Bearbeiten auf NULL und den Schalter wieder an', function () { $this->actingAs(payoutAdmin()); $incentive = Incentive::factory()->create([ 'amount_per_partner' => 50, 'bonus_rank_1' => 300, 'include_sales_points' => false, ]); $this->post(route('admin_incentive_update', [$incentive->id]), challengePayload([ 'amount_per_partner' => '', 'bonus_rank_1' => '', 'bonus_rank_2' => '', 'include_sales_points' => '1', ]))->assertRedirect(route('admin_incentive_show', [$incentive->id])); $incentive->refresh(); expect($incentive->amount_per_partner)->toBeNull() ->and($incentive->hasCashPayout())->toBeFalse() ->and($incentive->includesSalesPoints())->toBeTrue(); }); it('lehnt negative Betraege ab', function () { $this->actingAs(payoutAdmin()); $this->from(route('admin_incentive_create')) ->post(route('admin_incentive_store'), challengePayload(['amount_per_partner' => '-5'])) ->assertSessionHasErrors('amount_per_partner'); }); it('laedt die Auszahlungsliste als XLSX herunter', function () { Excel::fake(); $this->actingAs(payoutAdmin()); $incentive = Incentive::factory()->create([ 'slug' => 'recruiting-challenge', 'amount_per_partner' => 50, 'bonus_rank_1' => 300, 'max_winners' => 3, 'include_sales_points' => false, ]); $account = UserAccount::create(['first_name' => 'Anna', 'last_name' => 'Berater']); $winner = User::forceCreate([ 'email' => 'winner-'.uniqid('', true).'@example.com', 'password' => bcrypt('secret'), 'lang' => 'de', 'account_id' => $account->id, ]); IncentiveParticipant::factory()->create([ 'incentive_id' => $incentive->id, 'user_id' => $winner->id, 'qualified_partners' => 3, 'total_points' => 3, 'is_qualified' => true, 'rank' => 1, ]); $this->get(route('admin_incentive_payout_export', [$incentive->id]))->assertOk(); Excel::assertDownloaded('incentive-recruiting-challenge-auszahlung-'.now()->format('Y-m-d').'.xlsx', function ($export) { $rows = $export->collection(); return $rows->count() === 1 && $rows[0][2] === 'Anna Berater' && $rows[0][9] === 450.0; }); }); it('zeigt auf der Admin-Detailseite Export-Button und Praemienspalte nur bei Geldpraemie', function () { $this->actingAs(payoutAdmin()); $challenge = Incentive::factory()->create(['amount_per_partner' => 50, 'include_sales_points' => false]); $montenegro = Incentive::factory()->create(); $this->get(route('admin_incentive_show', [$challenge->id])) ->assertOk() ->assertSee('id="incentive-payout-export"', false) ->assertSee(__('incentive.payout_total')); $this->get(route('admin_incentive_show', [$montenegro->id])) ->assertOk() ->assertDontSee('id="incentive-payout-export"', false); });