*/ public function statsFor(Organisation $organisation): array { return [ 'members_count' => $this->membersCount($organisation), 'events_count' => $this->eventsCount($organisation), 'events_by_status' => $this->eventsByStatus($organisation), 'active_events_count' => $this->activeEventsCount($organisation), 'persons_count' => $this->personsCount($organisation), 'top_members' => $this->topMembers($organisation), 'recent_activity' => $this->recentActivity($organisation), ]; } private function membersCount(Organisation $organisation): int { return $organisation->users()->count(); } private function eventsCount(Organisation $organisation): int { return Event::withoutGlobalScope(OrganisationScope::class) ->where('organisation_id', $organisation->id) ->count(); } /** @return array */ private function eventsByStatus(Organisation $organisation): array { $counts = Event::withoutGlobalScope(OrganisationScope::class) ->where('organisation_id', $organisation->id) ->selectRaw('status, COUNT(*) as total') ->groupBy('status') ->pluck('total', 'status') ->map(fn ($count) => (int) $count) ->toArray(); $result = []; foreach (self::STATUSES as $status) { $result[$status] = $counts[$status] ?? 0; } return $result; } private function activeEventsCount(Organisation $organisation): int { return Event::withoutGlobalScope(OrganisationScope::class) ->where('organisation_id', $organisation->id) ->whereIn('status', self::ACTIVE_STATUSES) ->count(); } private function personsCount(Organisation $organisation): int { return Person::withoutGlobalScope(OrganisationScope::class) ->whereIn( 'event_id', Event::withoutGlobalScope(OrganisationScope::class) ->where('organisation_id', $organisation->id) ->select('id') ) ->count(); } /** @return array> */ private function topMembers(Organisation $organisation): array { return $organisation->users() ->orderBy('organisation_user.created_at', 'asc') ->limit(5) ->get() ->map(fn ($user) => [ 'id' => $user->id, 'name' => $user->full_name, 'email' => $user->email, 'avatar_url' => $user->avatar, 'role' => $user->pivot?->role, 'joined_at' => $user->pivot?->created_at?->toIso8601String(), ]) ->all(); } /** @return array> */ private function recentActivity(Organisation $organisation): array { return Activity::query() ->where('subject_type', (new Organisation)->getMorphClass()) ->where('subject_id', $organisation->id) ->with('causer') ->latest() ->limit(5) ->get() ->map(function (Activity $activity): array { /** @var \App\Models\User|null $causer */ $causer = $activity->causer; return [ 'id' => $activity->id, 'description' => $activity->description, 'causer_name' => $causer?->full_name, 'causer_avatar_url' => $causer?->avatar, 'subject_type' => $activity->subject_type ? class_basename($activity->subject_type) : null, 'subject_id' => $activity->subject_id, 'properties' => $activity->attribute_changes?->toArray() ?? [], 'created_at' => $activity->created_at?->toIso8601String(), ]; }) ->all(); } }