prepare($sql); $stmt->execute($params); $rows = $stmt->fetchAll(); if ($rows) { $ids = array_map(fn($r) => (int)$r['id'], $rows); $placeholders = implode(',', array_fill(0, count($ids), '?')); $anggotaStmt = $pdo->prepare('SELECT * FROM keluarga_anggota WHERE keluarga_id IN (' . $placeholders . ') ORDER BY FIELD(hubungan, "Kepala Keluarga", "Suami", "Istri", "Anak", "Orang Tua", "Mertua", "Famili Lain", "Lainnya"), tanggal_lahir ASC, nama ASC'); $anggotaStmt->execute($ids); $anggotaByKeluarga = []; foreach ($anggotaStmt->fetchAll() as $anggota) { $anggotaByKeluarga[(int)$anggota['keluarga_id']][] = $anggota; } foreach ($rows as &$row) { $row['anggota'] = $anggotaByKeluarga[(int)$row['id']] ?? []; } unset($row); } json_response(['success' => true, 'data' => $rows]); } if ($method === 'POST') { $data = get_json_input(); required_fields($data, ['nama_kk','alamat','kerentanan','kebutuhan','lat','lng']); $statusVerifikasi = clean_string($data['status_verifikasi'] ?? 'Menunggu Verifikasi'); if ($role === 'masyarakat' || !role_in(['admin','dinas','relawan'])) { $statusVerifikasi = 'Menunggu Verifikasi'; } $allowedStatus = ['Menunggu Verifikasi','Valid','Tidak Valid','Perlu Survei Ulang']; if (!in_array($statusVerifikasi, $allowedStatus, true)) { $statusVerifikasi = 'Menunggu Verifikasi'; } $anggota = is_array($data['anggota'] ?? null) ? $data['anggota'] : []; $anggota = array_values(array_filter($anggota, fn($a) => is_array($a) && trim((string)($a['nama'] ?? '')) !== '')); if (count($anggota) === 0) { json_response(['success' => false, 'message' => 'Minimal satu anggota keluarga harus diisi.'], 422); } $statusBantuan = $statusVerifikasi === 'Tidak Valid' ? 'Tidak Valid' : 'Menunggu Verifikasi'; $pdo->beginTransaction(); try { $stmt = $pdo->prepare('INSERT INTO keluarga (nama_kk, alamat, no_kk, nik, kerentanan, kebutuhan, status_verifikasi, status_bantuan, catatan, lat, lng, created_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); $stmt->execute([ clean_string($data['nama_kk']), clean_string($data['alamat']), clean_string($data['no_kk'] ?? ''), clean_string($data['nik'] ?? ''), clean_string($data['kerentanan']), clean_string($data['kebutuhan']), $statusVerifikasi, $statusBantuan, clean_string($data['catatan'] ?? ''), clean_float($data['lat']), clean_float($data['lng']), $user['id'] ]); $keluargaId = (int)$pdo->lastInsertId(); $anggotaStmt = $pdo->prepare('INSERT INTO keluarga_anggota (keluarga_id, nik, nama, hubungan, jenis_kelamin, tempat_lahir, tanggal_lahir, agama, pendidikan, pekerjaan, status_perkawinan, penghasilan, mampu_bekerja, keahlian, status_pemberdayaan, catatan) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); $allowedHubungan = ['Kepala Keluarga','Istri','Suami','Anak','Orang Tua','Mertua','Famili Lain','Lainnya']; $allowedGender = ['Laki-laki','Perempuan']; $allowedWork = ['Ya','Tidak']; foreach ($anggota as $a) { $tanggal = clean_string($a['tanggal_lahir'] ?? ''); $anggotaStmt->execute([ $keluargaId, clean_string($a['nik'] ?? ''), clean_string($a['nama'] ?? ''), clean_allowed($a['hubungan'] ?? '', $allowedHubungan, 'Lainnya'), clean_allowed($a['jenis_kelamin'] ?? '', $allowedGender, 'Laki-laki'), clean_string($a['tempat_lahir'] ?? ''), $tanggal !== '' ? $tanggal : null, clean_string($a['agama'] ?? ''), clean_string($a['pendidikan'] ?? ''), clean_string($a['pekerjaan'] ?? ''), clean_string($a['status_perkawinan'] ?? ''), clean_float($a['penghasilan'] ?? 0), clean_allowed($a['mampu_bekerja'] ?? 'Tidak', $allowedWork, 'Tidak'), clean_string($a['keahlian'] ?? ''), clean_allowed($a['mampu_bekerja'] ?? 'Tidak', $allowedWork, 'Tidak') === 'Ya' ? 'Layak Diberdayakan' : 'Belum Dinilai', clean_string($a['catatan'] ?? '') ]); } $pdo->commit(); json_response(['success' => true, 'message' => 'Data keluarga dan anggota KK berhasil disimpan.', 'id' => $keluargaId], 201); } catch (Throwable $e) { $pdo->rollBack(); json_response(['success' => false, 'message' => 'Data gagal disimpan: ' . $e->getMessage()], 500); } } if ($method === 'PUT') { api_require_role(['admin','dinas','relawan']); $data = get_json_input(); required_fields($data, ['id']); $id = clean_int($data['id']); $allowedStatus = ['Menunggu Verifikasi','Valid','Tidak Valid','Perlu Survei Ulang']; $statusVerifikasi = clean_string($data['status_verifikasi'] ?? 'Menunggu Verifikasi'); if (!in_array($statusVerifikasi, $allowedStatus, true)) { json_response(['success' => false, 'message' => 'Status verifikasi tidak valid.'], 422); } $statusBantuan = $statusVerifikasi === 'Tidak Valid' ? 'Tidak Valid' : 'Menunggu Verifikasi'; $stmt = $pdo->prepare('UPDATE keluarga SET status_verifikasi = ?, status_bantuan = ?, rumah_ibadah_id = NULL, catatan = CONCAT(COALESCE(catatan, ""), ?) WHERE id = ?'); $catatanTambahan = clean_string($data['catatan'] ?? ''); $catatanTambahan = $catatanTambahan ? "\n[Verifikasi] " . $catatanTambahan : ''; $stmt->execute([$statusVerifikasi, $statusBantuan, $catatanTambahan, $id]); json_response(['success' => true, 'message' => 'Status verifikasi berhasil diperbarui. Jalankan analisis ulang untuk memperbarui status bantuan.']); } if ($method === 'DELETE') { api_require_role(['admin','dinas']); $id = clean_int($_GET['id'] ?? 0); if ($id <= 0) json_response(['success' => false, 'message' => 'ID tidak valid.'], 422); $stmt = $pdo->prepare('DELETE FROM keluarga WHERE id = ?'); $stmt->execute([$id]); json_response(['success' => true, 'message' => 'Data keluarga berhasil dihapus.']); } json_response(['success' => false, 'message' => 'Method tidak didukung.'], 405);