month = $month; $this->year = $year; $date = Carbon::parse($year . '-' . $month . '-1'); $this->startDate = $date->format('Y-m-d H:i:s'); $this->endDate = $date->endOfMonth()->format('Y-m-d H:i:s'); \Log::info("BusinessUserRepository: Start Date: " . $this->startDate); \Log::info("BusinessUserRepository: End Date: " . $this->endDate); } /** * Lädt Root-User mit optimiertem Eager Loading und Caching */ public function getRootUsers(): Collection { $cacheKey = "root_users_{$this->month}_{$this->year}"; //root hat keinen parent m_sponsor, hat return cache()->remember($cacheKey, 3600, function () { return User::with([ 'account', 'user_level', 'userBusiness' => function ($query) { $query->where('month', $this->month) ->where('year', $this->year); } ]) ->select('users.*') ->where('users.deleted_at', '=', null) ->where('users.id', '!=', 1) ->where('users.admin', '<', 4) ->where('users.m_level', '!=', null) ->where('users.m_sponsor', '=', null) ->where('users.payment_account', '!=', null) ->where('users.active_date', '<=', $this->endDate) ->where('users.payment_account', '>', $this->endDate) ->get(); }); } /** * Lädt User ohne Parent-Zuordnung (Lazy Loading für Memory-Effizienz) */ public function getParentlessUsers(array $excludeUserIds = []): LazyCollection { $query = User::with([ 'account', 'user_level', 'userBusiness' => function ($query) { $query->where('month', $this->month) ->where('year', $this->year); } ]) ->select('users.*') ->where('users.deleted_at', '=', null) ->where('users.id', '!=', 1) ->where('users.admin', '<', 4) ->where('users.payment_account', '!=', null) ->where('users.active_date', '<=', $this->endDate); if (!empty($excludeUserIds)) { $query->whereNotIn('users.id', $excludeUserIds); } return $query->lazy(100); } /** * Lädt einen einzelnen User mit Relations und Caching */ public function getUserWithRelations(int $userId): ?User { $cacheKey = "user_relations_{$userId}_{$this->month}_{$this->year}"; return cache()->remember($cacheKey, 1800, function () use ($userId) { \Log::debug("BusinessUserRepository: Loading user {$userId} with relations (cache miss)"); return User::with([ 'account', 'user_level', 'userBusiness' => function ($query) { $query->where('month', $this->month) ->where('year', $this->year); } ])->find($userId); }); } /** * Lädt Sponsor für einen User */ public function getSponsorForUser(int $userId): ?User { $user = $this->getUserWithRelations($userId); if (!$user || !$user->m_sponsor) { return null; } return $this->getUserWithRelations($user->m_sponsor); } /** * Prüft ob gespeicherte Struktur existiert (mit Caching) */ public function getStoredStructure(): ?UserBusinessStructure { $cacheKey = "stored_structure_{$this->month}_{$this->year}"; return cache()->remember($cacheKey, 7200, function () { \Log::debug("BusinessUserRepository: Loading stored structure (cache miss)"); $structure = UserBusinessStructure::where('year', $this->year) ->where('month', $this->month) ->first(); return ($structure && $structure->completed) ? $structure : null; }); } /** * Lädt User-IDs aus gespeicherter Struktur */ public function getUserIdsFromStoredStructure(UserBusinessStructure $structure): array { $userIds = []; if ($structure->structure) { $this->extractUserIdsFromStructure((array) $structure->structure, $userIds); } if ($structure->parentless) { foreach ($structure->parentless as $item) { $userIds[] = $item->user_id; } } return array_unique($userIds); } /** * Rekursive Extraktion von User-IDs aus Struktur */ private function extractUserIdsFromStructure(array $structure, array &$userIds): void { foreach ($structure as $item) { $userIds[] = $item->user_id; if (isset($item->parents) && is_array($item->parents)) { $this->extractUserIdsFromStructure($item->parents, $userIds); } } } /** * Löscht alle Cache-Einträge für den aktuellen Monat/Jahr */ public function clearCache(): void { $cacheKeys = [ "root_users_{$this->month}_{$this->year}", "stored_structure_{$this->month}_{$this->year}" ]; foreach ($cacheKeys as $key) { cache()->forget($key); \Log::info("BusinessUserRepository: Cache cleared for key: {$key}"); } } /** * Batch-Loading für User-Kollektionen */ public function loadUsersInBatches(array $userIds, int $batchSize = 100): \Generator { $chunks = array_chunk($userIds, $batchSize); foreach ($chunks as $chunk) { yield User::with([ 'account', 'user_level', 'userBusiness' => function ($query) { $query->where('month', $this->month) ->where('year', $this->year); } ]) ->whereIn('id', $chunk) ->get() ->keyBy('id'); } } }