acct_type, UserActions::ViewGlobalReports)) { return ResponseHelper::returnUnauthorized(); } $type = $request->input('type', 'population'); $year = (int) $request->input('year', date('Y')); $data = match ($type) { 'population' => $this->populationReport(), 'households' => $this->householdsReport(), 'documents' => $this->documentsReport($year), 'blotters' => $this->blottersReport($year), 'budget' => $this->budgetReport($year), 'projects' => $this->projectsReport($year), default => [], }; return response()->json(['success' => true, 'data' => $data]); } private function populationReport(): array { $total = Resident::count(); $active = Resident::where('is_active', true)->count(); $voters = Resident::where('voter_status', true)->count(); $genderBreakdown = Resident::select('gender', DB::raw('count(*) as count')) ->whereNotNull('gender') ->groupBy('gender') ->pluck('count', 'gender') ->toArray(); $civilBreakdown = Resident::select('civil_status', DB::raw('count(*) as count')) ->whereNotNull('civil_status') ->groupBy('civil_status') ->pluck('count', 'civil_status') ->toArray(); $purokBreakdown = Resident::select('purok', DB::raw('count(*) as count')) ->whereNotNull('purok') ->groupBy('purok') ->orderBy('purok') ->pluck('count', 'purok') ->toArray(); // Age groups $now = Carbon::now(); $ageGroups = [ '0–12 (Children)' => [0, 12], '13–17 (Youth)' => [13, 17], '18–30 (Young Adult)' => [18, 30], '31–59 (Adult)' => [31, 59], '60+ (Senior)' => [60, 150], ]; $ageBreakdown = []; foreach ($ageGroups as $label => [$min, $max]) { $from = $now->copy()->subYears($max)->format('Y-m-d'); $to = $now->copy()->subYears($min)->format('Y-m-d'); $ageBreakdown[$label] = Resident::whereBetween('date_of_birth', [$from, $to])->count(); } return compact('total', 'active', 'voters', 'genderBreakdown', 'civilBreakdown', 'purokBreakdown', 'ageBreakdown') + [ 'total_residents' => $total, 'active_residents' => $active, 'registered_voters' => $voters, 'gender_breakdown' => $genderBreakdown, 'civil_status_breakdown'=> $civilBreakdown, 'purok_breakdown' => $purokBreakdown, 'age_breakdown' => $ageBreakdown, ]; } private function householdsReport(): array { $total = Household::count(); $withElectricity = Household::where('has_electricity', true)->count(); $withWater = Household::where('has_water', true)->count(); $avgMembers = round(Household::withCount('chapterMembers')->avg('chapter_members_count') ?? 0, 1); $byOwnership = Household::select('ownership_type', DB::raw('count(*) as count')) ->groupBy('ownership_type') ->pluck('count', 'ownership_type') ->toArray(); return [ 'total_households' => $total, 'with_electricity' => $withElectricity, 'with_water' => $withWater, 'avg_members' => $avgMembers, 'by_ownership' => $byOwnership, ]; } private function documentsReport(int $year): array { $base = DocumentRequest::whereYear('created_at', $year); $total = (clone $base)->count(); $claimed = (clone $base)->where('status', 'CLAIMED')->count(); $revenue = (clone $base)->where('payment_status', 'PAID')->sum('base_fee'); $byStatus = (clone $base)->select('status', DB::raw('count(*) as count')) ->groupBy('status') ->pluck('count', 'status') ->toArray(); $byType = (clone $base)->select( 'barangay_request_types.name', DB::raw('count(*) as count'), DB::raw('sum(case when barangay_document_requests.payment_status = \'PAID\' then barangay_document_requests.base_fee else 0 end) as revenue') ) ->leftJoin('barangay_request_types', 'barangay_request_types.id', '=', 'barangay_document_requests.request_type_id') ->groupBy('barangay_request_types.name') ->get() ->toArray(); return compact('total', 'claimed', 'revenue', 'byStatus', 'byType') + [ 'total_revenue' => $revenue, 'by_status' => $byStatus, 'by_type' => $byType, ]; } private function blottersReport(int $year): array { $base = Blotter::whereYear('created_at', $year); $total = (clone $base)->count(); $resolved = (clone $base)->whereIn('status', ['RESOLVED', 'SETTLED'])->count(); $pending = (clone $base)->whereIn('status', ['FILED', 'FOR_HEARING'])->count(); $byStatus = (clone $base)->select('status', DB::raw('count(*) as count')) ->groupBy('status') ->pluck('count', 'status') ->toArray(); $byType = (clone $base)->select('incident_type', DB::raw('count(*) as count')) ->groupBy('incident_type') ->pluck('count', 'incident_type') ->toArray(); return [ 'total' => $total, 'resolved' => $resolved, 'pending' => $pending, 'by_status' => $byStatus, 'by_incident_type'=> $byType, ]; } private function budgetReport(int $year): array { $income = BarangayBudget::income()->byYear($year)->sum('amount'); $expense = BarangayBudget::expense()->byYear($year)->sum('amount'); $balance = $income - $expense; $bySource = BarangayBudget::select('source', 'category', DB::raw('sum(amount) as amount')) ->byYear($year) ->groupBy('source', 'category') ->orderBy('category') ->get() ->toArray(); return [ 'summary' => compact('income', 'expense', 'balance') + [ 'total_income' => $income, 'total_expense' => $expense, ], 'by_source' => $bySource, ]; } private function projectsReport(int $year): array { $base = BarangayProject::whereYear('created_at', $year); $total = (clone $base)->count(); $ongoing = (clone $base)->where('status', 'ONGOING')->count(); $completed = (clone $base)->where('status', 'COMPLETED')->count(); $budget = (clone $base)->sum('budget'); $byStatus = (clone $base)->select('status', DB::raw('count(*) as count')) ->groupBy('status') ->pluck('count', 'status') ->toArray(); $byType = (clone $base)->select('type', DB::raw('count(*) as count')) ->groupBy('type') ->get() ->toArray(); return [ 'total' => $total, 'ongoing' => $ongoing, 'completed' => $completed, 'total_budget' => $budget, 'by_status' => $byStatus, 'by_type' => $byType, ]; } }