286 lines
11 KiB
PHP
286 lines
11 KiB
PHP
<?php
|
|
// ============================================================
|
|
// API: Keluarga Miskin (CRUD + Filter + Auto-assign)
|
|
// GET: publik | POST: admin+pengurus | PUT: admin+pengurus | DELETE: admin
|
|
// ============================================================
|
|
require_once __DIR__ . '/config.php';
|
|
|
|
$method = $_SERVER['REQUEST_METHOD'];
|
|
|
|
// Blokir aksi tulis walikota
|
|
blockWalikotaWrite();
|
|
|
|
// ── GET: Ambil semua (dengan filter) atau satu KK ────────────
|
|
if ($method === 'GET') {
|
|
$id = isset($_GET['id']) ? (int)$_GET['id'] : null;
|
|
|
|
if ($id) {
|
|
// Ambil satu KK beserta info rumah ibadah terkait
|
|
$stmt = $pdo->prepare("
|
|
SELECT km.*, ri.nama AS nama_ri, ri.jenis AS jenis_ri, ri.kode_pengurus,
|
|
COALESCE((SELECT SUM(hb.nominal) FROM histori_bantuan hb WHERE hb.kk_id = km.id), 0) AS total_bantuan
|
|
FROM keluarga_miskin km
|
|
LEFT JOIN rumah_ibadah ri ON km.rumah_ibadah_id = ri.id
|
|
WHERE km.id = ?
|
|
");
|
|
$stmt->execute([$id]);
|
|
$row = $stmt->fetch();
|
|
|
|
if (!$row) {
|
|
jsonResponse(null, 'Data keluarga miskin tidak ditemukan.', false, 404);
|
|
}
|
|
|
|
// Cek akses pengurus — hanya boleh lihat KK binaan miliknya
|
|
$sess = $_SESSION['user'] ?? null;
|
|
if ($sess && $sess['role'] === 'pengurus') {
|
|
if ((int)($row['rumah_ibadah_id'] ?? 0) !== (int)$sess['rumah_ibadah_id']) {
|
|
jsonResponse(null, 'Akses ditolak. KK ini bukan binaan Anda.', false, 403);
|
|
}
|
|
}
|
|
|
|
// Decode riwayat_penyakit JSON
|
|
$row['riwayat_penyakit'] = json_decode($row['riwayat_penyakit'] ?? '[]', true);
|
|
|
|
// Flag eligible_bansos_tunai: hanya untuk KK dengan status_dtks = 'Belum DTKS'
|
|
$row['eligible_bansos_tunai'] = ($row['status_dtks'] === 'Belum DTKS');
|
|
|
|
// Format total_bantuan
|
|
$row['total_bantuan_formatted'] = 'Rp ' . number_format((int)$row['total_bantuan'], 0, ',', '.');
|
|
|
|
jsonResponse($row, 'Data keluarga miskin ditemukan.');
|
|
}
|
|
|
|
// ── Ambil semua dengan filter ──
|
|
$where = [];
|
|
$params = [];
|
|
|
|
// Filter berdasarkan role pengurus
|
|
$sess = $_SESSION['user'] ?? null;
|
|
if ($sess && $sess['role'] === 'pengurus' && !empty($sess['rumah_ibadah_id'])) {
|
|
$where[] = 'km.rumah_ibadah_id = ?';
|
|
$params[] = (int)$sess['rumah_ibadah_id'];
|
|
}
|
|
|
|
// Filter kecamatan
|
|
if (!empty($_GET['kecamatan'])) {
|
|
$where[] = 'km.kecamatan = ?';
|
|
$params[] = clean($_GET['kecamatan']);
|
|
}
|
|
|
|
// Filter tingkat_kemiskinan
|
|
if (!empty($_GET['tingkat_kemiskinan'])) {
|
|
$where[] = 'km.tingkat_kemiskinan = ?';
|
|
$params[] = clean($_GET['tingkat_kemiskinan']);
|
|
}
|
|
|
|
// Filter status_dtks
|
|
if (!empty($_GET['status_dtks'])) {
|
|
$where[] = 'km.status_dtks = ?';
|
|
$params[] = clean($_GET['status_dtks']);
|
|
}
|
|
|
|
// Filter rumah_ibadah_id
|
|
if (isset($_GET['rumah_ibadah_id']) && $_GET['rumah_ibadah_id'] !== '') {
|
|
$where[] = 'km.rumah_ibadah_id = ?';
|
|
$params[] = (int)$_GET['rumah_ibadah_id'];
|
|
}
|
|
|
|
$sql = "
|
|
SELECT km.*, ri.nama AS nama_ri, ri.jenis AS jenis_ri,
|
|
COALESCE((SELECT SUM(hb.nominal) FROM histori_bantuan hb WHERE hb.kk_id = km.id), 0) AS total_bantuan
|
|
FROM keluarga_miskin km
|
|
LEFT JOIN rumah_ibadah ri ON km.rumah_ibadah_id = ri.id
|
|
";
|
|
if (!empty($where)) {
|
|
$sql .= ' WHERE ' . implode(' AND ', $where);
|
|
}
|
|
$sql .= ' ORDER BY km.nama_kepala_keluarga ASC';
|
|
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute($params);
|
|
$rows = $stmt->fetchAll();
|
|
|
|
// Proses setiap baris: decode JSON + flag eligible + format total
|
|
foreach ($rows as &$r) {
|
|
$r['riwayat_penyakit'] = json_decode($r['riwayat_penyakit'] ?? '[]', true);
|
|
$r['eligible_bansos_tunai'] = ($r['status_dtks'] === 'Belum DTKS');
|
|
$r['total_bantuan_formatted'] = 'Rp ' . number_format((int)$r['total_bantuan'], 0, ',', '.');
|
|
}
|
|
|
|
jsonResponse($rows, 'Daftar keluarga miskin.', true, 200);
|
|
}
|
|
|
|
// ── POST: Tambah KK (admin + pengurus) ───────────────────────
|
|
if ($method === 'POST') {
|
|
$user = requireRole(['admin', 'pengurus']);
|
|
$body = json_decode(file_get_contents('php://input'), true) ?? [];
|
|
|
|
// Validasi input
|
|
$nik = clean($body['nik'] ?? '');
|
|
$nama_kepala_keluarga = clean($body['nama_kepala_keluarga'] ?? '');
|
|
$tanggal_lahir = clean($body['tanggal_lahir'] ?? '');
|
|
$pendidikan = clean($body['pendidikan'] ?? 'Tidak Sekolah');
|
|
$jumlah_anggota = (int)($body['jumlah_anggota'] ?? 1);
|
|
$alamat = clean($body['alamat'] ?? '');
|
|
$kecamatan = clean($body['kecamatan'] ?? '');
|
|
$lat = (float)($body['lat'] ?? 0);
|
|
$lng = (float)($body['lng'] ?? 0);
|
|
$tingkat_kemiskinan = clean($body['tingkat_kemiskinan'] ?? 'Miskin');
|
|
$status_dtks = clean($body['status_dtks'] ?? 'Belum DTKS');
|
|
$riwayat_penyakit = $body['riwayat_penyakit'] ?? [];
|
|
|
|
if (!$nik || !$nama_kepala_keluarga || !$alamat || !$kecamatan || !$lat || !$lng) {
|
|
jsonResponse(null, 'NIK, nama KK, alamat, kecamatan, dan koordinat wajib diisi.', false, 400);
|
|
}
|
|
|
|
// Cek NIK unik
|
|
$stmt = $pdo->prepare("SELECT id FROM keluarga_miskin WHERE nik = ? LIMIT 1");
|
|
$stmt->execute([$nik]);
|
|
if ($stmt->fetch()) {
|
|
jsonResponse(null, 'NIK sudah terdaftar dalam sistem.', false, 400);
|
|
}
|
|
|
|
// Auto-assign ke rumah ibadah terdekat dalam radius
|
|
$assign = autoAssign($pdo, $lat, $lng);
|
|
$riId = $assign['rumah_ibadah_id'];
|
|
$jarakKm = $assign['jarak_km'];
|
|
$riwayatJson = json_encode(is_array($riwayat_penyakit) ? $riwayat_penyakit : []);
|
|
|
|
// Pengurus: paksa assign ke RI miliknya (jika dalam radius)
|
|
if ($user['role'] === 'pengurus') {
|
|
$riId = (int)$user['rumah_ibadah_id'];
|
|
// Hitung jarak ke RI miliknya
|
|
$stRi = $pdo->prepare("SELECT lat, lng FROM rumah_ibadah WHERE id = ?");
|
|
$stRi->execute([$riId]);
|
|
$riData = $stRi->fetch();
|
|
$jarakKm = $riData ? haversine($lat, $lng, (float)$riData['lat'], (float)$riData['lng']) : null;
|
|
}
|
|
|
|
$stmt = $pdo->prepare("
|
|
INSERT INTO keluarga_miskin
|
|
(nik, nama_kepala_keluarga, tanggal_lahir, pendidikan, jumlah_anggota,
|
|
alamat, kecamatan, lat, lng, tingkat_kemiskinan, status_dtks,
|
|
riwayat_penyakit, rumah_ibadah_id, jarak_ke_ibadah)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
");
|
|
$stmt->execute([
|
|
$nik, $nama_kepala_keluarga,
|
|
$tanggal_lahir ?: null, $pendidikan, $jumlah_anggota,
|
|
$alamat, $kecamatan, $lat, $lng,
|
|
$tingkat_kemiskinan, $status_dtks,
|
|
$riwayatJson, $riId, $jarakKm
|
|
]);
|
|
|
|
$newId = (int)$pdo->lastInsertId();
|
|
|
|
$assignMsg = $riId
|
|
? "Auto-assign ke rumah ibadah (jarak: {$jarakKm} km)."
|
|
: "Tidak ada rumah ibadah dalam radius cakupan.";
|
|
|
|
jsonResponse([
|
|
'id' => $newId,
|
|
'rumah_ibadah_id' => $riId,
|
|
'jarak_km' => $jarakKm,
|
|
], 'Data keluarga miskin berhasil ditambahkan. ' . $assignMsg);
|
|
}
|
|
|
|
// ── PUT: Update KK ───────────────────────────────────────────
|
|
if ($method === 'PUT') {
|
|
$user = requireRole(['admin', 'pengurus']);
|
|
$body = json_decode(file_get_contents('php://input'), true) ?? [];
|
|
$id = (int)($body['id'] ?? 0);
|
|
|
|
if (!$id) {
|
|
jsonResponse(null, 'ID keluarga miskin wajib diisi.', false, 400);
|
|
}
|
|
|
|
// Cek data ada
|
|
$stmt = $pdo->prepare("SELECT rumah_ibadah_id FROM keluarga_miskin WHERE id = ? LIMIT 1");
|
|
$stmt->execute([$id]);
|
|
$existing = $stmt->fetch();
|
|
|
|
if (!$existing) {
|
|
jsonResponse(null, 'Data keluarga miskin tidak ditemukan.', false, 404);
|
|
}
|
|
|
|
// Pengurus hanya bisa edit KK dalam RI-nya
|
|
if ($user['role'] === 'pengurus') {
|
|
if ((int)($existing['rumah_ibadah_id'] ?? 0) !== (int)$user['rumah_ibadah_id']) {
|
|
jsonResponse(null, 'Anda hanya dapat mengedit KK binaan rumah ibadah Anda.', false, 403);
|
|
}
|
|
}
|
|
|
|
$nik = clean($body['nik'] ?? '');
|
|
$nama_kepala_keluarga = clean($body['nama_kepala_keluarga'] ?? '');
|
|
$tanggal_lahir = clean($body['tanggal_lahir'] ?? '');
|
|
$pendidikan = clean($body['pendidikan'] ?? 'Tidak Sekolah');
|
|
$jumlah_anggota = (int)($body['jumlah_anggota'] ?? 1);
|
|
$alamat = clean($body['alamat'] ?? '');
|
|
$kecamatan = clean($body['kecamatan'] ?? '');
|
|
$lat = (float)($body['lat'] ?? 0);
|
|
$lng = (float)($body['lng'] ?? 0);
|
|
$tingkat_kemiskinan = clean($body['tingkat_kemiskinan'] ?? 'Miskin');
|
|
$status_dtks = clean($body['status_dtks'] ?? 'Belum DTKS');
|
|
$riwayat_penyakit = $body['riwayat_penyakit'] ?? [];
|
|
|
|
if (!$nik || !$nama_kepala_keluarga || !$alamat || !$kecamatan || !$lat || !$lng) {
|
|
jsonResponse(null, 'Semua field wajib diisi.', false, 400);
|
|
}
|
|
|
|
// Cek NIK unik (kecuali milik sendiri)
|
|
$stmt = $pdo->prepare("SELECT id FROM keluarga_miskin WHERE nik = ? AND id != ? LIMIT 1");
|
|
$stmt->execute([$nik, $id]);
|
|
if ($stmt->fetch()) {
|
|
jsonResponse(null, 'NIK sudah digunakan oleh KK lain.', false, 400);
|
|
}
|
|
|
|
// Re-calculate auto-assign
|
|
$assign = autoAssign($pdo, $lat, $lng);
|
|
$riId = $assign['rumah_ibadah_id'];
|
|
$jarakKm = $assign['jarak_km'];
|
|
$riwayatJson = json_encode(is_array($riwayat_penyakit) ? $riwayat_penyakit : []);
|
|
|
|
$stmt = $pdo->prepare("
|
|
UPDATE keluarga_miskin SET
|
|
nik = ?, nama_kepala_keluarga = ?, tanggal_lahir = ?, pendidikan = ?,
|
|
jumlah_anggota = ?, alamat = ?, kecamatan = ?, lat = ?, lng = ?,
|
|
tingkat_kemiskinan = ?, status_dtks = ?, riwayat_penyakit = ?,
|
|
rumah_ibadah_id = ?, jarak_ke_ibadah = ?
|
|
WHERE id = ?
|
|
");
|
|
$stmt->execute([
|
|
$nik, $nama_kepala_keluarga,
|
|
$tanggal_lahir ?: null, $pendidikan, $jumlah_anggota,
|
|
$alamat, $kecamatan, $lat, $lng,
|
|
$tingkat_kemiskinan, $status_dtks, $riwayatJson,
|
|
$riId, $jarakKm, $id
|
|
]);
|
|
|
|
jsonResponse([
|
|
'rumah_ibadah_id' => $riId,
|
|
'jarak_km' => $jarakKm,
|
|
], 'Data keluarga miskin berhasil diperbarui.');
|
|
}
|
|
|
|
// ── DELETE: Hapus KK (admin only) ────────────────────────────
|
|
if ($method === 'DELETE') {
|
|
$user = requireRole(['admin']);
|
|
$id = (int)($_GET['id'] ?? 0);
|
|
|
|
if (!$id) {
|
|
jsonResponse(null, 'ID keluarga miskin wajib diisi.', false, 400);
|
|
}
|
|
|
|
$stmt = $pdo->prepare("DELETE FROM keluarga_miskin WHERE id = ?");
|
|
$stmt->execute([$id]);
|
|
|
|
if ($stmt->rowCount() === 0) {
|
|
jsonResponse(null, 'Data tidak ditemukan.', false, 404);
|
|
}
|
|
|
|
jsonResponse(null, 'Data keluarga miskin berhasil dihapus.');
|
|
}
|
|
|
|
// ── Method tidak didukung ────────────────────────────────────
|
|
jsonResponse(null, 'Method tidak didukung.', false, 405);
|