prepare(" SELECT pm.*, ri.nama AS ibadah_nama, ri.jenis AS ibadah_jenis, ri.kontak AS ibadah_kontak, ri.lat AS ibadah_lat, ri.lng AS ibadah_lng FROM penduduk_miskin pm LEFT JOIN rumah_ibadah ri ON pm.rumah_ibadah_id = ri.id WHERE pm.id = ? "); $stmt->execute([$id]); $row = $stmt->fetch(); if (!$row) jsonResponse(['success' => false, 'message' => 'Data tidak ditemukan'], 404); // Anggota keluarga $stmtAk = $db->prepare("SELECT * FROM anggota_keluarga WHERE penduduk_id = ? ORDER BY id"); $stmtAk->execute([$id]); $row['anggota'] = $stmtAk->fetchAll(); jsonResponse(['success' => true, 'data' => $row]); } // List dengan filter + search $where = ['1=1']; $params = []; if (!empty($_GET['status'])) { $where[] = 'pm.status_bantuan = ?'; $params[] = $_GET['status']; } if (!empty($_GET['kecamatan'])) { $where[] = 'pm.kecamatan = ?'; $params[] = $_GET['kecamatan']; } if (!empty($_GET['kelurahan'])) { $where[] = 'pm.kelurahan = ?'; $params[] = $_GET['kelurahan']; } if (!empty($_GET['ibadah_id'])) { $where[] = 'pm.rumah_ibadah_id = ?'; $params[] = (int)$_GET['ibadah_id']; } if (!empty($_GET['search'])) { $where[] = '(pm.kk_nama LIKE ? OR pm.alamat LIKE ? OR pm.nik LIKE ?)'; $q = '%' . $_GET['search'] . '%'; $params = array_merge($params, [$q, $q, $q]); } $sql = "SELECT pm.*, ri.nama AS ibadah_nama, ri.jenis AS ibadah_jenis FROM penduduk_miskin pm LEFT JOIN rumah_ibadah ri ON pm.rumah_ibadah_id = ri.id WHERE " . implode(' AND ', $where) . " ORDER BY pm.created_at DESC"; $stmt = $db->prepare($sql); $stmt->execute($params); $rows = $stmt->fetchAll(); jsonResponse(['success' => true, 'data' => $rows, 'total' => count($rows)]); } // ── POST ─────────────────────────────────────────────────────── if ($method === 'POST') { $isMultipart = str_contains($_SERVER['CONTENT_TYPE'] ?? '', 'multipart/form-data'); $body = $isMultipart ? $_POST : (json_decode(file_get_contents('php://input'), true) ?? []); $required = ['kk_nama', 'lat', 'lng']; foreach ($required as $f) { if (empty($body[$f])) jsonResponse(['success' => false, 'message' => "Field '$f' wajib diisi"], 422); } $lat = (float)$body['lat']; $lng = (float)$body['lng']; // Auto-cari rumah ibadah terdekat $nearest = findNearestIbadah($lat, $lng); $ibadahId = $nearest ? (int)$nearest['id'] : null; $jarakIbadah = $nearest ? (float)$nearest['jarak'] : null; // Handle upload bukti $buktiFile = null; if (!empty($_FILES['bukti_file']) && $_FILES['bukti_file']['error'] === UPLOAD_ERR_OK) { $buktiFile = handleUpload($_FILES['bukti_file'], 'bukti'); } $stmt = $db->prepare(" INSERT INTO penduduk_miskin (kk_nama, nik, jumlah_anggota, alamat, kelurahan, kecamatan, lat, lng, rumah_ibadah_id, jarak_ke_ibadah, status_bantuan, jenis_bantuan, tanggal_bantuan, nominal_bantuan, bukti_file) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "); $stmt->execute([ sanitize($body['kk_nama']), sanitize($body['nik'] ?? ''), (int)($body['jumlah_anggota'] ?? 1), sanitize($body['alamat'] ?? ''), sanitize($body['kelurahan'] ?? ''), sanitize($body['kecamatan'] ?? ''), $lat, $lng, $ibadahId, $jarakIbadah, $body['status_bantuan'] ?? 'belum', sanitize($body['jenis_bantuan'] ?? ''), !empty($body['tanggal_bantuan']) ? $body['tanggal_bantuan'] : null, !empty($body['nominal_bantuan']) ? (float)str_replace(['.', ','], ['', '.'], $body['nominal_bantuan']) : null, $buktiFile, ]); $newId = $db->lastInsertId(); // Simpan anggota keluarga jika ada (anggota bisa berupa JSON string dari FormData) $anggotaData = $body['anggota'] ?? null; if (is_string($anggotaData)) $anggotaData = json_decode($anggotaData, true); if (!empty($anggotaData) && is_array($anggotaData)) { saveAnggota($db, $newId, $anggotaData); } // Fetch full data $new = $db->query(" SELECT pm.*, ri.nama AS ibadah_nama, ri.jenis AS ibadah_jenis FROM penduduk_miskin pm LEFT JOIN rumah_ibadah ri ON pm.rumah_ibadah_id = ri.id WHERE pm.id = $newId ")->fetch(); jsonResponse(['success' => true, 'message' => 'Data penduduk berhasil ditambahkan', 'data' => $new], 201); } // ── PUT ──────────────────────────────────────────────────────── if ($method === 'PUT') { if (!$id) jsonResponse(['success' => false, 'message' => 'ID wajib disertakan'], 400); // Cek apakah multipart (ada file) atau JSON $isMultipart = str_contains($_SERVER['CONTENT_TYPE'] ?? '', 'multipart/form-data'); $body = $isMultipart ? $_POST : (json_decode(file_get_contents('php://input'), true) ?? []); $current = $db->prepare("SELECT * FROM penduduk_miskin WHERE id = ?"); $current->execute([$id]); $existing = $current->fetch(); if (!$existing) jsonResponse(['success' => false, 'message' => 'Data tidak ditemukan'], 404); $lat = (float)($body['lat'] ?? $existing['lat']); $lng = (float)($body['lng'] ?? $existing['lng']); // Re-assign ibadah terdekat jika koordinat berubah $coordChanged = ($lat != (float)$existing['lat'] || $lng != (float)$existing['lng']); if ($coordChanged || isset($body['force_reassign'])) { $nearest = findNearestIbadah($lat, $lng); $ibadahId = $nearest ? (int)$nearest['id'] : null; $jarakIbadah = $nearest ? (float)$nearest['jarak'] : null; } else { $ibadahId = (int)($body['rumah_ibadah_id'] ?? $existing['rumah_ibadah_id']); $jarakIbadah = (float)($existing['jarak_ke_ibadah'] ?? 0); } // Handle upload bukti baru $buktiFile = $existing['bukti_file']; if (!empty($_FILES['bukti_file']) && $_FILES['bukti_file']['error'] === UPLOAD_ERR_OK) { $newFile = handleUpload($_FILES['bukti_file'], 'bukti'); if ($newFile) $buktiFile = $newFile; } $status_bantuan = $body['status_bantuan'] ?? $existing['status_bantuan']; if ($status_bantuan === 'belum') { $jenis_bantuan = null; $tanggal_bantuan = null; $nominal_bantuan = null; } else { $jenis_bantuan = isset($body['jenis_bantuan']) ? sanitize($body['jenis_bantuan']) : $existing['jenis_bantuan']; $tanggal_bantuan = isset($body['tanggal_bantuan']) ? (!empty($body['tanggal_bantuan']) ? $body['tanggal_bantuan'] : null) : $existing['tanggal_bantuan']; if (isset($body['nominal_bantuan'])) { $nominal_bantuan = $body['nominal_bantuan'] !== '' ? (float)str_replace(['.', ','], ['', '.'], $body['nominal_bantuan']) : null; } else { $nominal_bantuan = $existing['nominal_bantuan']; } } $stmt = $db->prepare(" UPDATE penduduk_miskin SET kk_nama=?, nik=?, jumlah_anggota=?, alamat=?, kelurahan=?, kecamatan=?, lat=?, lng=?, rumah_ibadah_id=?, jarak_ke_ibadah=?, status_bantuan=?, jenis_bantuan=?, tanggal_bantuan=?, nominal_bantuan=?, bukti_file=? WHERE id=? "); $stmt->execute([ sanitize($body['kk_nama'] ?? $existing['kk_nama']), sanitize($body['nik'] ?? $existing['nik'] ?? ''), (int)($body['jumlah_anggota'] ?? $existing['jumlah_anggota']), sanitize($body['alamat'] ?? $existing['alamat'] ?? ''), sanitize($body['kelurahan'] ?? $existing['kelurahan'] ?? ''), sanitize($body['kecamatan'] ?? $existing['kecamatan'] ?? ''), $lat, $lng, $ibadahId, $jarakIbadah, $status_bantuan, $jenis_bantuan, $tanggal_bantuan, $nominal_bantuan, $buktiFile, $id, ]); // Update anggota keluarga (anggota bisa berupa JSON string dari FormData) if (isset($body['anggota'])) { $anggotaDataPut = $body['anggota']; if (is_string($anggotaDataPut)) $anggotaDataPut = json_decode($anggotaDataPut, true); if (is_array($anggotaDataPut)) { $db->prepare("DELETE FROM anggota_keluarga WHERE penduduk_id = ?")->execute([$id]); saveAnggota($db, $id, $anggotaDataPut); } } $updated = $db->query(" SELECT pm.*, ri.nama AS ibadah_nama, ri.jenis AS ibadah_jenis FROM penduduk_miskin pm LEFT JOIN rumah_ibadah ri ON pm.rumah_ibadah_id = ri.id WHERE pm.id = $id ")->fetch(); jsonResponse(['success' => true, 'message' => 'Data berhasil diperbarui', 'data' => $updated]); } // ── DELETE ───────────────────────────────────────────────────── if ($method === 'DELETE') { if (!$id) jsonResponse(['success' => false, 'message' => 'ID wajib disertakan'], 400); $stmt = $db->prepare("DELETE FROM penduduk_miskin WHERE id = ?"); $stmt->execute([$id]); if ($stmt->rowCount() === 0) jsonResponse(['success' => false, 'message' => 'Data tidak ditemukan'], 404); jsonResponse(['success' => true, 'message' => 'Data berhasil dihapus']); } // ── Helper ───────────────────────────────────────────────────── function saveAnggota(PDO $db, int $pendudukId, array $list): void { $stmt = $db->prepare(" INSERT INTO anggota_keluarga (penduduk_id, nama, hubungan, umur, pekerjaan, keterangan) VALUES (?,?,?,?,?,?) "); foreach ($list as $a) { if (empty($a['nama'])) continue; $stmt->execute([ $pendudukId, sanitize($a['nama'] ?? ''), sanitize($a['hubungan'] ?? ''), !empty($a['umur']) ? (int)$a['umur'] : null, sanitize($a['pekerjaan'] ?? ''), sanitize($a['keterangan'] ?? ''), ]); } } jsonResponse(['success' => false, 'message' => 'Method tidak didukung'], 405);