$name, 'pos' => $pos, 'active' => 1, 'default' => 0, ]); } function bslMakeUser(?int $sponsorId = null, ?int $levelId = null): User { return User::forceCreate([ 'email' => 'bsl-'.uniqid('', true).'@example.com', 'password' => bcrypt('secret'), 'lang' => 'de', 'm_level' => $levelId ?? 1, 'm_sponsor' => $sponsorId, 'active_date' => '2026-01-15', 'payment_account' => now()->addYear(), ]); } function bslMakeAbo(int $userId, string $isFor, string $startDate, int $status = 2): UserAbo { return UserAbo::create([ 'user_id' => $userId, 'member_id' => $userId, 'shopping_user_id' => 0, 'email' => 'bsl-abo-'.uniqid('', true).'@example.com', 'is_for' => $isFor, 'payone_userid' => 0, 'clearingtype' => 'cc', 'amount' => 5000, 'active' => true, 'status' => $status, 'abo_interval' => 5, 'start_date' => $startDate, 'last_date' => $startDate, 'next_date' => '2026-12-10', ]); } it('rankt neue Kundenabos pro Berater absteigend inklusive Linie', function (): void { $root = bslMakeUser(); $anna = bslMakeUser($root->id); $ben = bslMakeUser($anna->id); bslMakeAbo($anna->id, 'ot', '2026-06-10'); bslMakeAbo($ben->id, 'ot', '2026-06-05'); bslMakeAbo($ben->id, 'ot', '2026-06-20'); bslMakeAbo($ben->id, 'ot', '2026-05-10'); // anderer Monat, zaehlt nicht bslMakeAbo($anna->id, 'me', '2026-06-12'); // Eigenabo, zaehlt nicht $overview = app(BackofficeDashboardService::class)->overview($root, 6, 2026); $ranking = $overview['new_customer_abos']; expect($ranking)->toHaveCount(2) ->and($ranking[0]['user_id'])->toBe($ben->id) ->and($ranking[0]['abo_count'])->toBe(2) ->and($ranking[0]['total_abo_count'])->toBe(3) // inkl. Mai-Abo ->and($ranking[0]['line'])->toBe(2) ->and($ranking[1]['user_id'])->toBe($anna->id) ->and($ranking[1]['abo_count'])->toBe(1) ->and($ranking[1]['total_abo_count'])->toBe(1) ->and($ranking[1]['line'])->toBe(1); }); it('zaehlt Fuehrungskraefte-Abos erst ab Stufe Vertriebsleiter inklusive Linie und Summe', function (): void { $berater = bslMakeLevel('Berater', 3); $vertriebsleiter = bslMakeLevel('Vertriebsleiter', 6); $bronze = bslMakeLevel('Bronze Member', 7); $root = bslMakeUser(); $anna = bslMakeUser($root->id, $vertriebsleiter->id); $ben = bslMakeUser($root->id, $berater->id); $carla = bslMakeUser($anna->id, $bronze->id); bslMakeAbo($anna->id, 'me', '2026-06-01'); bslMakeAbo($anna->id, 'me', '2026-04-01'); bslMakeAbo($anna->id, 'me', '2026-03-01', 4); // storniert, zaehlt nicht bslMakeAbo($anna->id, 'ot', '2026-06-01'); // Kundenabo von Anna bslMakeAbo($carla->id, 'ot', '2026-05-01'); // Kundenabo von Carla bslMakeAbo($ben->id, 'me', '2026-06-01'); // unterhalb Vertriebsleiter $overview = app(BackofficeDashboardService::class)->overview($root, 6, 2026); $leaderAbos = $overview['leader_abos']; expect($leaderAbos['total'])->toBe(4) ->and($leaderAbos['total_own'])->toBe(2) ->and($leaderAbos['total_customer'])->toBe(2) ->and($leaderAbos['rows'])->toHaveCount(2) ->and($leaderAbos['rows'][0]['user_id'])->toBe($anna->id) ->and($leaderAbos['rows'][0]['own_abo_count'])->toBe(2) ->and($leaderAbos['rows'][0]['customer_abo_count'])->toBe(1) ->and($leaderAbos['rows'][0]['line'])->toBe(1) ->and($leaderAbos['rows'][0]['career_level'])->toBe('Vertriebsleiter') ->and($leaderAbos['rows'][1]['user_id'])->toBe($carla->id) ->and($leaderAbos['rows'][1]['own_abo_count'])->toBe(0) ->and($leaderAbos['rows'][1]['customer_abo_count'])->toBe(1) ->and($leaderAbos['rows'][1]['line'])->toBe(2); }); it('liefert eine leere Fuehrungskraefte-Liste, wenn die Stufe Vertriebsleiter nicht existiert', function (): void { $root = bslMakeUser(); bslMakeUser($root->id); $overview = app(BackofficeDashboardService::class)->overview($root, 6, 2026); expect($overview['leader_abos']['total'])->toBe(0) ->and($overview['leader_abos']['rows'])->toBe([]); });