223 lines
11 KiB
PHP
223 lines
11 KiB
PHP
<?php
|
|
// api/penduduk.php
|
|
header('Content-Type: application/json');
|
|
header('Access-Control-Allow-Origin: *');
|
|
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
|
|
header('Access-Control-Allow-Headers: Content-Type');
|
|
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit; }
|
|
|
|
require_once '../includes/config.php';
|
|
$method = $_SERVER['REQUEST_METHOD'];
|
|
$action = $_GET['action'] ?? 'geojson';
|
|
|
|
function buildFeature($row, $conn) {
|
|
$pid = (int)$row['id'];
|
|
// Anggota keluarga + umur otomatis
|
|
$ak = $conn->query("SELECT *,
|
|
TIMESTAMPDIFF(YEAR,tanggal_lahir,CURDATE()) AS umur
|
|
FROM anggota_keluarga WHERE id_penduduk=$pid ORDER BY id");
|
|
$anggota = [];
|
|
while ($a = $ak->fetch_assoc()) {
|
|
// Pendidikan terakhir
|
|
$pend = $conn->query("SELECT jenjang,nama_institusi,tahun_lulus,status_pendidikan
|
|
FROM riwayat_pendidikan WHERE id_anggota={$a['id']}
|
|
ORDER BY tahun_masuk DESC LIMIT 1")->fetch_assoc();
|
|
$a['pendidikan_terakhir'] = $pend;
|
|
$anggota[] = $a;
|
|
}
|
|
$row['anggota'] = $anggota;
|
|
|
|
// Histori bantuan
|
|
$bq = $conn->query("SELECT b.*,kb.nama AS jenis_bantuan,ri.nama AS nama_ibadah,rim.nama AS nama_mitra
|
|
FROM bantuan b
|
|
JOIN kategori_bantuan kb ON b.id_kategori_bantuan=kb.id
|
|
LEFT JOIN rumah_ibadah ri ON b.id_rumah_ibadah=ri.id
|
|
LEFT JOIN rumah_ibadah rim ON b.id_rumah_ibadah_mitra=rim.id
|
|
WHERE b.id_penduduk=$pid ORDER BY b.tanggal_bantuan DESC");
|
|
$bantuan = [];
|
|
while ($b = $bq->fetch_assoc()) $bantuan[] = $b;
|
|
$row['histori_bantuan'] = $bantuan;
|
|
$row['jumlah_bantuan'] = count($bantuan);
|
|
|
|
return [
|
|
'type' => 'Feature',
|
|
'geometry' => ['type'=>'Point','coordinates'=>[(float)$row['longitude'],(float)$row['latitude']]],
|
|
'properties' => $row
|
|
];
|
|
}
|
|
|
|
// ── GET ───────────────────────────────────────────────────
|
|
if ($method === 'GET') {
|
|
if ($action === 'geojson') {
|
|
$where = "WHERE 1=1";
|
|
if (isset($_GET['status_ekonomi']) && $_GET['status_ekonomi'] !== 'all')
|
|
$where .= " AND p.status_ekonomi='".esc($conn,$_GET['status_ekonomi'])."'";
|
|
if (isset($_GET['id_ibadah']) && $_GET['id_ibadah'])
|
|
$where .= " AND p.id_rumah_ibadah=".(int)$_GET['id_ibadah'];
|
|
if (isset($_GET['kecamatan']) && $_GET['kecamatan'])
|
|
$where .= " AND p.kecamatan='".esc($conn,$_GET['kecamatan'])."'";
|
|
|
|
$res = $conn->query("SELECT p.*,ri.nama AS nama_ibadah,ri.jenis AS jenis_ibadah
|
|
FROM penduduk p
|
|
LEFT JOIN rumah_ibadah ri ON p.id_rumah_ibadah=ri.id
|
|
$where ORDER BY p.id DESC");
|
|
$features = [];
|
|
while ($row = $res->fetch_assoc()) $features[] = buildFeature($row, $conn);
|
|
jsonResponse(['type'=>'FeatureCollection','features'=>$features]);
|
|
|
|
} elseif ($action === 'get' && isset($_GET['id'])) {
|
|
$id = (int)$_GET['id'];
|
|
$row = $conn->query("SELECT p.*,ri.nama AS nama_ibadah
|
|
FROM penduduk p LEFT JOIN rumah_ibadah ri ON p.id_rumah_ibadah=ri.id
|
|
WHERE p.id=$id")->fetch_assoc();
|
|
jsonResponse($row ? buildFeature($row,$conn) : ['error'=>'Tidak ditemukan']);
|
|
|
|
} elseif ($action === 'dashboard') {
|
|
$where = 'WHERE 1=1';
|
|
$ibadahFilter = '';
|
|
$laporanFilter = '';
|
|
if (!empty($_SESSION['role']) && $_SESSION['role'] === 'pengurus_ibadah') {
|
|
$iid = (int)($_SESSION['id_rumah_ibadah'] ?? 0);
|
|
$where .= " AND p.id_rumah_ibadah=$iid";
|
|
$ibadahFilter = " WHERE id=$iid";
|
|
$laporanFilter = " WHERE id_rumah_ibadah=$iid";
|
|
}
|
|
$total = $conn->query("SELECT COUNT(*) c FROM penduduk $where")->fetch_assoc()['c'];
|
|
$jiwa = $conn->query("SELECT COALESCE(SUM(jumlah_anggota),0) c FROM penduduk $where")->fetch_assoc()['c'];
|
|
$ibadah = $conn->query("SELECT COUNT(*) c FROM rumah_ibadah$ibadahFilter")->fetch_assoc()['c'];
|
|
$bantuan = $conn->query("SELECT COUNT(*) c FROM bantuan" . ($laporanFilter ? " WHERE id_rumah_ibadah=$iid" : ''))->fetch_assoc()['c'];
|
|
$pending = $conn->query("SELECT COUNT(*) c FROM laporan_status" . ($laporanFilter ? " WHERE status_verifikasi='pending' AND id_rumah_ibadah=$iid" : " WHERE status_verifikasi='pending'") )->fetch_assoc()['c'];
|
|
$sm = $conn->query("SELECT COUNT(*) c FROM penduduk $where AND status_ekonomi='sangat_miskin'")->fetch_assoc()['c'];
|
|
$miskin = $conn->query("SELECT COUNT(*) c FROM penduduk $where AND status_ekonomi='miskin'")->fetch_assoc()['c'];
|
|
$rentan = $conn->query("SELECT COUNT(*) c FROM penduduk $where AND status_ekonomi='rentan'")->fetch_assoc()['c'];
|
|
|
|
// Per kecamatan
|
|
$kecRes = $conn->query("SELECT kecamatan,COUNT(*) AS jumlah_kk,SUM(jumlah_anggota) AS jiwa
|
|
FROM penduduk $where GROUP BY kecamatan ORDER BY jumlah_kk DESC");
|
|
$perkec = [];
|
|
while ($r = $kecRes->fetch_assoc()) $perkec[] = $r;
|
|
|
|
jsonResponse([
|
|
'total_kk' => (int)$total,
|
|
'total_jiwa' => (int)$jiwa,
|
|
'total_ibadah' => (int)$ibadah,
|
|
'total_bantuan' => (int)$bantuan,
|
|
'pending_laporan'=> (int)$pending,
|
|
'sangat_miskin' => (int)$sm,
|
|
'miskin' => (int)$miskin,
|
|
'rentan' => (int)$rentan,
|
|
'per_kecamatan' => $perkec,
|
|
]);
|
|
}
|
|
}
|
|
|
|
// ── POST: tambah penduduk ─────────────────────────────────
|
|
if ($method === 'POST') {
|
|
requireLogin(['admin','pengurus_ibadah','masyarakat']);
|
|
|
|
$nama = esc($conn,$_POST['nama_kepala_keluarga']??'');
|
|
$no_kk = esc($conn,$_POST['no_kk']??'');
|
|
$nik = esc($conn,$_POST['nik_kepala']??'');
|
|
$lat = (float)($_POST['latitude']??0);
|
|
$lon = (float)($_POST['longitude']??0);
|
|
$alamat = esc($conn,$_POST['alamat']??'');
|
|
$rt = esc($conn,$_POST['rt']??'');
|
|
$rw = esc($conn,$_POST['rw']??'');
|
|
$kel = esc($conn,$_POST['kelurahan']??'');
|
|
$kec = esc($conn,$_POST['kecamatan']??'');
|
|
$jml = (int)($_POST['jumlah_anggota']??1);
|
|
$sekon = esc($conn,$_POST['status_ekonomi']??'miskin');
|
|
$shun = esc($conn,$_POST['status_hunian']??'milik_sendiri');
|
|
|
|
$nearest = findNearestIbadah($conn,$lat,$lon);
|
|
$id_ibadah = $nearest?$nearest['id']:'NULL';
|
|
$jarak = $nearest?$nearest['jarak']:0;
|
|
|
|
$sql = "INSERT INTO penduduk (no_kk,nama_kepala_keluarga,nik_kepala,latitude,longitude,
|
|
alamat,rt,rw,kelurahan,kecamatan,jumlah_anggota,id_rumah_ibadah,jarak_ke_ibadah,
|
|
status_ekonomi,status_hunian)
|
|
VALUES ('$no_kk','$nama','$nik',$lat,$lon,'$alamat','$rt','$rw','$kel','$kec',
|
|
$jml,$id_ibadah,$jarak,'$sekon','$shun')";
|
|
|
|
if ($conn->query($sql)) {
|
|
$pid = $conn->insert_id;
|
|
|
|
// Simpan anggota keluarga
|
|
$anggota = json_decode($_POST['anggota']??'[]', true);
|
|
foreach ($anggota as $a) {
|
|
$anm = esc($conn,$a['nama']??'');
|
|
$hub = esc($conn,$a['hubungan']??'Anak');
|
|
$jk = esc($conn,$a['jenis_kelamin']??'L');
|
|
$tgl = esc($conn,$a['tanggal_lahir']??'2000-01-01');
|
|
$tmp = esc($conn,$a['tempat_lahir']??'');
|
|
$agm = esc($conn,$a['agama']??'Islam');
|
|
$pkj = esc($conn,$a['pekerjaan']??'');
|
|
$nik2 = esc($conn,$a['nik']??'');
|
|
$conn->query("INSERT INTO anggota_keluarga
|
|
(id_penduduk,nik,nama,hubungan,jenis_kelamin,tanggal_lahir,tempat_lahir,agama,pekerjaan)
|
|
VALUES ($pid,'$nik2','$anm','$hub','$jk','$tgl','$tmp','$agm','$pkj')");
|
|
$aid = $conn->insert_id;
|
|
|
|
// Riwayat pendidikan per anggota
|
|
$pendList = json_decode($a['pendidikan']??'[]', true);
|
|
foreach ($pendList as $pd) {
|
|
$jj = esc($conn,$pd['jenjang']??'');
|
|
$ni = esc($conn,$pd['nama_institusi']??'');
|
|
$tm = (int)($pd['tahun_masuk']??0)?:'NULL';
|
|
$tl = (int)($pd['tahun_lulus']??0)?:'NULL';
|
|
$sp = esc($conn,$pd['status_pendidikan']??'lulus');
|
|
$conn->query("INSERT INTO riwayat_pendidikan (id_anggota,jenjang,nama_institusi,tahun_masuk,tahun_lulus,status_pendidikan)
|
|
VALUES ($aid,'$jj','$ni',$tm,$tl,'$sp')");
|
|
}
|
|
}
|
|
|
|
// Upload foto/dokumen
|
|
$foto = uploadFile('foto','penduduk');
|
|
|
|
logAktivitas($conn,'tambah_penduduk','penduduk',$pid,"Tambah KK: $nama");
|
|
jsonResponse(['success'=>true,'id'=>$pid,'message'=>'Data berhasil disimpan','nearest_ibadah'=>$nearest]);
|
|
} else {
|
|
jsonResponse(['success'=>false,'error'=>$conn->error],500);
|
|
}
|
|
}
|
|
|
|
// ── PUT: update penduduk ──────────────────────────────────
|
|
if ($method === 'PUT') {
|
|
requireLogin(['admin','pengurus_ibadah']);
|
|
$d = json_decode(file_get_contents('php://input'), true);
|
|
$id = (int)$d['id'];
|
|
$nama = esc($conn,$d['nama_kepala_keluarga']??'');
|
|
$lat = (float)($d['latitude']??0);
|
|
$lon = (float)($d['longitude']??0);
|
|
$alam = esc($conn,$d['alamat']??'');
|
|
$jml = (int)($d['jumlah_anggota']??1);
|
|
$se = esc($conn,$d['status_ekonomi']??'miskin');
|
|
|
|
$nearest = findNearestIbadah($conn,$lat,$lon);
|
|
$id_ibadah = $nearest?$nearest['id']:'NULL';
|
|
$jarak = $nearest?$nearest['jarak']:0;
|
|
|
|
$sql = "UPDATE penduduk SET nama_kepala_keluarga='$nama',latitude=$lat,longitude=$lon,
|
|
alamat='$alam',jumlah_anggota=$jml,status_ekonomi='$se',
|
|
id_rumah_ibadah=$id_ibadah,jarak_ke_ibadah=$jarak WHERE id=$id";
|
|
if ($conn->query($sql)) {
|
|
logAktivitas($conn,'edit_penduduk','penduduk',$id,"Edit KK: $nama");
|
|
jsonResponse(['success'=>true,'message'=>'Data diperbarui']);
|
|
} else {
|
|
jsonResponse(['success'=>false,'error'=>$conn->error],500);
|
|
}
|
|
}
|
|
|
|
// ── DELETE ────────────────────────────────────────────────
|
|
if ($method === 'DELETE') {
|
|
requireLogin(['admin']);
|
|
$id = (int)($_GET['id']??0);
|
|
if ($conn->query("DELETE FROM penduduk WHERE id=$id")) {
|
|
logAktivitas($conn,'hapus_penduduk','penduduk',$id,'');
|
|
jsonResponse(['success'=>true,'message'=>'Data dihapus']);
|
|
} else {
|
|
jsonResponse(['success'=>false,'error'=>$conn->error],500);
|
|
}
|
|
}
|
|
?>
|