prepare($sql); $stmt->execute($params); $rows = $stmt->fetchAll(); // Hitung unread $unreadStmt = $db->prepare("SELECT COUNT(*) FROM notifikasi WHERE sudah_dibaca = 0 AND (user_id = ? OR user_id IS NULL)"); $unreadStmt->execute([$userId ?? 0]); $unreadCount = (int)$unreadStmt->fetchColumn(); jsonResponse(['success' => true, 'data' => $rows, 'unread_count' => $unreadCount]); break; // ════════════════════════════════════════════════════════ // PUT – Tandai sudah dibaca // ════════════════════════════════════════════════════════ case 'PUT': $in = getInput(); $id = $in['id'] ?? 'all'; if ($id === 'all') { $userId = (int)($in['user_id'] ?? 0); $db->prepare("UPDATE notifikasi SET sudah_dibaca = 1 WHERE user_id = ? OR user_id IS NULL") ->execute([$userId]); jsonResponse(['success' => true, 'message' => 'Semua notifikasi ditandai dibaca']); } else { $db->prepare("UPDATE notifikasi SET sudah_dibaca = 1 WHERE id = ?") ->execute([(int)$id]); jsonResponse(['success' => true, 'message' => 'Notifikasi ditandai dibaca']); } break; // ════════════════════════════════════════════════════════ // POST – Buat notifikasi manual // ════════════════════════════════════════════════════════ case 'POST': $in = getInput(); if (empty($in['judul']) || empty($in['pesan'])) { jsonResponse(['success' => false, 'error' => 'Judul dan pesan wajib diisi'], 400); } $db->prepare(" INSERT INTO notifikasi (user_id, jenis, judul, pesan, penduduk_id) VALUES (?,?,?,?,?) ")->execute([ $in['user_id'] ?? null, $in['jenis'] ?? 'info', $in['judul'], $in['pesan'], $in['penduduk_id'] ?? null, ]); jsonResponse(['success' => true, 'id' => $db->lastInsertId(), 'message' => 'Notifikasi dibuat']); break; default: jsonResponse(['success' => false, 'error' => 'Method tidak diizinkan'], 405); } // ============================================================ // FUNGSI: Generate notifikasi otomatis // ============================================================ function generateNotifikasi(PDO $db): void { // 1. KK belum terverifikasi $belumVerif = $db->query(" SELECT id, nama_kk FROM penduduk_miskin WHERE status_verifikasi = 'belum_diverifikasi' AND id NOT IN ( SELECT DISTINCT penduduk_id FROM notifikasi WHERE jenis = 'belum_verifikasi' AND sudah_dibaca = 0 ) LIMIT 20 ")->fetchAll(); foreach ($belumVerif as $p) { $db->prepare(" INSERT INTO notifikasi (jenis, judul, pesan, penduduk_id) VALUES ('belum_verifikasi','Data Menunggu Verifikasi',?,?) ")->execute(["KK {$p['nama_kk']} belum diverifikasi.", $p['id']]); } // 2. KK belum menerima bantuan apapun (sangat miskin) $belumBantuan = $db->query(" SELECT id, nama_kk FROM penduduk_miskin WHERE kategori_kemiskinan = 'sangat_miskin' AND id NOT IN ( SELECT penduduk_id FROM bantuan_penduduk WHERE status = 'aktif' ) AND id NOT IN ( SELECT DISTINCT penduduk_id FROM notifikasi WHERE jenis = 'belum_bantuan' AND sudah_dibaca = 0 ) LIMIT 20 ")->fetchAll(); foreach ($belumBantuan as $p) { $db->prepare(" INSERT INTO notifikasi (jenis, judul, pesan, penduduk_id) VALUES ('belum_bantuan','KK Sangat Miskin Tanpa Bantuan',?,?) ")->execute(["KK {$p['nama_kk']} berkategori sangat miskin namun belum menerima bantuan apapun.", $p['id']]); } // 3. Data usang (tidak diupdate > DATA_USANG_HARI hari) $usang = $db->prepare(" SELECT id, nama_kk, DATEDIFF(NOW(), updated_at) AS hari_usang FROM penduduk_miskin WHERE updated_at < DATE_SUB(NOW(), INTERVAL ? DAY) AND id NOT IN ( SELECT DISTINCT penduduk_id FROM notifikasi WHERE jenis = 'data_usang' AND sudah_dibaca = 0 ) LIMIT 10 "); $usang->execute([DATA_USANG_HARI]); foreach ($usang->fetchAll() as $p) { $db->prepare(" INSERT INTO notifikasi (jenis, judul, pesan, penduduk_id) VALUES ('data_usang','Data Tidak Diperbarui',?,?) ")->execute(["Data KK {$p['nama_kk']} belum diperbarui selama {$p['hari_usang']} hari.", $p['id']]); } }