date('start_date', now()->subDays(30)); $endDate = $request->date('end_date', now()); // Overview Statistics $stats = [ 'total_issues' => Issue::count(), 'open_issues' => Issue::open()->count(), 'closed_issues' => Issue::closed()->count(), 'overdue_issues' => Issue::overdue()->count(), ]; // Issues by Status $issuesByStatus = Issue::select('status', DB::raw('count(*) as count')) ->groupBy('status') ->get() ->mapWithKeys(fn($item) => [$item->status => $item->count]); // Issues by Priority $issuesByPriority = Issue::select('priority', DB::raw('count(*) as count')) ->groupBy('priority') ->get() ->mapWithKeys(fn($item) => [$item->priority => $item->count]); // Issues by Type $issuesByType = Issue::select('issue_type', DB::raw('count(*) as count')) ->groupBy('issue_type') ->get() ->mapWithKeys(fn($item) => [$item->issue_type => $item->count]); // Issues Created Over Time (last 30 days) $issuesCreatedOverTime = Issue::select( DB::raw('DATE(created_at) as date'), DB::raw('count(*) as count') ) ->whereBetween('created_at', [$startDate, $endDate]) ->groupBy('date') ->orderBy('date') ->get(); // Issues Closed Over Time (last 30 days) $issuesClosedOverTime = Issue::select( DB::raw('DATE(closed_at) as date'), DB::raw('count(*) as count') ) ->whereNotNull('closed_at') ->whereBetween('closed_at', [$startDate, $endDate]) ->groupBy('date') ->orderBy('date') ->get(); // Assignee Performance $assigneePerformance = User::select('users.id', 'users.name') ->leftJoin('issues', 'users.id', '=', 'issues.assigned_to_user_id') ->selectRaw('count(issues.id) as total_assigned') ->selectRaw('sum(case when issues.status = ? then 1 else 0 end) as completed', [Issue::STATUS_CLOSED]) ->selectRaw('sum(case when issues.due_date < NOW() and issues.status != ? then 1 else 0 end) as overdue', [Issue::STATUS_CLOSED]) ->groupBy('users.id', 'users.name') ->having('total_assigned', '>', 0) ->orderByDesc('total_assigned') ->limit(10) ->get() ->map(function ($user) { $user->completion_rate = $user->total_assigned > 0 ? round(($user->completed / $user->total_assigned) * 100, 1) : 0; return $user; }); // Time Tracking Metrics $timeTrackingMetrics = Issue::selectRaw(' sum(estimated_hours) as total_estimated, sum(actual_hours) as total_actual, avg(estimated_hours) as avg_estimated, avg(actual_hours) as avg_actual ') ->whereNotNull('estimated_hours') ->first(); // Top Labels Used $topLabels = DB::table('issue_labels') ->select('issue_labels.id', 'issue_labels.name', 'issue_labels.color', DB::raw('count(issue_label_pivot.issue_id) as usage_count')) ->leftJoin('issue_label_pivot', 'issue_labels.id', '=', 'issue_label_pivot.issue_label_id') ->groupBy('issue_labels.id', 'issue_labels.name', 'issue_labels.color') ->having('usage_count', '>', 0) ->orderByDesc('usage_count') ->limit(10) ->get(); // Average Resolution Time (days) $avgResolutionTime = Issue::whereNotNull('closed_at') ->selectRaw('avg(TIMESTAMPDIFF(DAY, created_at, closed_at)) as avg_days') ->value('avg_days'); // Recent Activity (last 10 issues) $recentIssues = Issue::with(['creator', 'assignee']) ->latest() ->limit(10) ->get(); return view('admin.issue-reports.index', compact( 'stats', 'issuesByStatus', 'issuesByPriority', 'issuesByType', 'issuesCreatedOverTime', 'issuesClosedOverTime', 'assigneePerformance', 'timeTrackingMetrics', 'topLabels', 'avgResolutionTime', 'recentIssues', 'startDate', 'endDate' )); } }