226 lines
8.8 KiB
PHP
226 lines
8.8 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
|
|
use App\Models\AcademicPeriod;
|
|
use App\Models\Classes;
|
|
use App\Models\Schedule;
|
|
use App\Models\Subject;
|
|
use App\Models\Teacher;
|
|
use App\Services\QrLinkService;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\Crypt;
|
|
|
|
class JadwalController extends Controller
|
|
{
|
|
protected QrLinkService $qrLinkService;
|
|
|
|
public function __construct(QrLinkService $qrLinkService)
|
|
{
|
|
$this->qrLinkService = $qrLinkService;
|
|
}
|
|
public function index()
|
|
{
|
|
$kelas = Classes::all();
|
|
$mapel = Subject::all();
|
|
|
|
// Join teachers dengan subjects berdasarkan kolom subject (code)
|
|
$guru = Teacher::all()->map(function($teacher) {
|
|
// Cari subject berdasarkan code yang ada di kolom subject teacher
|
|
// Gunakan array_map('trim', ...) untuk menghilangkan spasi sebelum/sesudah koma
|
|
$subjectCodes = array_map('trim', explode(',', $teacher->subject));
|
|
$subjects = Subject::whereIn('code', $subjectCodes)->pluck('id')->toArray();
|
|
$teacher->subject_ids = $subjects;
|
|
return $teacher;
|
|
});
|
|
|
|
$periodes = AcademicPeriod::orderBy('start_date', 'desc')->get();
|
|
$periode_aktif = AcademicPeriod::where('is_active', true)->first();
|
|
$jadwal = Schedule::with(['class', 'subject', 'teacher'])->get();
|
|
return view('pages.jadwal.jadwal', compact('kelas', 'mapel', 'guru', 'periodes', 'periode_aktif', 'jadwal'));
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$validated = $request->validate([
|
|
'day_of_week' => 'required|string',
|
|
'period_start' => 'required|integer',
|
|
'period_end' => 'required|integer',
|
|
'start_time' => 'required|string',
|
|
'end_time' => 'required|string',
|
|
'code' => 'nullable|string',
|
|
'id_class' => 'required|exists:clases,id',
|
|
'id_subject' => 'required|exists:subjects,id',
|
|
'id_teacher' => 'required|exists:teachers,id',
|
|
'id_academic_periods' => 'nullable|exists:academic_periods,id',
|
|
]);
|
|
|
|
// Hitung jam mulai dan jam selesai
|
|
$startHour = 7 + ($validated['period_start'] - 1);
|
|
$endHour = 7 + ($validated['period_end'] - 1);
|
|
$start_time = sprintf('%02d:00', $startHour);
|
|
$end_time = sprintf('%02d:00', $endHour);
|
|
|
|
// Ambil data untuk kode otomatis
|
|
$class = Classes::find($validated['id_class']);
|
|
$subject = Subject::find($validated['id_subject']);
|
|
$period = $validated['id_academic_periods'] ?? '';
|
|
$token = (string) random_int(1000, 9999);
|
|
|
|
$day = strtoupper(substr($validated['day_of_week'], 0, 3));
|
|
$className = $class ? $class->name : '';
|
|
$subjectCode = $subject ? $subject->code : '';
|
|
$periodCode = $period ?: '0';
|
|
|
|
$autoCode = "{$className}-{$day}-{$validated['period_start']}-{$validated['period_end']}-{$subjectCode}-{$periodCode}-{$token}";
|
|
|
|
$code = $request->input('code') ?: $autoCode;
|
|
|
|
// Hash code sebelum simpan ke database
|
|
$hashedCode = Crypt::encryptString($code);
|
|
|
|
Schedule::create([
|
|
// make day of week to lowercase
|
|
'day_of_week' => strtolower($validated['day_of_week']),
|
|
'period_start' => $validated['period_start'],
|
|
'period_end' => $validated['period_end'],
|
|
'start_time' => $validated['start_time'],
|
|
'end_time' => $validated['end_time'],
|
|
'code' => $hashedCode,
|
|
'id_class' => $validated['id_class'],
|
|
'id_subject' => $validated['id_subject'],
|
|
'id_teacher' => $validated['id_teacher'],
|
|
'id_academic_periods' => $validated['id_academic_periods'] ?? null,
|
|
]);
|
|
|
|
return redirect()->route('jadwal.index')->with('success', 'Jadwal berhasil ditambahkan!');
|
|
}
|
|
|
|
public function update(Request $request, $id)
|
|
{
|
|
$validated = $request->validate([
|
|
'day_of_week' => 'required|string',
|
|
'period_start' => 'required|integer',
|
|
'period_end' => 'required|integer',
|
|
'start_time' => 'required|string',
|
|
'end_time' => 'required|string',
|
|
'code' => 'required|string',
|
|
'id_class' => 'required|exists:clases,id',
|
|
'id_subject' => 'required|exists:subjects,id',
|
|
'id_teacher' => 'required|exists:teachers,id',
|
|
'id_academic_periods' => 'nullable|exists:academic_periods,id',
|
|
]);
|
|
|
|
// Hitung jam mulai dan jam selesai
|
|
$startHour = 7 + ($validated['period_start'] - 1);
|
|
$endHour = 7 + ($validated['period_end'] - 1);
|
|
$start_time = sprintf('%02d:00', $startHour);
|
|
$end_time = sprintf('%02d:00', $endHour);
|
|
|
|
// Ambil schedule lama untuk cek perubahan dan avoid double encryption
|
|
$jadwalLama = Schedule::findOrFail($id);
|
|
|
|
// Cek apakah ada perubahan di field-field yang mempengaruhi code
|
|
$codeChanged = false;
|
|
if ($jadwalLama->day_of_week != strtolower($validated['day_of_week']) ||
|
|
$jadwalLama->period_start != $validated['period_start'] ||
|
|
$jadwalLama->period_end != $validated['period_end'] ||
|
|
$jadwalLama->id_subject != $validated['id_subject'] ||
|
|
$jadwalLama->id_class != $validated['id_class'] ||
|
|
$jadwalLama->id_academic_periods != $validated['id_academic_periods']) {
|
|
$codeChanged = true;
|
|
}
|
|
|
|
// Generate code baru jika ada perubahan, atau gunakan code lama
|
|
if ($codeChanged) {
|
|
// Generate code baru
|
|
$class = Classes::find($validated['id_class']);
|
|
$subject = Subject::find($validated['id_subject']);
|
|
$period = $validated['id_academic_periods'] ?? '';
|
|
$token = (string) random_int(1000, 9999);
|
|
|
|
$day = strtoupper(substr($validated['day_of_week'], 0, 3));
|
|
$className = $class ? $class->name : '';
|
|
$subjectCode = $subject ? $subject->code : '';
|
|
$periodCode = $period ?: '0';
|
|
|
|
$autoCode = "{$className}-{$day}-{$validated['period_start']}-{$validated['period_end']}-{$subjectCode}-{$periodCode}-{$token}";
|
|
$hashedCode = Crypt::encryptString($autoCode);
|
|
} else {
|
|
// Gunakan code lama tanpa encrypt ulang (avoid double encryption)
|
|
$hashedCode = $jadwalLama->code;
|
|
}
|
|
|
|
$jadwalLama->update([
|
|
'day_of_week' => strtolower($validated['day_of_week']),
|
|
'period_start' => $validated['period_start'],
|
|
'period_end' => $validated['period_end'],
|
|
'start_time' => $validated['start_time'],
|
|
'end_time' => $validated['end_time'],
|
|
'code' => $hashedCode,
|
|
'id_class' => $validated['id_class'],
|
|
'id_subject' => $validated['id_subject'],
|
|
'id_teacher' => $validated['id_teacher'],
|
|
'id_academic_periods' => $validated['id_academic_periods'] ?? null,
|
|
]);
|
|
|
|
return redirect()->route('jadwal.index')->with('success', 'Jadwal berhasil diupdate!');
|
|
}
|
|
|
|
public function destroy(Request $request)
|
|
{
|
|
$ids = $request->input('ids');
|
|
if (!$ids) {
|
|
return redirect()->route('jadwal.index')->with('error', 'Tidak ada jadwal yang dipilih untuk dihapus.');
|
|
}
|
|
// Ubah string menjadi array jika perlu
|
|
if (is_string($ids)) {
|
|
$ids = explode(',', $ids);
|
|
}
|
|
Schedule::destroy($ids);
|
|
return redirect()->route('jadwal.index')->with('success', 'Jadwal berhasil dihapus!');
|
|
}
|
|
|
|
public function showQr($id)
|
|
{
|
|
$jadwal = Schedule::findOrFail($id);
|
|
return view('pages.jadwal.qr', compact('jadwal'));
|
|
}
|
|
|
|
public function showPublicQr($token)
|
|
{
|
|
$tokenData = Cache::get("public_qr_link:$token");
|
|
|
|
if (!$tokenData) {
|
|
return view('public.attendance.qr-error', [
|
|
'status' => 'expired',
|
|
'message' => 'Link QR sudah expired atau tidak valid. Silakan minta link baru dari guru.'
|
|
]);
|
|
}
|
|
|
|
$idSchedule = $tokenData['schedule_id'];
|
|
$expiresAt = $tokenData['expires_at'];
|
|
|
|
$jadwal = Schedule::with(['class', 'subject', 'teacher'])->find($idSchedule);
|
|
|
|
if (!$jadwal) {
|
|
return view('public.attendance.qr-error', [
|
|
'status' => 'notfound',
|
|
'message' => 'Data jadwal tidak ditemukan.'
|
|
]);
|
|
}
|
|
|
|
$publicUrl = route('jadwal.qr.public', ['token' => $token]);
|
|
|
|
return view('public.attendance.qr', compact('jadwal', 'publicUrl', 'expiresAt'));
|
|
}
|
|
|
|
public function generateQrLink($id)
|
|
{
|
|
$result = $this->qrLinkService->generateLink($id);
|
|
return response()->json($result);
|
|
}
|
|
}
|