false, 'message' => 'Input tidak valid']); exit; } try { ensurePendudukDistanceColumns($pdo); ensurePendudukFeatureSchema($pdo); $input_lat = floatval($input['lat']); $input_lng = floatval($input['lng']); $coverage = calculatePendudukCoverage($pdo, $input_lat, $input_lng); $buktiFile = saveUploadedEvidence('bukti_file'); if ($buktiFile === null && !empty($input['existing_bukti_file'])) { $buktiFile = $input['existing_bukti_file']; } $stmt = $pdo->prepare(" UPDATE penduduk_miskin SET kk_nama=?, kk_nik=?, alamat=?, lat=?, lng=?, status_bantuan=?, kategori_kebutuhan=?, deskripsi_kebutuhan=?, tindak_lanjut=?, kondisi_rumah=?, penghasilan=?, catatan_survei=?, bukti_file=?, jenis_bantuan=?, tanggal_bantuan=?, ibadah_id=?, jarak_m=?, jarak_rute_m=?, is_blank_spot=? WHERE id=? "); $stmt->execute([ $input['kk_nama'], $input['kk_nik'] ?? null, $input['alamat'], $input['lat'], $input['lng'], $input['status_bantuan'] ?? 'Belum dibantu', $input['kategori_kebutuhan'] ?? null, $input['deskripsi_kebutuhan'] ?? null, $input['tindak_lanjut'] ?? 'Belum disurvei', $input['kondisi_rumah'] ?? null, normalizeNonNegativeIntOrNull($input['penghasilan'] ?? '', 'Penghasilan'), $input['catatan_survei'] ?? null, $buktiFile, $input['jenis_bantuan'] ?? null, normalizeDateOrNull($input['tanggal_bantuan'] ?? null), $coverage['ibadah_id'], $coverage['jarak_m'], $coverage['jarak_rute_m'], $coverage['is_blank_spot'], $input['id'] ]); // 4. Delete old anggota and insert new ones $pdo->prepare("DELETE FROM anggota_keluarga WHERE penduduk_id=?")->execute([$input['id']]); if (!empty($input['anggota']) && is_array($input['anggota'])) { $stmtAnggota = $pdo->prepare("INSERT INTO anggota_keluarga (penduduk_id, nama, hubungan, umur, pekerjaan) VALUES (?, ?, ?, ?, ?)"); foreach ($input['anggota'] as $anggota) { $stmtAnggota->execute([ $input['id'], $anggota['nama'], $anggota['hubungan'], $anggota['umur'] ?? null, $anggota['pekerjaan'] ?? null ]); } } updatePendudukPriority($pdo, (int)$input['id']); echo json_encode([ 'success' => true, 'ibadah_id' => $coverage['ibadah_id'], 'jarak_m' => $coverage['jarak_m'], 'jarak_rute_m' => $coverage['jarak_rute_m'], 'is_blank_spot' => $coverage['is_blank_spot'] ]); } catch (Exception $e) { echo json_encode(['success' => false, 'message' => $e->getMessage()]); }