get('search')); $academicYearId = $request->get('academic_year_id'); $departmentId = $request->get('department_id'); $classId = $request->get('class_id'); $studentExitsQuery = StudentExit::query() ->with(['academicYear', 'department', 'classRoom']) ->when($search !== '', function ($query) use ($search) { $query->where(function ($subQuery) use ($search) { $subQuery->where('full_name', 'like', "%{$search}%") ->orWhere('student_number', 'like', "%{$search}%") ->orWhere('nisn', 'like', "%{$search}%"); }); }) ->when($academicYearId, fn ($query) => $query->where('academic_year_id', $academicYearId)) ->when($departmentId, fn ($query) => $query->where('department_id', $departmentId)) ->when($classId, fn ($query) => $query->where('class_id', $classId)); $studentExits = (clone $studentExitsQuery) ->orderByDesc('entry_date') ->orderByDesc('id') ->paginate(10) ->withQueryString(); $totalExits = StudentExit::count(); $withLetterCount = StudentExit::query()->whereNotNull('exit_letter_file_path')->count(); $withoutLetterCount = max($totalExits - $withLetterCount, 0); $thisYearCount = StudentExit::query()->whereYear('exit_date', now()->year)->count(); $latestExitDate = StudentExit::query()->max('exit_date'); $recentExits = StudentExit::query() ->latest('exit_date') ->latest('id') ->limit(3) ->get(['id', 'full_name', 'exit_date', 'department_id', 'class_id']); return view('student-exits.index', [ 'studentExits' => $studentExits, 'search' => $search, 'filters' => [ 'academic_year_id' => $academicYearId, 'department_id' => $departmentId, 'class_id' => $classId, ], 'academicYears' => AcademicYear::orderBy('name')->pluck('name', 'id'), 'departments' => Department::orderBy('name')->pluck('name', 'id'), 'classes' => SchoolClass::orderBy('name')->pluck('name', 'id'), 'summary' => [ 'total' => $totalExits, 'with_letter' => $withLetterCount, 'without_letter' => $withoutLetterCount, 'this_year' => $thisYearCount, 'latest_exit_date' => $latestExitDate, 'filtered' => $studentExits->total(), ], 'recentExits' => $recentExits, ]); } public function show(StudentExit $studentExit): View { $studentExit->load(['academicYear', 'department', 'classRoom']); return view('student-exits.show', [ 'studentExit' => $studentExit, ]); } public function update(Request $request, StudentExit $studentExit): RedirectResponse { $validated = $request->validate([ 'exit_date' => ['nullable', 'date'], 'exit_reason' => ['nullable', 'string'], 'exit_letter' => ['nullable', 'file', 'mimes:pdf,jpg,jpeg,png', 'max:2048'], ], [ 'exit_letter.mimes' => 'Surat keluar harus berupa file PDF, JPG, JPEG, atau PNG.', 'exit_letter.max' => 'Ukuran surat keluar maksimal 2 MB.', ]); $studentExit->exit_date = $validated['exit_date'] ?? $studentExit->exit_date; $studentExit->exit_reason = $validated['exit_reason'] ?? $studentExit->exit_reason; if ($request->hasFile('exit_letter')) { if ($studentExit->exit_letter_file_path && Storage::disk('public')->exists($studentExit->exit_letter_file_path)) { Storage::disk('public')->delete($studentExit->exit_letter_file_path); } $file = $request->file('exit_letter'); $path = $file->store("student-exit-letters/{$studentExit->student_id}", 'public'); $studentExit->exit_letter_file_name = $file->getClientOriginalName(); $studentExit->exit_letter_file_path = $path; $studentExit->exit_letter_mime_type = $file->getMimeType(); $studentExit->exit_letter_file_size = $file->getSize(); } $studentExit->save(); Alert::success('Berhasil', 'Arsip siswa keluar berhasil diperbarui.'); return redirect()->route('student-exits.show', $studentExit)->with('success', 'Arsip siswa keluar berhasil diperbarui.'); } public function previewLetter(StudentExit $studentExit): View { abort_unless($studentExit->exit_letter_file_path && Storage::disk('public')->exists($studentExit->exit_letter_file_path), 404); $mimeType = $studentExit->exit_letter_mime_type ?: Storage::disk('public')->mimeType($studentExit->exit_letter_file_path); $fileUrl = asset('storage/' . $studentExit->exit_letter_file_path); $isImage = str_starts_with((string) $mimeType, 'image/'); $isPdf = $mimeType === 'application/pdf'; return view('student-exits.preview-letter', [ 'studentExit' => $studentExit, 'fileUrl' => $fileUrl, 'mimeType' => $mimeType, 'isImage' => $isImage, 'isPdf' => $isPdf, ]); } }