185 lines
6.9 KiB
PHP
185 lines
6.9 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Admin\Manage;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\Admin\Manage\RejectCourseRegistrationRequest;
|
|
use App\Http\Requests\Admin\Manage\SaveCourseRegistrationRequest;
|
|
use App\Http\Requests\Admin\Manage\SignCourseRegistrationRequest;
|
|
use App\Http\Requests\PaginatedRequest;
|
|
use App\Models\Course;
|
|
use App\Models\CourseRegistrationSubmission;
|
|
use App\Models\Student;
|
|
use App\Services\Admin\Manage\CourseRegistrationService;
|
|
use App\Services\Admin\Master\AcademicTermService;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Inertia\Inertia;
|
|
use Inertia\Response;
|
|
|
|
class CourseRegistrationController extends Controller
|
|
{
|
|
public function __construct(
|
|
private readonly CourseRegistrationService $service,
|
|
private readonly AcademicTermService $academicTermService,
|
|
) {}
|
|
|
|
public function index(PaginatedRequest $request): Response|RedirectResponse
|
|
{
|
|
$user = auth()->user();
|
|
|
|
if ($user->hasRole('mahasiswa')) {
|
|
return to_route('admin.manage.course-registrations.show', $user->student->id);
|
|
}
|
|
|
|
$isKaprodi = $user->hasRole('kaprodi');
|
|
|
|
return Inertia::render('admin/manage/course-registrations/index', [
|
|
'departments' => $this->service->departmentSummary(),
|
|
'registrations' => $this->service->paginated(
|
|
...$request->validatedWithDefaults(),
|
|
departmentId: $request->validated('department_id'),
|
|
advisorLecturerId: ! $isKaprodi && $user->hasRole('dosen') ? $user->lecturer?->id : null,
|
|
ledDepartmentIds: $isKaprodi ? $user->ledDepartmentIds() : null,
|
|
),
|
|
'filters' => $request->only(['department_id']),
|
|
]);
|
|
}
|
|
|
|
public function show(Student $student): Response
|
|
{
|
|
$user = auth()->user();
|
|
$isStudent = $user->hasRole('mahasiswa');
|
|
|
|
abort_if($isStudent && $user->student->id !== $student->id, 403);
|
|
abort_if(! $isStudent && ! $user->canAccessCourseRegistrationOf($student), 403);
|
|
|
|
$backHref = $isStudent
|
|
? null
|
|
: route('admin.manage.course-registrations.index');
|
|
|
|
$canReview = ! $isStudent
|
|
&& $user->can('approve-course-registrations')
|
|
&& $user->canReviewCourseRegistrationOf($student);
|
|
|
|
$canSignAsKaprodi = $user->isKaprodiOf($student);
|
|
$canSignAsAdvisor = $user->isAdvisorOf($student);
|
|
|
|
$activeTerm = $this->academicTermService->getActive();
|
|
$allCourseClasses = $activeTerm
|
|
? $this->service->availableCourseClasses($student->department_id, $activeTerm->id)
|
|
: collect();
|
|
|
|
$departmentCourses = $this->service->departmentCourses($student->department_id);
|
|
|
|
$semesters = $departmentCourses
|
|
->map(fn (Course $course) => $course->semester_number)
|
|
->unique()
|
|
->sort()
|
|
->values();
|
|
|
|
$submissions = $activeTerm
|
|
? $semesters->mapWithKeys(fn (?int $semesterNumber) => [
|
|
CourseRegistrationSubmission::semesterKey($semesterNumber) => $this->service->buildSubmissionPayload(
|
|
$student,
|
|
$activeTerm,
|
|
$semesterNumber,
|
|
$departmentCourses,
|
|
$allCourseClasses,
|
|
),
|
|
])
|
|
: collect();
|
|
|
|
return Inertia::render('admin/manage/course-registrations/show', [
|
|
'submissions' => $submissions,
|
|
'semesters' => $semesters->values(),
|
|
'openSemesters' => $activeTerm?->open_semesters ?? [],
|
|
'studentCurrentSemester' => $student->current_semester,
|
|
'hasActiveTerm' => $activeTerm !== null,
|
|
'backHref' => $backHref,
|
|
'canReview' => $canReview,
|
|
'canSignAsKaprodi' => $canSignAsKaprodi,
|
|
'canSignAsAdvisor' => $canSignAsAdvisor,
|
|
]);
|
|
}
|
|
|
|
public function save(Student $student, string $semester, SaveCourseRegistrationRequest $request): RedirectResponse
|
|
{
|
|
$semesterNumber = CourseRegistrationSubmission::parseSemesterKey($semester);
|
|
|
|
$activeTerm = $this->academicTermService->getActive();
|
|
|
|
abort_if($activeTerm === null, 422);
|
|
|
|
$selectableIds = $this->service->selectableCourseClassIds(
|
|
$student->department_id,
|
|
$activeTerm->id,
|
|
$semesterNumber,
|
|
$activeTerm->open_semesters ?? [],
|
|
$student->current_semester,
|
|
);
|
|
|
|
$selectedIds = array_values(array_intersect(
|
|
$request->validated('course_class_ids') ?? [],
|
|
$selectableIds,
|
|
));
|
|
|
|
$submission = $this->service->findOrCreateForStudent($student, $activeTerm, $semesterNumber);
|
|
|
|
$this->service->saveRegistrations(
|
|
$submission,
|
|
$selectedIds,
|
|
$activeTerm->id,
|
|
$student->id,
|
|
$request->file('signature'),
|
|
);
|
|
|
|
Inertia::flash('toast', ['type' => 'success', 'message' => 'KRS berhasil disimpan.']);
|
|
|
|
return to_route('admin.manage.course-registrations.show', $student->id);
|
|
}
|
|
|
|
public function signAsKaprodi(Student $student, string $semester, SignCourseRegistrationRequest $request): RedirectResponse
|
|
{
|
|
abort_unless(auth()->user()->isKaprodiOf($student), 403);
|
|
|
|
$submission = $this->service->findOrCreateForSemester($student, $semester);
|
|
|
|
$this->service->signAsKaprodi($submission, $request->file('signature'));
|
|
|
|
Inertia::flash('toast', ['type' => 'success', 'message' => 'Tanda tangan berhasil disimpan.']);
|
|
|
|
return to_route('admin.manage.course-registrations.show', $student->id);
|
|
}
|
|
|
|
public function signAsAdvisor(Student $student, string $semester, SignCourseRegistrationRequest $request): RedirectResponse
|
|
{
|
|
abort_unless(auth()->user()->isAdvisorOf($student), 403);
|
|
|
|
$submission = $this->service->findOrCreateForSemester($student, $semester);
|
|
|
|
$this->service->signAsAdvisor($submission, $request->file('signature'));
|
|
|
|
Inertia::flash('toast', ['type' => 'success', 'message' => 'Tanda tangan berhasil disimpan.']);
|
|
|
|
return to_route('admin.manage.course-registrations.show', $student->id);
|
|
}
|
|
|
|
public function approve(CourseRegistrationSubmission $submission): RedirectResponse
|
|
{
|
|
abort_unless(auth()->user()->canReviewCourseRegistrationOf($submission->student), 403);
|
|
|
|
$this->service->approve($submission);
|
|
|
|
return Inertia::flash('toast', ['type' => 'success', 'message' => 'KRS berhasil disetujui.'])->back();
|
|
}
|
|
|
|
public function reject(RejectCourseRegistrationRequest $request, CourseRegistrationSubmission $submission): RedirectResponse
|
|
{
|
|
abort_unless(auth()->user()->canReviewCourseRegistrationOf($submission->student), 403);
|
|
|
|
$this->service->reject($submission, $request->validated('reason'));
|
|
|
|
return Inertia::flash('toast', ['type' => 'success', 'message' => 'KRS berhasil ditolak.'])->back();
|
|
}
|
|
}
|