acct_type, UserActions::ViewBarangayProjects); } private function checkWrite(): bool { return UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::ManageBarangayProjects); } public function index(Request $request) { if (!$this->checkRead()) return ResponseHelper::returnUnauthorized(); $query = BarangayProject::orderByDesc('id'); if ($status = $request->input('status')) $query->where('status', $status); if ($type = $request->input('type')) $query->where('type', $type); if ($year = $request->input('year')) { $query->whereYear('start_date', $year); } $projects = $query->paginate((int) $request->input('per_page', 20)); return response()->json(['success' => true, 'data' => $projects]); } public function show(Request $request) { if (!$this->checkRead()) return ResponseHelper::returnUnauthorized(); $project = BarangayProject::where('hashkey', $request->input('target'))->first(); if (!$project) return ResponseHelper::returnError('Project not found', 404); return response()->json(['success' => true, 'data' => $project]); } public function store(Request $request) { if (!$this->checkWrite()) return ResponseHelper::returnUnauthorized(); $validator = Validator::make($request->all(), [ 'project_name' => 'required|string|max:500', 'description' => 'nullable|string', 'type' => 'required|in:INFRASTRUCTURE,LIVELIHOOD,HEALTH,EDUCATION,ENVIRONMENT,OTHERS', 'budget' => 'required|numeric|min:0', 'fund_source' => 'required|in:GENERAL_FUND,SK,PROVINCE,NATIONAL,OTHERS', 'start_date' => 'required|date', 'end_date' => 'nullable|date|after:start_date', 'implementing_office' => 'nullable|string|max:255', 'contractor' => 'nullable|string|max:255', 'location' => 'nullable|string|max:500', 'beneficiaries_count' => 'nullable|integer|min:0', ]); if ($validator->fails()) { return response()->json(['success' => false, 'errors' => $validator->errors()], 422); } $data = $validator->validated(); $data['hashkey'] = hash('sha256', uniqid((string) now(), true)); $data['status'] = 'PLANNED'; $data['created_by'] = Auth::id(); $data['updated_by'] = Auth::id(); $project = BarangayProject::create($data); return response()->json(['success' => true, 'data' => $project, 'message' => 'Project created']); } public function update(Request $request) { if (!$this->checkWrite()) return ResponseHelper::returnUnauthorized(); $project = BarangayProject::where('hashkey', $request->input('target'))->first(); if (!$project) return ResponseHelper::returnError('Project not found', 404); $data = $request->except(['target', 'hashkey', 'created_by']); $data['updated_by'] = Auth::id(); $project->update($data); return response()->json(['success' => true, 'data' => $project, 'message' => 'Project updated']); } public function updateStatus(Request $request) { if (!$this->checkWrite()) return ResponseHelper::returnUnauthorized(); $project = BarangayProject::where('hashkey', $request->input('target'))->first(); if (!$project) return ResponseHelper::returnError('Project not found', 404); $validStatuses = ['PLANNED', 'ONGOING', 'COMPLETED', 'SUSPENDED', 'CANCELLED']; $status = $request->input('status'); if (!in_array($status, $validStatuses)) { return ResponseHelper::returnError('Invalid status', 422); } $project->update(['status' => $status, 'updated_by' => Auth::id()]); return response()->json(['success' => true, 'data' => $project, 'message' => "Project status set to {$status}"]); } public function summary() { if (!$this->checkRead()) return ResponseHelper::returnUnauthorized(); $summary = [ 'total' => BarangayProject::count(), 'planned' => BarangayProject::where('status', 'PLANNED')->count(), 'ongoing' => BarangayProject::where('status', 'ONGOING')->count(), 'completed' => BarangayProject::where('status', 'COMPLETED')->count(), 'total_budget' => BarangayProject::sum('budget'), 'by_type' => BarangayProject::selectRaw('type, count(*) as count, sum(budget) as budget') ->groupBy('type')->get(), ]; return response()->json(['success' => true, 'data' => $summary]); } }