fix: anti-duplikat pelanggaran alpha dari push ulang E-Jurnal

Setiap kali E-Jurnal push ulang (misal edit jurnal), sistem
sekarang cek dulu apakah sudah ada pelanggaran alpha untuk
(student_id + violation_type_id + violation_date) dengan
recorded_by = NULL (system-generated).

- Jika sudah ada: update points + description
- Jika belum: buat baru via ViolationService

Ini mencegah akumulasi pelanggaran duplikat tiap kali guru
mengedit jurnal di E-Jurnal.
This commit is contained in:
Bro
2026-07-24 13:33:35 +07:00
parent a5db795eda
commit f184f43df7
@@ -107,7 +107,7 @@ class AttendanceSyncController extends Controller
} }
} }
// Auto-generate violations via service (includes realtime notifications) // Auto-generate / update violations for alpha students
if (!empty($alphaCounts)) { if (!empty($alphaCounts)) {
$alphaType = ViolationType::where('slug', 'alpha')->first(); $alphaType = ViolationType::where('slug', 'alpha')->first();
@@ -115,18 +115,40 @@ class AttendanceSyncController extends Controller
$violationService = app(\App\Services\ViolationService::class); $violationService = app(\App\Services\ViolationService::class);
foreach ($alphaCounts as $studentId => $count) { foreach ($alphaCounts as $studentId => $count) {
try { try {
$violationService->recordViolation([ $points = max(1, (int) round(($alphaType->points / 10) * $count));
'student_id' => $studentId, $desc = "Alpha - Tidak hadir tanpa keterangan ({$count} jam pelajaran)";
'violation_type_id' => $alphaType->id,
'violation_date' => $alphaDate, // Cek apakah sudah ada pelanggaran alpha untuk siswa+ tanggal+type yang sama
'points' => max(1, (int) round(($alphaType->points / 10) * $count)), // (system-generated: recorded_by IS NULL)
'description' => "Alpha - Tidak hadir tanpa keterangan ({$count} jam pelajaran)", $existing = \App\Models\Violation::where('student_id', $studentId)
'notes' => 'Dibuat otomatis dari sinkron E-Jurnal.', ->where('violation_type_id', $alphaType->id)
'evidences' => [], ->where('violation_date', $alphaDate)
], null); ->whereNull('recorded_by')
$results['violations']++; ->first();
if ($existing) {
// Update existing violation (points & description mungkin berubah)
$existing->update([
'points' => $points,
'description' => $desc,
'notes' => 'Diperbarui otomatis dari sinkron E-Jurnal.',
]);
$results['violations']++;
} else {
// Buat baru (via service biar notifikasi & SP threshold jalan)
$violationService->recordViolation([
'student_id' => $studentId,
'violation_type_id' => $alphaType->id,
'violation_date' => $alphaDate,
'points' => $points,
'description' => $desc,
'notes' => 'Dibuat otomatis dari sinkron E-Jurnal.',
'evidences' => [],
], null);
$results['violations']++;
}
} catch (\Exception $e) { } catch (\Exception $e) {
$results['errors'][] = "Violation creation failed for student={$studentId}: " . $e->getMessage(); $results['errors'][] = "Violation failed for student={$studentId}: " . $e->getMessage();
} }
} }
} else { } else {