prepare("SELECT k.*, ri.nama as ri_nama, ri.jenis as ri_jenis FROM keluarga k LEFT JOIN rumah_ibadah ri ON ri.id=k.rumah_ibadah_id WHERE k.id=?"); $st->execute([$id]); $row = $st->fetch(); if (!$row) jsonErr('Tidak ditemukan.', 404); // anggota keluarga $an = $db->prepare("SELECT id,nik,nama,jenis_kelamin,umur,profil_umur, status_keluarga,status_perkawinan,status_ekonomi, kondisi_kesehatan,pekerjaan,penghasilan, status_pendidikan,pendidikan_terakhir FROM penduduk WHERE keluarga_id=? AND status_hidup='hidup' ORDER BY FIELD(status_keluarga,'kepala','istri','anak','orang_tua','lainnya')"); $an->execute([$id]); $row['anggota'] = $an->fetchAll(); jsonOk($row); break; } $where = []; $params = []; if (!empty($_GET['status_ekonomi'])) { $where[] = "k.status_ekonomi=?"; $params[] = $_GET['status_ekonomi']; } if (!empty($_GET['kelurahan'])) { $where[] = "k.kelurahan=?"; $params[] = $_GET['kelurahan']; } if (!empty($_GET['rumah_ibadah_id'])) { $where[] = "k.rumah_ibadah_id=?"; $params[] = (int)$_GET['rumah_ibadah_id']; } if (!empty($_GET['q'])) { $where[] = "(k.nama_kk LIKE ? OR k.no_kk LIKE ?)"; $params[] = '%'.$_GET['q'].'%'; $params[] = '%'.$_GET['q'].'%'; } $wStr = $where ? 'WHERE '.implode(' AND ',$where) : ''; $st = $db->prepare("SELECT k.id, k.no_kk, k.nama_kk, k.alamat, k.rt, k.rw, k.kelurahan, k.kecamatan, k.lat, k.lng, k.status_ekonomi, ri.nama as ri_nama, (SELECT COUNT(*) FROM penduduk p WHERE p.keluarga_id=k.id AND p.status_hidup='hidup') as jumlah_jiwa, (SELECT COUNT(*) FROM histori_bantuan hb JOIN penduduk p ON p.id=hb.penduduk_id WHERE p.keluarga_id=k.id AND hb.status='disalurkan') as total_bantuan_diterima FROM keluarga k LEFT JOIN rumah_ibadah ri ON ri.id=k.rumah_ibadah_id $wStr ORDER BY k.nama_kk ASC LIMIT 500"); $st->execute($params); jsonOk($st->fetchAll()); break; case 'POST': requireRole(['superadmin','pengurus','relawan']); $b = json_decode(file_get_contents('php://input'), true); $no_kk = sanitize($b['no_kk'] ?? ''); $nama_kk = sanitize($b['nama_kk'] ?? ''); if (!$no_kk || !$nama_kk) jsonErr('No KK dan nama KK wajib diisi.'); if (strlen($no_kk) !== 16) jsonErr('No KK harus 16 digit.'); $chk = $db->prepare("SELECT id FROM keluarga WHERE no_kk=?"); $chk->execute([$no_kk]); if ($chk->fetch()) jsonErr('No KK sudah terdaftar.'); $db->prepare("INSERT INTO keluarga (no_kk,nama_kk,alamat,rt,rw,kelurahan,kecamatan,lat,lng,rumah_ibadah_id,status_ekonomi,created_by) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)") ->execute([ $no_kk, $nama_kk, sanitize($b['alamat'] ?? ''), sanitize($b['rt'] ?? ''), sanitize($b['rw'] ?? ''), sanitize($b['kelurahan'] ?? ''), sanitize($b['kecamatan'] ?? ''), isset($b['lat']) ? (float)$b['lat'] : null, isset($b['lng']) ? (float)$b['lng'] : null, !empty($b['rumah_ibadah_id']) ? (int)$b['rumah_ibadah_id'] : null, $b['status_ekonomi'] ?? 'rentan', $user['id'] ]); $newId = (int)$db->lastInsertId(); log_aksi($user['id'], 'CREATE', 'keluarga', $newId, "Tambah KK: $nama_kk"); jsonOk(['id'=>$newId], 'Keluarga berhasil ditambahkan.'); break; case 'PUT': requireRole(['superadmin','pengurus','relawan']); if (!$id) jsonErr('ID tidak valid.'); $b = json_decode(file_get_contents('php://input'), true); $db->prepare("UPDATE keluarga SET nama_kk=?,alamat=?,rt=?,rw=?,kelurahan=?,kecamatan=?, lat=?,lng=?,rumah_ibadah_id=?,status_ekonomi=?,updated_at=NOW() WHERE id=?") ->execute([ sanitize($b['nama_kk'] ?? ''), sanitize($b['alamat'] ?? ''), sanitize($b['rt'] ?? ''), sanitize($b['rw'] ?? ''), sanitize($b['kelurahan'] ?? ''), sanitize($b['kecamatan'] ?? ''), isset($b['lat']) ? (float)$b['lat'] : null, isset($b['lng']) ? (float)$b['lng'] : null, !empty($b['rumah_ibadah_id']) ? (int)$b['rumah_ibadah_id'] : null, $b['status_ekonomi'] ?? 'rentan', $id ]); log_aksi($user['id'], 'UPDATE', 'keluarga', $id, "Edit KK ID: $id"); jsonOk(null, 'Data keluarga diperbarui.'); break; case 'DELETE': requireRole(['superadmin']); if (!$id) jsonErr('ID tidak valid.'); $db->prepare("DELETE FROM keluarga WHERE id=?")->execute([$id]); log_aksi($user['id'], 'DELETE', 'keluarga', $id, "Hapus KK ID: $id"); jsonOk(null, 'Data keluarga dihapus.'); break; default: jsonErr('Method tidak didukung.', 405); }