From 4fa709509fb984394b1015023eb91a7a3e8cb081 Mon Sep 17 00:00:00 2001 From: Bro Date: Fri, 24 Jul 2026 18:38:35 +0700 Subject: [PATCH] feat: snapshot class_name di setiap presensi & pelanggaran MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Migration: tambah kolom: - attendances.class_name (varchar 100) - violations.student_class (varchar 100) - Backfill data existing dari students.class_name Controller manual: simpan class_name dari form Sync E-Jurnal: simpan class_name dari lookup student ViolationService: ambil class_name dari student saat buat Model: tambah ke fillable Ini menjamin data historis tetap akurat meskipun siswa naik kelas (X→XI→XII) di tahun ajaran baru. --- .../Api/AttendanceSyncController.php | 7 ++- app/Http/Controllers/AttendanceController.php | 1 + app/Models/Attendance.php | 2 +- app/Models/Violation.php | 2 +- app/Services/ViolationService.php | 1 + ...lass_name_to_attendance_and_violations.php | 44 +++++++++++++++++++ 6 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 database/migrations/2026_07_24_183600_add_class_name_to_attendance_and_violations.php diff --git a/app/Http/Controllers/Api/AttendanceSyncController.php b/app/Http/Controllers/Api/AttendanceSyncController.php index 8648f2a..87e3381 100644 --- a/app/Http/Controllers/Api/AttendanceSyncController.php +++ b/app/Http/Controllers/Api/AttendanceSyncController.php @@ -51,9 +51,11 @@ class AttendanceSyncController extends Controller ]; $sourceIds = array_unique(array_column($attendances, 'source_student_id')); - $studentMap = Student::whereIn('source_id', $sourceIds) + \$students = Student::whereIn('source_id', $sourceIds) ->where('is_active', true) - ->pluck('id', 'source_id'); + ->get(['id', 'source_id', 'class_name']); + $studentMap = $students->pluck('id', 'source_id'); + $classNameMap = $students->pluck('class_name', 'id'); $alphaCounts = []; $alphaDate = null; @@ -88,6 +90,7 @@ class AttendanceSyncController extends Controller ], [ 'status' => $localStatus, + 'class_name' => $classNameMap[$localStudentId] ?? null, 'notes' => $item['notes'] ?? null, 'recorded_by' => null, ] diff --git a/app/Http/Controllers/AttendanceController.php b/app/Http/Controllers/AttendanceController.php index 9c26d0e..57fbee0 100644 --- a/app/Http/Controllers/AttendanceController.php +++ b/app/Http/Controllers/AttendanceController.php @@ -162,6 +162,7 @@ class AttendanceController extends Controller ], [ 'status' => $data['status'], + 'class_name' => $class_name, 'recorded_by' => $request->user()->id, ] ); diff --git a/app/Models/Attendance.php b/app/Models/Attendance.php index 43ca8e8..bc1eaf2 100644 --- a/app/Models/Attendance.php +++ b/app/Models/Attendance.php @@ -8,7 +8,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; class Attendance extends Model { protected $fillable = [ - 'student_id', 'date', 'lesson_hour', + 'student_id', 'class_name', 'date', 'lesson_hour', 'status', 'notes', 'recorded_by', ]; diff --git a/app/Models/Violation.php b/app/Models/Violation.php index 88a1fa1..9a1ddd1 100644 --- a/app/Models/Violation.php +++ b/app/Models/Violation.php @@ -12,7 +12,7 @@ class Violation extends Model use SoftDeletes; protected $fillable = [ - 'student_id', 'violation_type_id', 'recorded_by', + 'student_id', 'student_class', 'violation_type_id', 'recorded_by', 'description', 'points', 'sanction', 'location', 'violation_date', 'violation_time', 'is_verified', 'verified_by', 'verified_at', diff --git a/app/Services/ViolationService.php b/app/Services/ViolationService.php index b484ec2..e6c13d1 100644 --- a/app/Services/ViolationService.php +++ b/app/Services/ViolationService.php @@ -19,6 +19,7 @@ class ViolationService $violation = DB::transaction(function () use ($data, $userId) { $violation = Violation::create([ 'student_id' => $data['student_id'], + 'student_class' => \App\Models\Student::where('id', $data['student_id'])->value('class_name'), 'violation_type_id' => $data['violation_type_id'], 'recorded_by' => $userId, 'description' => $data['description'] ?? null, diff --git a/database/migrations/2026_07_24_183600_add_class_name_to_attendance_and_violations.php b/database/migrations/2026_07_24_183600_add_class_name_to_attendance_and_violations.php new file mode 100644 index 0000000..ab220b5 --- /dev/null +++ b/database/migrations/2026_07_24_183600_add_class_name_to_attendance_and_violations.php @@ -0,0 +1,44 @@ +string('class_name', 100)->nullable()->after('student_id'); + }); + + // Add student_class to violations (can't use 'class' — reserved word) + Schema::table('violations', function (Blueprint $table) { + $table->string('student_class', 100)->nullable()->after('student_id'); + }); + + // Backfill existing records with current student class_name + DB::statement("UPDATE attendances a + JOIN students s ON s.id = a.student_id + SET a.class_name = s.class_name + WHERE a.class_name IS NULL"); + + DB::statement("UPDATE violations v + JOIN students s ON s.id = v.student_id + SET v.student_class = s.class_name + WHERE v.student_class IS NULL"); + } + + public function down(): void + { + Schema::table('attendances', function (Blueprint $table) { + $table->dropColumn('class_name'); + }); + + Schema::table('violations', function (Blueprint $table) { + $table->dropColumn('student_class'); + }); + } +};