fix: hapus violation jika status berubah dari alpha ke hadir

Sebelumnya violation hanya di-create/update, tidak pernah
dihapus. Jika guru edit jurnal dari alpha jadi hadir, violation
lama tetap ada.

Sekarang: untuk setiap siswa dalam push, sistem cek:
- alpha > 0: create/update violation
- alpha = 0 & ada violation lama: hapus (soft delete)
- siswa tidak ada di push: violation tidak disentuh
This commit is contained in:
Bro
2026-07-24 13:38:41 +07:00
parent f184f43df7
commit 3aa84387f3
@@ -57,6 +57,7 @@ class AttendanceSyncController extends Controller
$alphaCounts = []; $alphaCounts = [];
$alphaDate = null; $alphaDate = null;
$allStudentIdsInPush = []; // track all students for cleanup
foreach ($attendances as $item) { foreach ($attendances as $item) {
$sourceId = $item['source_student_id']; $sourceId = $item['source_student_id'];
@@ -68,6 +69,7 @@ class AttendanceSyncController extends Controller
} }
$localStudentId = $studentMap[$sourceId]; $localStudentId = $studentMap[$sourceId];
$allStudentIdsInPush[$localStudentId] = true;
$statusMap = [ $statusMap = [
'present' => 'hadir', 'present' => 'hadir',
@@ -107,35 +109,35 @@ class AttendanceSyncController extends Controller
} }
} }
// Auto-generate / update violations for alpha students // Auto-generate / update / hapus violations untuk alpha siswa di push ini
if (!empty($alphaCounts)) {
$alphaType = ViolationType::where('slug', 'alpha')->first(); $alphaType = ViolationType::where('slug', 'alpha')->first();
if ($alphaType) { if ($alphaType) {
$violationService = app(\App\Services\ViolationService::class); $violationService = app(\App\Services\ViolationService::class);
foreach ($alphaCounts as $studentId => $count) {
try {
$points = max(1, (int) round(($alphaType->points / 10) * $count));
$desc = "Alpha - Tidak hadir tanpa keterangan ({$count} jam pelajaran)";
// Cek apakah sudah ada pelanggaran alpha untuk siswa+ tanggal+type yang sama foreach ($allStudentIdsInPush as $studentId => $_) {
// (system-generated: recorded_by IS NULL) try {
$count = $alphaCounts[$studentId] ?? 0;
// Cari existing system-generated violation
$existing = \App\Models\Violation::where('student_id', $studentId) $existing = \App\Models\Violation::where('student_id', $studentId)
->where('violation_type_id', $alphaType->id) ->where('violation_type_id', $alphaType->id)
->where('violation_date', $alphaDate) ->where('violation_date', $alphaDate)
->whereNull('recorded_by') ->whereNull('recorded_by')
->first(); ->first();
if ($count > 0) {
// Ada alpha → buat/update violation
$points = max(1, (int) round(($alphaType->points / 10) * $count));
$desc = "Alpha - Tidak hadir tanpa keterangan ({$count} jam pelajaran)";
if ($existing) { if ($existing) {
// Update existing violation (points & description mungkin berubah)
$existing->update([ $existing->update([
'points' => $points, 'points' => $points,
'description' => $desc, 'description' => $desc,
'notes' => 'Diperbarui otomatis dari sinkron E-Jurnal.', 'notes' => 'Diperbarui otomatis dari sinkron E-Jurnal.',
]); ]);
$results['violations']++;
} else { } else {
// Buat baru (via service biar notifikasi & SP threshold jalan)
$violationService->recordViolation([ $violationService->recordViolation([
'student_id' => $studentId, 'student_id' => $studentId,
'violation_type_id' => $alphaType->id, 'violation_type_id' => $alphaType->id,
@@ -145,16 +147,20 @@ class AttendanceSyncController extends Controller
'notes' => 'Dibuat otomatis dari sinkron E-Jurnal.', 'notes' => 'Dibuat otomatis dari sinkron E-Jurnal.',
'evidences' => [], 'evidences' => [],
], null); ], null);
}
$results['violations']++;
} elseif ($existing) {
// Tidak ada alpha tapi ada violation lama → hapus (ganti status ke hadir)
$existing->delete();
$results['violations']++; $results['violations']++;
} }
} catch (\Exception $e) { } catch (\Exception $e) {
$results['errors'][] = "Violation failed for student={$studentId}: " . $e->getMessage(); $results['errors'][] = "Violation sync failed for student={$studentId}: " . $e->getMessage();
} }
} }
} else { } else {
$results['errors'][] = 'Violation type "Alpha" not found. Create a violation type with slug "alpha".'; $results['errors'][] = 'Violation type "Alpha" not found. Create a violation type with slug "alpha".';
} }
}
return response()->json([ return response()->json([
'success' => true, 'success' => true,