Files
D1041231084_WebGis_GeoPoverty/api/warga.php
T
2026-06-11 21:20:59 +07:00

261 lines
10 KiB
PHP

<?php
// ============================================================
// api/warga.php — CRUD Data Warga (Kepala Keluarga)
// GET ?kat=&kel_id=&kec=&status=aktif — list warga
// POST — tambah warga
// PUT ?id= — update warga
// DELETE ?id= — hapus warga
// ============================================================
require_once __DIR__ . '/config.php';
$method = $_SERVER['REQUEST_METHOD'];
$db = getDB();
// ── GET: list warga dengan filter ──────────────────────────
if ($method === 'GET') {
$where = ["w.status = 'aktif'"];
$params = [];
if ($kat = getParam('kat')) { $where[] = "w.kategori = ?"; $params[] = $kat; }
if ($kid = getParam('kel_id')){ $where[] = "w.kelurahan_id = ?"; $params[] = $kid; }
if ($kec = getParam('kec')) { $where[] = "k.kecamatan = ?"; $params[] = $kec; }
$sql = "SELECT w.id, w.nama, w.nik, w.lat, w.lng, w.kategori,
w.jumlah_anggota, w.penghasilan, w.tgl_lahir, w.pendidikan,
w.keterangan, w.status, w.pelapor, w.no_laporan, w.created_at,
k.id AS kelurahan_id, k.nama AS kelurahan, k.kecamatan
FROM warga w
LEFT JOIN kelurahan k ON w.kelurahan_id = k.id
WHERE " . implode(' AND ', $where) . "
ORDER BY w.created_at DESC";
$stmt = $db->prepare($sql);
$stmt->execute($params);
$wargaList = $stmt->fetchAll();
// Ambil anggota & penyakit untuk setiap warga
foreach ($wargaList as &$w) {
$stmt2 = $db->prepare(
"SELECT a.id, a.nama, a.usia, a.hubungan,
GROUP_CONCAT(rp.penyakit SEPARATOR ',') AS penyakit_csv
FROM anggota_keluarga a
LEFT JOIN riwayat_penyakit rp ON rp.anggota_id = a.id
WHERE a.warga_id = ?
GROUP BY a.id"
);
$stmt2->execute([$w['id']]);
$anggota = $stmt2->fetchAll();
foreach ($anggota as &$a) {
$a['penyakit'] = $a['penyakit_csv'] ? explode(',', $a['penyakit_csv']) : [];
unset($a['penyakit_csv']);
}
$w['anggota'] = $anggota;
// Riwayat penyakit KK (dari anggota dengan nama sama / index 0)
$rp_kk = [];
if (!empty($anggota)) {
$rp_kk = $anggota[0]['penyakit'];
}
$w['riwayat_penyakit'] = $rp_kk;
// Histori bantuan
$stmt3 = $db->prepare(
"SELECT id, tanggal, jenis, nominal, sumber_dana AS sumber, keterangan
FROM histori_bantuan WHERE warga_id = ? ORDER BY tanggal DESC"
);
$stmt3->execute([$w['id']]);
$w['histori_bantuan'] = $stmt3->fetchAll();
}
jsonOk($wargaList);
}
// ── POST: tambah warga ──────────────────────────────────────
if ($method === 'POST') {
requireEdit();
$d = body();
if (empty($d['nama'])) jsonError('Nama wajib diisi.');
if (!isset($d['lat'], $d['lng'])) jsonError('Koordinat lokasi wajib diisi.');
if (empty($d['kelurahan_id'])) jsonError('Kelurahan wajib dipilih.');
$db->beginTransaction();
try {
$stmt = $db->prepare(
"INSERT INTO warga (nama, nik, kelurahan_id, lat, lng, kategori, jumlah_anggota,
penghasilan, tgl_lahir, pendidikan, keterangan, pelapor, no_laporan)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"
);
$stmt->execute([
$d['nama'],
$d['nik'] ?? null,
$d['kelurahan_id'],
$d['lat'],
$d['lng'],
$d['kategori'] ?? 'miskin',
$d['jumlah_anggota'] ?? 1,
$d['penghasilan'] ?? 0,
!empty($d['tgl_lahir']) ? $d['tgl_lahir'] : null,
$d['pendidikan'] ?? '',
$d['keterangan'] ?? '',
$d['pelapor'] ?? null,
$d['no_laporan'] ?? null,
]);
$wargaId = $db->lastInsertId();
// 1. Simpan Kepala Keluarga sebagai anggota keluarga pertama
$usiaKk = 0;
if (!empty($d['tgl_lahir'])) {
try {
$birthDate = new DateTime($d['tgl_lahir']);
$today = new DateTime();
$usiaKk = $today->diff($birthDate)->y;
} catch (Exception $e) {
$usiaKk = 0;
}
}
$stmtKk = $db->prepare(
"INSERT INTO anggota_keluarga (warga_id, nama, usia, hubungan) VALUES (?, ?, ?, 'Kepala Keluarga')"
);
$stmtKk->execute([$wargaId, $d['nama'], $usiaKk]);
$kkAnggotaId = $db->lastInsertId();
$kkPenyakit = $d['rp'] ?? $d['riwayat_penyakit'] ?? [];
foreach ($kkPenyakit as $py) {
if (!$py) continue;
$db->prepare("INSERT INTO riwayat_penyakit (anggota_id, penyakit) VALUES (?, ?)")
->execute([$kkAnggotaId, $py]);
}
// 2. Simpan anggota keluarga lainnya + penyakit mereka
foreach (($d['anggota'] ?? []) as $a) {
if (empty($a['nama'])) continue;
// Hindari duplikasi jika KK dikirim lagi di list anggota
if (strtolower(trim($a['nama'])) === strtolower(trim($d['nama'])) && ($a['hub'] ?? $a['hubungan'] ?? '') === 'Kepala Keluarga') {
continue;
}
$stmtA = $db->prepare(
"INSERT INTO anggota_keluarga (warga_id, nama, usia, hubungan) VALUES (?,?,?,?)"
);
$stmtA->execute([$wargaId, $a['nama'], $a['usia'] ?? 0, $a['hub'] ?? $a['hubungan'] ?? 'Anak']);
$anggotaId = $db->lastInsertId();
foreach (($a['penyakit'] ?? $a['py'] ?? []) as $py) {
if (!$py) continue;
$db->prepare("INSERT INTO riwayat_penyakit (anggota_id, penyakit) VALUES (?,?)")
->execute([$anggotaId, $py]);
}
}
$db->commit();
jsonOk(['id' => $wargaId], 'Data warga berhasil ditambahkan');
} catch (Exception $e) {
$db->rollBack();
jsonError('Gagal menyimpan: ' . $e->getMessage(), 500);
}
}
// ── PUT: update data warga ─────────────────────────────────
if ($method === 'PUT') {
requireEdit();
$id = getParam('id');
if (!$id) jsonError('ID wajib disertakan.');
$d = body();
if (empty($d['nama'])) jsonError('Nama wajib diisi.');
if (!isset($d['lat'], $d['lng'])) jsonError('Koordinat lokasi wajib diisi.');
if (empty($d['kelurahan_id'])) jsonError('Kelurahan wajib dipilih.');
$db->beginTransaction();
try {
// 1. Update data kepala keluarga
$stmt = $db->prepare(
"UPDATE warga SET nama=?, nik=?, kelurahan_id=?, lat=?, lng=?,
kategori=?, jumlah_anggota=?, penghasilan=?,
tgl_lahir=?, pendidikan=?, keterangan=?
WHERE id=?"
);
$stmt->execute([
$d['nama'],
$d['nik'] ?? null,
$d['kelurahan_id'],
$d['lat'],
$d['lng'],
$d['kategori'] ?? 'miskin',
$d['jumlah_anggota'] ?? 1,
$d['penghasilan'] ?? 0,
!empty($d['tgl_lahir']) ? $d['tgl_lahir'] : null,
$d['pendidikan'] ?? '',
$d['keterangan'] ?? '',
$id
]);
// 2. Hapus anggota lama beserta riwayat penyakitnya
$oldAnggota = $db->prepare("SELECT id FROM anggota_keluarga WHERE warga_id=?");
$oldAnggota->execute([$id]);
foreach ($oldAnggota->fetchAll() as $oa) {
$db->prepare("DELETE FROM riwayat_penyakit WHERE anggota_id=?")->execute([$oa['id']]);
}
$db->prepare("DELETE FROM anggota_keluarga WHERE warga_id=?")->execute([$id]);
// 3. Simpan KK sebagai anggota keluarga pertama
$usiaKk = 0;
if (!empty($d['tgl_lahir'])) {
try {
$birthDate = new DateTime($d['tgl_lahir']);
$today = new DateTime();
$usiaKk = $today->diff($birthDate)->y;
} catch (Exception $e) { $usiaKk = 0; }
}
$stmtKk = $db->prepare(
"INSERT INTO anggota_keluarga (warga_id, nama, usia, hubungan) VALUES (?, ?, ?, 'Kepala Keluarga')"
);
$stmtKk->execute([$id, $d['nama'], $usiaKk]);
$kkAnggotaId = $db->lastInsertId();
$kkPenyakit = $d['rp'] ?? $d['riwayat_penyakit'] ?? [];
foreach ($kkPenyakit as $py) {
if (!$py) continue;
$db->prepare("INSERT INTO riwayat_penyakit (anggota_id, penyakit) VALUES (?, ?)")
->execute([$kkAnggotaId, $py]);
}
// 4. Simpan anggota keluarga lainnya
foreach (($d['anggota'] ?? []) as $a) {
if (empty($a['nama'])) continue;
if (strtolower(trim($a['nama'])) === strtolower(trim($d['nama'])) &&
($a['hub'] ?? $a['hubungan'] ?? '') === 'Kepala Keluarga') {
continue;
}
$stmtA = $db->prepare(
"INSERT INTO anggota_keluarga (warga_id, nama, usia, hubungan) VALUES (?,?,?,?)"
);
$stmtA->execute([$id, $a['nama'], $a['usia'] ?? 0, $a['hub'] ?? $a['hubungan'] ?? 'Anak']);
$anggotaId = $db->lastInsertId();
foreach (($a['penyakit'] ?? $a['py'] ?? []) as $py) {
if (!$py) continue;
$db->prepare("INSERT INTO riwayat_penyakit (anggota_id, penyakit) VALUES (?,?)")
->execute([$anggotaId, $py]);
}
}
$db->commit();
jsonOk(null, 'Data warga berhasil diperbarui');
} catch (Exception $e) {
$db->rollBack();
jsonError('Gagal memperbarui: ' . $e->getMessage(), 500);
}
}
// ── DELETE: hapus warga ────────────────────────────────────
if ($method === 'DELETE') {
requireEdit();
$id = getParam('id');
if (!$id) jsonError('ID wajib disertakan.');
$db->prepare("UPDATE warga SET status='nonaktif' WHERE id=?")->execute([$id]);
jsonOk(null, 'Data warga berhasil dihapus');
}
jsonError('Method tidak valid', 405);