Files
2026-06-13 11:24:58 +07:00

161 lines
8.5 KiB
PHP

<?php
require_once __DIR__ . '/../config/db.php';
require_once __DIR__ . '/helpers.php';
require_once __DIR__ . '/../config/activity.php';
$pdo = Database::getConnection();
$method = $_SERVER['REQUEST_METHOD'];
// Pastikan sesi aktif sebelum membaca role/uid
if (session_status() === PHP_SESSION_NONE) startAppSession();
$role = $_SESSION['role'] ?? '';
$uid = $_SESSION['user_id'] ?? null;
// Mutasi: operator (penuh) atau enumerator (buat & edit data sendiri)
if ($method !== 'GET') requireApiAnyRole(['operator', 'enumerator']);
/** Ubah string kosong jadi NULL (untuk kolom ENUM/opsional). */
function nn($v) { return ($v === '' || $v === null) ? null : $v; }
/** Wilayah_id penugasan enumerator (cocokkan nama wilayah_tugas). */
function enumeratorWilayahId(PDO $pdo): ?int {
$tugas = $_SESSION['wilayah_tugas'] ?? '';
if (!$tugas) return null;
$st = $pdo->prepare("SELECT id FROM wilayah WHERE nama = ? LIMIT 1");
$st->execute([$tugas]);
$id = $st->fetchColumn();
return $id ? (int)$id : null;
}
/** Pastikan record milik enumerator yang sedang login. */
function assertOwn(PDO $pdo, $id, string $role, $uid): void {
if ($role !== 'enumerator') return; // operator bebas
$st = $pdo->prepare("SELECT created_by FROM warga_miskin WHERE id=?");
$st->execute([$id]);
$owner = $st->fetchColumn();
if ((int)$owner !== (int)$uid) sendError('Anda hanya dapat mengubah data yang Anda input', 403);
}
switch ($method) {
case 'GET':
// Enumerator hanya melihat data yang ia input (KF-26)
$where = ($role === 'enumerator') ? "WHERE w.created_by = " . (int)$uid : "";
$stmt = $pdo->query("
SELECT w.id, w.nama_kk, w.nik_kk, w.alamat, w.wilayah_id, w.rt, w.rw,
w.jumlah_jiwa, w.pekerjaan_kk, w.penghasilan, w.jumlah_tanggungan,
w.sumber_air, w.status_listrik, w.material_dinding, w.status_kepemilikan,
w.status_verifikasi, w.created_at,
ST_AsGeoJSON(w.geom) AS geojson,
(SELECT GROUP_CONCAT(jb.kode SEPARATOR ',')
FROM bantuan_sosial bs JOIN jenis_bantuan jb ON jb.id = bs.jenis_bantuan_id
WHERE bs.warga_id = w.id AND bs.is_aktif = 1) AS bantuan_aktif,
(SELECT COUNT(*) FROM foto_rumah f WHERE f.warga_id = w.id) AS jumlah_foto
FROM warga_miskin w
$where
ORDER BY w.id DESC
");
$features = [];
while ($r = $stmt->fetch()) {
$features[] = [
'type' => 'Feature',
'geometry' => json_decode($r['geojson']),
'properties' => [
'id' => (int)$r['id'], 'nama_kk' => $r['nama_kk'], 'nik_kk' => $r['nik_kk'],
'alamat' => $r['alamat'], 'wilayah_id' => $r['wilayah_id'],
'rt' => $r['rt'], 'rw' => $r['rw'], 'jumlah_jiwa' => $r['jumlah_jiwa'],
'pekerjaan_kk' => $r['pekerjaan_kk'], 'penghasilan' => $r['penghasilan'],
'jumlah_tanggungan' => $r['jumlah_tanggungan'], 'sumber_air' => $r['sumber_air'],
'status_listrik' => $r['status_listrik'], 'material_dinding' => $r['material_dinding'],
'status_kepemilikan' => $r['status_kepemilikan'], 'status_verifikasi' => $r['status_verifikasi'],
'bantuan_aktif' => $r['bantuan_aktif'], 'jumlah_foto' => (int)$r['jumlah_foto'],
'created_at' => $r['created_at'],
],
];
}
sendSuccess(['type' => 'FeatureCollection', 'features' => $features], 'Data Warga Miskin');
break;
case 'POST':
$d = getInput();
if (empty($d['nama_kk']) || empty($d['geometry'])) sendError('Nama KK & lokasi wajib diisi');
// Enumerator: wilayah dipaksa ke wilayah penugasannya
$wilayahId = ($role === 'enumerator') ? enumeratorWilayahId($pdo) : nn($d['wilayah_id'] ?? null);
// Enumerator: data baru selalu berstatus "belum" untuk diverifikasi operator
$verif = ($role === 'enumerator') ? 'belum' : ($d['status_verifikasi'] ?? 'belum');
$pdo->prepare("
INSERT INTO warga_miskin
(nama_kk, nik_kk, alamat, wilayah_id, rt, rw, jumlah_jiwa, pekerjaan_kk,
penghasilan, jumlah_tanggungan, sumber_air, status_listrik, material_dinding,
status_kepemilikan, status_verifikasi, created_by, geom)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ST_GeomFromGeoJSON(?))
")->execute([
$d['nama_kk'], nn($d['nik_kk'] ?? null), nn($d['alamat'] ?? null), $wilayahId,
nn($d['rt'] ?? null), nn($d['rw'] ?? null), nn($d['jumlah_jiwa'] ?? null), nn($d['pekerjaan_kk'] ?? null),
$d['penghasilan'] ?? 0, $d['jumlah_tanggungan'] ?? 0,
nn($d['sumber_air'] ?? null), nn($d['status_listrik'] ?? null), nn($d['material_dinding'] ?? null),
nn($d['status_kepemilikan'] ?? null), $verif, $uid, json_encode($d['geometry']),
]);
$newId = (int)$pdo->lastInsertId();
logActivity($pdo, 'create', 'warga_miskin', $newId, "Tambah warga {$d['nama_kk']}");
sendSuccess(['id' => $newId], 'Warga disimpan', 201);
break;
case 'PUT':
$d = getInput();
$id = $_GET['id'] ?? null;
if (!$id) sendError('ID wajib');
// Mode verifikasi → hanya operator
if (isset($d['status_verifikasi']) && count($d) === 1) {
if ($role !== 'operator') sendError('Hanya operator yang dapat memverifikasi', 403);
$pdo->prepare("UPDATE warga_miskin SET status_verifikasi=? WHERE id=?")->execute([$d['status_verifikasi'], $id]);
logActivity($pdo, 'update', 'warga_miskin', (int)$id, "Verifikasi: {$d['status_verifikasi']}");
sendSuccess(null, 'Status verifikasi diperbarui');
}
assertOwn($pdo, $id, $role, $uid);
// Mode lokasi saja
if (!empty($d['geometry']) && empty($d['nama_kk'])) {
$pdo->prepare("UPDATE warga_miskin SET geom=ST_GeomFromGeoJSON(?) WHERE id=?")->execute([json_encode($d['geometry']), $id]);
logActivity($pdo, 'update', 'warga_miskin', (int)$id, 'Ubah lokasi warga');
sendSuccess(null, 'Lokasi diperbarui');
}
// Mode data lengkap. Enumerator tidak boleh mengubah status verifikasi.
$verifSet = ($role === 'operator') ? ($d['status_verifikasi'] ?? 'belum') : null;
if ($verifSet !== null) {
$sql = "UPDATE warga_miskin SET nama_kk=?, nik_kk=?, alamat=?, rt=?, rw=?, jumlah_jiwa=?, pekerjaan_kk=?,
penghasilan=?, jumlah_tanggungan=?, sumber_air=?, status_listrik=?, material_dinding=?,
status_kepemilikan=?, status_verifikasi=? WHERE id=?";
$params = [$d['nama_kk'], nn($d['nik_kk'] ?? null), nn($d['alamat'] ?? null), nn($d['rt'] ?? null), nn($d['rw'] ?? null),
nn($d['jumlah_jiwa'] ?? null), nn($d['pekerjaan_kk'] ?? null), $d['penghasilan'] ?? 0, $d['jumlah_tanggungan'] ?? 0,
nn($d['sumber_air'] ?? null), nn($d['status_listrik'] ?? null), nn($d['material_dinding'] ?? null),
nn($d['status_kepemilikan'] ?? null), $verifSet, $id];
} else {
$sql = "UPDATE warga_miskin SET nama_kk=?, nik_kk=?, alamat=?, rt=?, rw=?, jumlah_jiwa=?, pekerjaan_kk=?,
penghasilan=?, jumlah_tanggungan=?, sumber_air=?, status_listrik=?, material_dinding=?,
status_kepemilikan=? WHERE id=?";
$params = [$d['nama_kk'], nn($d['nik_kk'] ?? null), nn($d['alamat'] ?? null), nn($d['rt'] ?? null), nn($d['rw'] ?? null),
nn($d['jumlah_jiwa'] ?? null), nn($d['pekerjaan_kk'] ?? null), $d['penghasilan'] ?? 0, $d['jumlah_tanggungan'] ?? 0,
nn($d['sumber_air'] ?? null), nn($d['status_listrik'] ?? null), nn($d['material_dinding'] ?? null),
nn($d['status_kepemilikan'] ?? null), $id];
}
$pdo->prepare($sql)->execute($params);
logActivity($pdo, 'update', 'warga_miskin', (int)$id, 'Edit data warga');
sendSuccess(null, 'Warga diperbarui');
break;
case 'DELETE':
if ($role !== 'operator') sendError('Hanya operator yang dapat menghapus data', 403);
$id = $_GET['id'] ?? null;
if (!$id) sendError('ID wajib');
$pdo->prepare("DELETE FROM warga_miskin WHERE id=?")->execute([$id]);
logActivity($pdo, 'delete', 'warga_miskin', (int)$id, 'Hapus data warga');
sendSuccess(null, 'Warga dihapus');
break;
default:
sendError('Method not allowed', 405);
}