'Missing required field: id']); exit; } $id = (int)$data['id']; $db = getDB(); $existingStmt = $db->prepare('SELECT * FROM households WHERE id = ?'); $existingStmt->execute([$id]); $existing = $existingStmt->fetch(PDO::FETCH_ASSOC); if (!$existing) { http_response_code(404); echo json_encode(['error' => 'Household not found']); exit; } $updates = []; $params = []; $error = null; if (array_key_exists('household_code', $data)) { $householdCode = trim((string)$data['household_code']); if ($householdCode === '') { http_response_code(400); echo json_encode(['error' => 'household_code cannot be empty']); exit; } $updates[] = 'household_code = ?'; $params[] = $householdCode; } if (array_key_exists('head_name', $data)) { $headName = trim((string)$data['head_name']); if ($headName === '') { http_response_code(400); echo json_encode(['error' => 'head_name cannot be empty']); exit; } $updates[] = 'head_name = ?'; $params[] = $headName; } if (array_key_exists('nik', $data) || array_key_exists('nik_hash', $data)) { if (array_key_exists('nik', $data)) { $nikHash = normalizeNikHashFromInput($data['nik']); } else { $nikHash = trim((string)$data['nik_hash']); if ($nikHash === '') { $nikHash = null; } } $updates[] = 'nik_hash = ?'; $params[] = $nikHash; } $hasLatitude = array_key_exists('latitude', $data); $hasLongitude = array_key_exists('longitude', $data); if ($hasLatitude || $hasLongitude) { $latitude = $hasLatitude ? $data['latitude'] : $existing['latitude']; $longitude = $hasLongitude ? $data['longitude'] : $existing['longitude']; if (!validateCoordinates($latitude, $longitude, $error)) { http_response_code(400); echo json_encode(['error' => $error]); exit; } $updates[] = 'latitude = ?'; $params[] = (float)$latitude; $updates[] = 'longitude = ?'; $params[] = (float)$longitude; } if (array_key_exists('need_point_id', $data)) { if ($data['need_point_id'] === null || $data['need_point_id'] === '') { $needPointId = null; } else { if (!is_numeric($data['need_point_id'])) { http_response_code(400); echo json_encode(['error' => 'need_point_id must be numeric']); exit; } $needPointId = (int)$data['need_point_id']; $npStmt = $db->prepare('SELECT id FROM need_points WHERE id = ?'); $npStmt->execute([$needPointId]); if (!$npStmt->fetch(PDO::FETCH_ASSOC)) { http_response_code(400); echo json_encode(['error' => 'need_point_id is not found']); exit; } } $updates[] = 'need_point_id = ?'; $params[] = $needPointId; } if (array_key_exists('masjid_id', $data)) { if ($data['masjid_id'] === null || $data['masjid_id'] === '') { $masjidId = null; } else { if (!is_numeric($data['masjid_id'])) { http_response_code(400); echo json_encode(['error' => 'masjid_id must be numeric']); exit; } $masjidId = (int)$data['masjid_id']; $masjidStmt = $db->prepare('SELECT id FROM masjids WHERE id = ?'); $masjidStmt->execute([$masjidId]); if (!$masjidStmt->fetch(PDO::FETCH_ASSOC)) { http_response_code(400); echo json_encode(['error' => 'masjid_id is not found']); exit; } } $updates[] = 'masjid_id = ?'; $params[] = $masjidId; } if (array_key_exists('pontianak_area_id', $data)) { if ($data['pontianak_area_id'] === null || $data['pontianak_area_id'] === '') { $areaId = null; } else { if (!is_numeric($data['pontianak_area_id'])) { http_response_code(400); echo json_encode(['error' => 'pontianak_area_id must be numeric']); exit; } $areaId = (int)$data['pontianak_area_id']; $areaStmt = $db->prepare('SELECT id FROM pontianak_areas WHERE id = ?'); $areaStmt->execute([$areaId]); if (!$areaStmt->fetch(PDO::FETCH_ASSOC)) { http_response_code(400); echo json_encode(['error' => 'pontianak_area_id is not found']); exit; } } $updates[] = 'pontianak_area_id = ?'; $params[] = $areaId; } if (array_key_exists('monthly_income', $data)) { $monthlyIncome = normalizeMonthlyIncome($data['monthly_income'], $error); if ($monthlyIncome === null) { http_response_code(400); echo json_encode(['error' => $error]); exit; } $updates[] = 'monthly_income = ?'; $params[] = $monthlyIncome; } if (array_key_exists('dependents_count', $data)) { $dependentsCount = normalizeDependentsCount($data['dependents_count'], $error); if ($dependentsCount === null) { http_response_code(400); echo json_encode(['error' => $error]); exit; } $updates[] = 'dependents_count = ?'; $params[] = $dependentsCount; } if (array_key_exists('housing_condition_score', $data)) { $housingConditionScore = normalizeHousingConditionScore($data['housing_condition_score'], $error); if ($housingConditionScore === null) { http_response_code(400); echo json_encode(['error' => $error]); exit; } $updates[] = 'housing_condition_score = ?'; $params[] = $housingConditionScore; } if (array_key_exists('employment_status', $data)) { $employmentStatus = normalizeEmploymentStatus($data['employment_status'], $error); if ($employmentStatus === null) { http_response_code(400); echo json_encode(['error' => $error]); exit; } $updates[] = 'employment_status = ?'; $params[] = $employmentStatus; } if (array_key_exists('verification_status', $data)) { $verificationStatus = normalizeVerificationStatus($data['verification_status'], $error, true); if ($verificationStatus === null) { http_response_code(400); echo json_encode(['error' => $error]); exit; } $updates[] = 'verification_status = ?'; $params[] = $verificationStatus; } if (array_key_exists('vulnerability_notes', $data)) { $vulnerabilityNotes = trim((string)$data['vulnerability_notes']); if ($vulnerabilityNotes === '') { $vulnerabilityNotes = null; } $updates[] = 'vulnerability_notes = ?'; $params[] = $vulnerabilityNotes; } if (empty($updates)) { http_response_code(400); echo json_encode(['error' => 'No fields to update']); exit; } $updates[] = 'updated_at = CURRENT_TIMESTAMP'; $params[] = $id; $sql = 'UPDATE households SET ' . implode(', ', $updates) . ' WHERE id = ?'; $updateStmt = $db->prepare($sql); $updateStmt->execute($params); $household = getHouseholdById($db, $id); echo json_encode([ 'success' => true, 'household' => $household ]); } catch (PDOException $e) { if ($e->getCode() === '23000') { http_response_code(409); echo json_encode(['error' => 'Duplicate household_code or need_point_id mapping']); exit; } http_response_code(500); echo json_encode(['error' => $e->getMessage()]); } catch (Exception $e) { http_response_code(500); echo json_encode(['error' => $e->getMessage()]); } } else { http_response_code(405); echo json_encode(['error' => 'Method not allowed']); } ?>