acct_type, UserActions::ViewDocumentRequests); } private function checkWrite(): bool { return UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::ProcessDocumentRequest); } public function index(Request $request) { if (!$this->checkRead()) return ResponseHelper::returnUnauthorized(); $query = DocumentRequest::with(['requestType', 'resident', 'processedBy'])->orderByDesc('id'); if ($status = $request->input('status')) $query->where('status', $status); if ($payStatus = $request->input('payment_status')) $query->where('payment_status', $payStatus); if ($typeId = $request->input('request_type_id')) $query->where('request_type_id', $typeId); if ($search = $request->input('search')) { $query->where('request_no', 'like', "%{$search}%"); } $requests = $query->paginate((int) $request->input('per_page', 20)); return response()->json(['success' => true, 'data' => $requests]); } public function myRequests(Request $request) { $requests = DocumentRequest::with('requestType') ->where('resident_user_id', Auth::id()) ->orderByDesc('id') ->get(); return response()->json(['success' => true, 'data' => $requests]); } public function show(Request $request) { if (!$this->checkRead()) return ResponseHelper::returnUnauthorized(); $doc = DocumentRequest::with(['requestType', 'resident', 'processedBy', 'payments']) ->where('hashkey', $request->input('target')) ->first(); if (!$doc) return ResponseHelper::returnError('Request not found', 404); return response()->json(['success' => true, 'data' => $doc]); } public function store(Request $request) { $validator = Validator::make($request->all(), [ 'request_type_id' => 'required|integer|exists:barangay_request_types,id', 'purpose' => 'required|string|max:500', ]); if ($validator->fails()) { return response()->json(['success' => false, 'errors' => $validator->errors()], 422); } $reqType = RequestType::findOrFail($request->input('request_type_id')); $doc = DocumentRequest::create([ 'hashkey' => hash('sha256', uniqid((string) now(), true)), 'request_no' => DocumentRequest::generateRequestNo(), 'resident_user_id' => Auth::id(), 'request_type_id' => $reqType->id, 'purpose' => $request->input('purpose'), 'fee_amount' => $reqType->base_fee, 'payment_status' => PaymentStatus::PENDING, 'status' => $reqType->base_fee > 0 ? DocumentStatus::PENDING_PAYMENT : DocumentStatus::PAID, 'requested_by' => Auth::id(), ]); return response()->json(['success' => true, 'data' => $doc, 'message' => 'Document request submitted']); } public function updateStatus(Request $request) { if (!$this->checkWrite()) return ResponseHelper::returnUnauthorized(); $doc = DocumentRequest::where('hashkey', $request->input('target'))->first(); if (!$doc) return ResponseHelper::returnError('Request not found', 404); $newStatus = DocumentStatus::tryFrom($request->input('status')); if (!$newStatus) return ResponseHelper::returnError('Invalid status', 422); $data = [ 'status' => $newStatus, 'processed_by' => Auth::id(), ]; if ($newStatus === DocumentStatus::CLAIMED) { $data['claimed_at'] = now(); } if ($request->input('notes')) $data['notes'] = $request->input('notes'); $doc->update($data); return response()->json(['success' => true, 'data' => $doc, 'message' => 'Status updated to ' . $newStatus->label()]); } public function confirmPayment(Request $request) { if (!$this->checkWrite()) return ResponseHelper::returnUnauthorized(); $doc = DocumentRequest::where('hashkey', $request->input('target'))->first(); if (!$doc) return ResponseHelper::returnError('Request not found', 404); $validator = Validator::make($request->all(), [ 'method' => 'required|in:CASH,GCASH,QRPH,BANK,WAIVED', 'reference' => 'nullable|string|max:100', 'amount' => 'nullable|numeric|min:0', ]); if ($validator->fails()) { return response()->json(['success' => false, 'errors' => $validator->errors()], 422); } $method = $request->input('method'); $amount = $request->input('amount', $doc->fee_amount); RequestPayment::create([ 'request_id' => $doc->id, 'amount' => $amount, 'method' => $method, 'reference' => $request->input('reference'), 'paid_at' => now(), 'verified_by' => Auth::id(), ]); $doc->update([ 'payment_status' => PaymentStatus::PAID, 'payment_method' => $method, 'payment_ref' => $request->input('reference'), 'status' => DocumentStatus::PROCESSING, 'processed_by' => Auth::id(), ]); return response()->json(['success' => true, 'data' => $doc, 'message' => 'Payment confirmed']); } public function markReady(Request $request) { if (!$this->checkWrite()) return ResponseHelper::returnUnauthorized(); $doc = DocumentRequest::where('hashkey', $request->input('target'))->first(); if (!$doc) return ResponseHelper::returnError('Request not found', 404); $doc->update(['status' => DocumentStatus::READY, 'processed_by' => Auth::id()]); return response()->json(['success' => true, 'data' => $doc, 'message' => 'Marked as ready for pickup']); } public function markClaimed(Request $request) { if (!$this->checkWrite()) return ResponseHelper::returnUnauthorized(); $doc = DocumentRequest::where('hashkey', $request->input('target'))->first(); if (!$doc) return ResponseHelper::returnError('Request not found', 404); $doc->update([ 'status' => DocumentStatus::CLAIMED, 'claimed_at' => now(), ]); return response()->json(['success' => true, 'data' => $doc, 'message' => 'Document marked as claimed']); } public function cancel(Request $request) { $doc = DocumentRequest::where('hashkey', $request->input('target'))->first(); if (!$doc) return ResponseHelper::returnError('Request not found', 404); if ($doc->resident_user_id !== Auth::id() && !$this->checkWrite()) { return ResponseHelper::returnUnauthorized(); } if (in_array($doc->status, [DocumentStatus::CLAIMED, DocumentStatus::CANCELLED])) { return ResponseHelper::returnError('Cannot cancel this request', 422); } $doc->update(['status' => DocumentStatus::CANCELLED]); return response()->json(['success' => true, 'message' => 'Request cancelled']); } }