fix: anti-duplikat violation di input manual presensi

Sama seperti fix di sync controller:
- Cek existing violation (student_id + type + date + recorded_by)
- Ada alpha → update atau create
- Tidak alpha → hapus violation lama
- Berlaku untuk alpha dan terlambat
- Mencegah duplikat tiap kali admin submit ulang form
This commit is contained in:
Bro
2026-07-24 17:32:22 +07:00
parent 3aa84387f3
commit a867b3a267
+65 -25
View File
@@ -156,37 +156,77 @@ class AttendanceController extends Controller
} }
} }
// Auto-generate violation untuk alpha & terlambat // Auto-generate / update / hapus violation (anti-duplikat)
if ($request->boolean('auto_violation') && (!empty($alphaIds) || !empty($terlambatIds))) { if ($request->boolean('auto_violation')) {
$alphaType = ViolationType::where('slug', 'alpha')->first(); $alphaType = ViolationType::where('slug', 'alpha')->first();
$terlambatType = ViolationType::where('slug', 'terlambat')->first(); $terlambatType = ViolationType::where('slug', 'terlambat')->first();
$userId = $request->user()->id;
foreach ($alphaIds as $studentId => $count) { // Kumpulkan semua student yang ada di form
if ($alphaType) { $allStudentsInForm = array_keys($request->input('attendances', []));
$this->violationService->recordViolation([
'student_id' => $studentId, // Proses alpha
'violation_type_id' => $alphaType->id, if ($alphaType) {
'violation_date' => $date, foreach ($allStudentsInForm as $studentId) {
'points' => max(1, (int) round(($alphaType->points / 10) * $count)), $count = $alphaIds[$studentId] ?? 0;
'description' => "Alpha - Tidak hadir tanpa keterangan ({$count} jam pelajaran)", $existing = \App\Models\Violation::where('student_id', $studentId)
'notes' => 'Dibuat otomatis dari presensi.', ->where('violation_type_id', $alphaType->id)
'evidences' => [], ->where('violation_date', $date)
], $request->user()->id); ->where('recorded_by', $userId)
$autoViolations++; ->first();
if ($count > 0) {
$points = max(1, (int) round(($alphaType->points / 10) * $count));
$desc = "Alpha - Tidak hadir tanpa keterangan ({$count} jam pelajaran)";
if ($existing) {
$existing->update(['points' => $points, 'description' => $desc, 'notes' => 'Diperbarui otomatis dari presensi.']);
} else {
$this->violationService->recordViolation([
'student_id' => $studentId,
'violation_type_id' => $alphaType->id,
'violation_date' => $date,
'points' => $points,
'description' => $desc,
'notes' => 'Dibuat otomatis dari presensi.',
'evidences' => [],
], $userId);
}
$autoViolations++;
} elseif ($existing) {
// Tidak alpha lagi tapi ada violation lama → hapus
$existing->delete();
$autoViolations++;
}
} }
} }
foreach ($terlambatIds as $studentId => $count) { // Proses terlambat (similar logic, tanpa delete karena terlambat per event)
if ($terlambatType) { if ($terlambatType) {
$this->violationService->recordViolation([ foreach ($terlambatIds as $studentId => $count) {
'student_id' => $studentId, $existing = \App\Models\Violation::where('student_id', $studentId)
'violation_type_id' => $terlambatType->id, ->where('violation_type_id', $terlambatType->id)
'violation_date' => $date, ->where('violation_date', $date)
'points' => $terlambatType->points, ->where('recorded_by', $userId)
'description' => "Terlambat ({$count} jam pelajaran)", ->first();
'notes' => 'Dibuat otomatis dari presensi.',
'evidences' => [], if ($existing) {
], $request->user()->id); $existing->update([
'points' => $terlambatType->points,
'description' => "Terlambat ({$count} jam pelajaran)",
'notes' => 'Diperbarui otomatis dari presensi.',
]);
} else {
$this->violationService->recordViolation([
'student_id' => $studentId,
'violation_type_id' => $terlambatType->id,
'violation_date' => $date,
'points' => $terlambatType->points,
'description' => "Terlambat ({$count} jam pelajaran)",
'notes' => 'Dibuat otomatis dari presensi.',
'evidences' => [],
], $userId);
}
$autoViolations++; $autoViolations++;
} }
} }