290 lines
14 KiB
PHP
290 lines
14 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\AcademicYear;
|
|
use App\Models\Department;
|
|
use App\Models\SchoolClass;
|
|
use App\Models\StudentGraduation;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Str;
|
|
use Illuminate\View\View;
|
|
use RealRashid\SweetAlert\Facades\Alert;
|
|
|
|
class GraduatedStudentController extends Controller
|
|
{
|
|
public function index(Request $request): View
|
|
{
|
|
$search = trim((string) $request->get('search'));
|
|
$academicYearId = $request->get('academic_year_id');
|
|
$departmentId = $request->get('department_id');
|
|
$classId = $request->get('class_id');
|
|
$documentStatus = (string) $request->get('document_status', 'all');
|
|
$sort = (string) $request->get('sort', 'full_name');
|
|
$direction = strtolower((string) $request->get('direction', 'asc')) === 'desc' ? 'desc' : 'asc';
|
|
|
|
$allowedSorts = [
|
|
'full_name' => 'full_name',
|
|
'student_number' => 'student_number',
|
|
'academic_year' => 'academic_year_id',
|
|
'department' => 'department_id',
|
|
'class' => 'class_id',
|
|
'graduation_date' => 'graduation_date',
|
|
'created_at' => 'created_at',
|
|
];
|
|
|
|
if (! array_key_exists($sort, $allowedSorts)) {
|
|
$sort = 'full_name';
|
|
}
|
|
|
|
$documentFields = [
|
|
'skl_file_path',
|
|
'ijazah_file_path',
|
|
'transcript_file_path',
|
|
'ukk_certificate_file_path',
|
|
'lsp_certificate_file_path',
|
|
];
|
|
|
|
$graduations = StudentGraduation::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))
|
|
->when($documentStatus === 'incomplete', function ($query) use ($documentFields) {
|
|
foreach ($documentFields as $field) {
|
|
$query->orWhereNull($field);
|
|
}
|
|
})
|
|
->when($documentStatus === 'complete', function ($query) use ($documentFields) {
|
|
foreach ($documentFields as $field) {
|
|
$query->whereNotNull($field);
|
|
}
|
|
})
|
|
->orderBy($allowedSorts[$sort], $direction)
|
|
->orderBy('id', $direction)
|
|
->paginate(10)
|
|
->withQueryString();
|
|
|
|
$totalGraduations = StudentGraduation::count();
|
|
$summary = [
|
|
'total' => $totalGraduations,
|
|
'filtered' => $graduations->total(),
|
|
'with_skl' => StudentGraduation::query()->whereNotNull('skl_file_path')->count(),
|
|
'with_ijazah' => StudentGraduation::query()->whereNotNull('ijazah_file_path')->count(),
|
|
'with_transcript' => StudentGraduation::query()->whereNotNull('transcript_file_path')->count(),
|
|
'with_ukk_certificate' => StudentGraduation::query()->whereNotNull('ukk_certificate_file_path')->count(),
|
|
'with_lsp_certificate' => StudentGraduation::query()->whereNotNull('lsp_certificate_file_path')->count(),
|
|
'this_year' => StudentGraduation::query()->whereYear('graduation_date', now()->year)->count(),
|
|
'latest_graduation_date' => StudentGraduation::query()->max('graduation_date'),
|
|
];
|
|
|
|
$graduations->getCollection()->transform(function (StudentGraduation $graduation) use ($documentFields) {
|
|
$availableDocuments = collect($documentFields)->filter(fn ($field) => filled($graduation->{$field}))->count();
|
|
$graduation->documents_total = count($documentFields);
|
|
$graduation->documents_available = $availableDocuments;
|
|
$graduation->documents_missing = max($graduation->documents_total - $availableDocuments, 0);
|
|
$graduation->documents_progress_percentage = $graduation->documents_total > 0
|
|
? (int) round(($availableDocuments / $graduation->documents_total) * 100)
|
|
: 100;
|
|
|
|
return $graduation;
|
|
});
|
|
|
|
return view('graduated-students.index', [
|
|
'graduations' => $graduations,
|
|
'search' => $search,
|
|
'filters' => [
|
|
'academic_year_id' => $academicYearId,
|
|
'department_id' => $departmentId,
|
|
'class_id' => $classId,
|
|
'document_status' => $documentStatus,
|
|
],
|
|
'academicYears' => AcademicYear::orderBy('name')->pluck('name', 'id'),
|
|
'departments' => Department::orderBy('name')->pluck('name', 'id'),
|
|
'classes' => SchoolClass::query()
|
|
->when($academicYearId, function ($query) use ($academicYearId, $classId) {
|
|
$query->where('academic_year_id', $academicYearId)
|
|
->where(function ($innerQuery) use ($classId) {
|
|
$innerQuery->where('level', 'XII');
|
|
|
|
if ($classId) {
|
|
$innerQuery->orWhere('id', $classId);
|
|
}
|
|
});
|
|
}, function ($query) use ($classId) {
|
|
if ($classId) {
|
|
$query->whereKey($classId);
|
|
} else {
|
|
$query->whereRaw('1 = 0');
|
|
}
|
|
})
|
|
->orderBy('name')
|
|
->pluck('name', 'id'),
|
|
'documentStatusOptions' => [
|
|
'all' => 'Semua Dokumen',
|
|
'complete' => 'Dokumen Lengkap',
|
|
'incomplete' => 'Dokumen Belum Lengkap',
|
|
],
|
|
'sort' => $sort,
|
|
'direction' => $direction,
|
|
'summary' => $summary,
|
|
]);
|
|
}
|
|
|
|
public function show(StudentGraduation $graduatedStudent): View
|
|
{
|
|
$graduatedStudent->load(['academicYear', 'department', 'classRoom']);
|
|
|
|
return view('graduated-students.show', [
|
|
'graduation' => $graduatedStudent,
|
|
]);
|
|
}
|
|
|
|
public function update(Request $request, StudentGraduation $graduatedStudent): RedirectResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'graduation_date' => ['nullable', 'date'],
|
|
'graduation_note' => ['nullable', 'string'],
|
|
'skl_file' => ['nullable', 'file', 'mimes:pdf,jpg,jpeg,png', 'max:4096'],
|
|
'ijazah_file' => ['nullable', 'file', 'mimes:pdf,jpg,jpeg,png', 'max:4096'],
|
|
'transcript_file' => ['nullable', 'file', 'mimes:pdf,jpg,jpeg,png', 'max:4096'],
|
|
'ukk_certificate_file' => ['nullable', 'file', 'mimes:pdf,jpg,jpeg,png', 'max:4096'],
|
|
'lsp_certificate_file' => ['nullable', 'file', 'mimes:pdf,jpg,jpeg,png', 'max:4096'],
|
|
], [
|
|
'skl_file.mimes' => 'File SKL harus berupa PDF, JPG, JPEG, atau PNG.',
|
|
'skl_file.max' => 'Ukuran file SKL maksimal 4 MB.',
|
|
'ijazah_file.mimes' => 'File ijazah harus berupa PDF, JPG, JPEG, atau PNG.',
|
|
'ijazah_file.max' => 'Ukuran file ijazah maksimal 4 MB.',
|
|
'transcript_file.mimes' => 'File transkrip nilai harus berupa PDF, JPG, JPEG, atau PNG.',
|
|
'transcript_file.max' => 'Ukuran file transkrip nilai maksimal 4 MB.',
|
|
'ukk_certificate_file.mimes' => 'File sertifikat UKK harus berupa PDF, JPG, JPEG, atau PNG.',
|
|
'ukk_certificate_file.max' => 'Ukuran file sertifikat UKK maksimal 4 MB.',
|
|
'lsp_certificate_file.mimes' => 'File sertifikat LSP harus berupa PDF, JPG, JPEG, atau PNG.',
|
|
'lsp_certificate_file.max' => 'Ukuran file sertifikat LSP maksimal 4 MB.',
|
|
]);
|
|
|
|
$graduatedStudent->graduation_date = $validated['graduation_date'] ?? $graduatedStudent->graduation_date;
|
|
$graduatedStudent->graduation_note = $validated['graduation_note'] ?? $graduatedStudent->graduation_note;
|
|
|
|
if ($request->hasFile('skl_file')) {
|
|
if ($graduatedStudent->skl_file_path && Storage::disk('public')->exists($graduatedStudent->skl_file_path)) {
|
|
Storage::disk('public')->delete($graduatedStudent->skl_file_path);
|
|
}
|
|
|
|
$file = $request->file('skl_file');
|
|
$path = $file->store("student-graduation-documents/{$graduatedStudent->student_id}/skl", 'public');
|
|
|
|
$graduatedStudent->skl_file_name = $file->getClientOriginalName();
|
|
$graduatedStudent->skl_file_path = $path;
|
|
$graduatedStudent->skl_mime_type = $file->getMimeType();
|
|
$graduatedStudent->skl_file_size = $file->getSize();
|
|
}
|
|
|
|
if ($request->hasFile('ijazah_file')) {
|
|
if ($graduatedStudent->ijazah_file_path && Storage::disk('public')->exists($graduatedStudent->ijazah_file_path)) {
|
|
Storage::disk('public')->delete($graduatedStudent->ijazah_file_path);
|
|
}
|
|
|
|
$file = $request->file('ijazah_file');
|
|
$path = $file->store("student-graduation-documents/{$graduatedStudent->student_id}/ijazah", 'public');
|
|
|
|
$graduatedStudent->ijazah_file_name = $file->getClientOriginalName();
|
|
$graduatedStudent->ijazah_file_path = $path;
|
|
$graduatedStudent->ijazah_mime_type = $file->getMimeType();
|
|
$graduatedStudent->ijazah_file_size = $file->getSize();
|
|
}
|
|
|
|
if ($request->hasFile('transcript_file')) {
|
|
if ($graduatedStudent->transcript_file_path && Storage::disk('public')->exists($graduatedStudent->transcript_file_path)) {
|
|
Storage::disk('public')->delete($graduatedStudent->transcript_file_path);
|
|
}
|
|
|
|
$file = $request->file('transcript_file');
|
|
$path = $file->store("student-graduation-documents/{$graduatedStudent->student_id}/transcript", 'public');
|
|
|
|
$graduatedStudent->transcript_file_name = $file->getClientOriginalName();
|
|
$graduatedStudent->transcript_file_path = $path;
|
|
$graduatedStudent->transcript_mime_type = $file->getMimeType();
|
|
$graduatedStudent->transcript_file_size = $file->getSize();
|
|
}
|
|
|
|
if ($request->hasFile('ukk_certificate_file')) {
|
|
if ($graduatedStudent->ukk_certificate_file_path && Storage::disk('public')->exists($graduatedStudent->ukk_certificate_file_path)) {
|
|
Storage::disk('public')->delete($graduatedStudent->ukk_certificate_file_path);
|
|
}
|
|
|
|
$file = $request->file('ukk_certificate_file');
|
|
$path = $file->store("student-graduation-documents/{$graduatedStudent->student_id}/ukk-certificate", 'public');
|
|
|
|
$graduatedStudent->ukk_certificate_file_name = $file->getClientOriginalName();
|
|
$graduatedStudent->ukk_certificate_file_path = $path;
|
|
$graduatedStudent->ukk_certificate_mime_type = $file->getMimeType();
|
|
$graduatedStudent->ukk_certificate_file_size = $file->getSize();
|
|
}
|
|
|
|
if ($request->hasFile('lsp_certificate_file')) {
|
|
if ($graduatedStudent->lsp_certificate_file_path && Storage::disk('public')->exists($graduatedStudent->lsp_certificate_file_path)) {
|
|
Storage::disk('public')->delete($graduatedStudent->lsp_certificate_file_path);
|
|
}
|
|
|
|
$file = $request->file('lsp_certificate_file');
|
|
$path = $file->store("student-graduation-documents/{$graduatedStudent->student_id}/lsp-certificate", 'public');
|
|
|
|
$graduatedStudent->lsp_certificate_file_name = $file->getClientOriginalName();
|
|
$graduatedStudent->lsp_certificate_file_path = $path;
|
|
$graduatedStudent->lsp_certificate_mime_type = $file->getMimeType();
|
|
$graduatedStudent->lsp_certificate_file_size = $file->getSize();
|
|
}
|
|
|
|
$graduatedStudent->save();
|
|
|
|
Alert::success('Berhasil', 'Arsip siswa lulus berhasil diperbarui.');
|
|
|
|
return redirect()->route('graduated-students.show', $graduatedStudent)->with('success', 'Arsip siswa lulus berhasil diperbarui.');
|
|
}
|
|
|
|
public function previewDocument(StudentGraduation $graduatedStudent, string $document): View
|
|
{
|
|
abort_unless(in_array($document, ['skl', 'ijazah', 'transcript', 'ukk-certificate', 'lsp-certificate'], true), 404);
|
|
|
|
$documentConfig = [
|
|
'skl' => ['path' => 'skl_file_path', 'name' => 'skl_file_name', 'mime' => 'skl_mime_type', 'label' => 'SKL'],
|
|
'ijazah' => ['path' => 'ijazah_file_path', 'name' => 'ijazah_file_name', 'mime' => 'ijazah_mime_type', 'label' => 'Ijazah'],
|
|
'transcript' => ['path' => 'transcript_file_path', 'name' => 'transcript_file_name', 'mime' => 'transcript_mime_type', 'label' => 'Transkrip Nilai'],
|
|
'ukk-certificate' => ['path' => 'ukk_certificate_file_path', 'name' => 'ukk_certificate_file_name', 'mime' => 'ukk_certificate_mime_type', 'label' => 'Sertifikat UKK'],
|
|
'lsp-certificate' => ['path' => 'lsp_certificate_file_path', 'name' => 'lsp_certificate_file_name', 'mime' => 'lsp_certificate_mime_type', 'label' => 'Sertifikat LSP'],
|
|
][$document];
|
|
|
|
$filePathField = $documentConfig['path'];
|
|
$fileNameField = $documentConfig['name'];
|
|
$mimeTypeField = $documentConfig['mime'];
|
|
|
|
abort_unless($graduatedStudent->{$filePathField} && Storage::disk('public')->exists($graduatedStudent->{$filePathField}), 404);
|
|
|
|
$mimeType = $graduatedStudent->{$mimeTypeField} ?: Storage::disk('public')->mimeType($graduatedStudent->{$filePathField});
|
|
$fileUrl = asset('storage/' . $graduatedStudent->{$filePathField});
|
|
$isImage = Str::startsWith((string) $mimeType, 'image/');
|
|
$isPdf = $mimeType === 'application/pdf';
|
|
|
|
return view('graduated-students.preview-document', [
|
|
'graduation' => $graduatedStudent,
|
|
'documentType' => $document,
|
|
'documentLabel' => $documentConfig['label'],
|
|
'fileName' => $graduatedStudent->{$fileNameField},
|
|
'fileUrl' => $fileUrl,
|
|
'mimeType' => $mimeType,
|
|
'isImage' => $isImage,
|
|
'isPdf' => $isPdf,
|
|
]);
|
|
}
|
|
}
|