siakad-itm/app/Http/Controllers/Admin/AcademicClasses/AttendanceController.php

109 lines
3.8 KiB
PHP

<?php
namespace App\Http\Controllers\Admin\AcademicClasses;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\AcademicClasses\AttendanceStoreRequest;
use App\Models\CourseClass;
use App\Services\Admin\AcademicClasses\AttendanceService;
use App\Services\Admin\Master\AcademicTermService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
class AttendanceController extends Controller
{
public function __construct(
private readonly AttendanceService $service,
private readonly AcademicTermService $academicTermService,
) {}
public function index(Request $request): Response
{
$academicTermId = $request->has('academic_term_id')
? $request->integer('academic_term_id')
: $this->academicTermService->getActive()?->id;
return Inertia::render('admin/academic-classes/attendances/index', [
'courseClasses' => $this->service->courseClassesForUser($request->user(), $academicTermId),
'academicTerms' => $this->academicTermService->getAllForSelect(),
'filters' => [
'academic_term_id' => $academicTermId ? (string) $academicTermId : null,
],
]);
}
public function mine(Request $request): Response
{
$student = $request->user()->student;
abort_if(! $student, 403);
return Inertia::render('admin/academic-classes/attendances/mine', [
'summaries' => $this->service->forStudent($student),
]);
}
public function show(CourseClass $courseClass): Response
{
$this->abortUnlessLecturerOwnsClass($courseClass);
$courseClass->load(['course', 'academicTerm']);
return Inertia::render('admin/academic-classes/attendances/course-class', [
'courseClass' => $courseClass,
'sessions' => $this->service->sessionsForClass($courseClass),
'nextMeetingNumber' => $this->service->nextMeetingNumber($courseClass),
]);
}
public function session(CourseClass $courseClass, int $meetingNumber): Response
{
$this->abortUnlessLecturerOwnsClass($courseClass);
$courseClass->load('course');
$data = $this->service->session($courseClass, $meetingNumber);
return Inertia::render('admin/academic-classes/attendances/session', [
'courseClass' => $courseClass,
'meetingNumber' => $meetingNumber,
'roster' => $data['roster'],
'date' => $data['date'],
]);
}
public function store(AttendanceStoreRequest $request, CourseClass $courseClass, int $meetingNumber): RedirectResponse
{
$this->service->saveSession($courseClass->id, $meetingNumber, $request->validated('date'), $request->validated('records'));
Inertia::flash('toast', ['type' => 'success', 'message' => 'Kehadiran berhasil disimpan.']);
return to_route('admin.academic-classes.attendances.session', [$courseClass->id, $meetingNumber]);
}
public function destroy(CourseClass $courseClass, int $meetingNumber): RedirectResponse
{
$this->abortUnlessLecturerOwnsClass($courseClass);
$this->service->deleteSession($courseClass->id, $meetingNumber);
Inertia::flash('toast', ['type' => 'success', 'message' => 'Sesi kehadiran berhasil dihapus.']);
return to_route('admin.academic-classes.attendances.show', [$courseClass->id]);
}
/**
* A dosen may only take or manage attendance for classes they lecture.
*/
private function abortUnlessLecturerOwnsClass(CourseClass $courseClass): void
{
$user = request()->user();
abort_if(
$user->hasRole('dosen') && $courseClass->lecturer_id !== $user->lecturer?->id,
403,
);
}
}