beginTransaction(); try { $rumahStmt = $pdo->query('SELECT * FROM rumah_ibadah WHERE status = "Aktif" ORDER BY nama ASC'); $rumahIbadah = $rumahStmt->fetchAll(); $kelStmt = $pdo->query('SELECT * FROM keluarga ORDER BY FIELD(kerentanan, "Miskin Ekstrem", "Sangat Miskin", "Miskin", "Rentan Miskin"), created_at ASC'); $keluarga = $kelStmt->fetchAll(); $terpakai = []; foreach ($rumahIbadah as $ri) { $terpakai[(int)$ri['id']] = 0; } $update = $pdo->prepare('UPDATE keluarga SET status_bantuan = ?, rumah_ibadah_id = ? WHERE id = ?'); $jumlahDitanggung = 0; $jumlahBlankSpot = 0; $jumlahMenunggu = 0; $jumlahTidakValid = 0; foreach ($keluarga as $kel) { $kelId = (int)$kel['id']; if ($kel['status_verifikasi'] === 'Tidak Valid') { $update->execute(['Tidak Valid', null, $kelId]); $jumlahTidakValid++; continue; } if ($kel['status_verifikasi'] !== 'Valid') { $update->execute(['Menunggu Verifikasi', null, $kelId]); $jumlahMenunggu++; continue; } $kandidat = []; foreach ($rumahIbadah as $ri) { $riId = (int)$ri['id']; $kuota = (int)$ri['kuota']; $radius = (int)$ri['radius']; if ($kuota <= 0 || ($terpakai[$riId] ?? 0) >= $kuota) { continue; } $jarak = haversine_meter((float)$kel['lat'], (float)$kel['lng'], (float)$ri['lat'], (float)$ri['lng']); if ($jarak <= $radius) { $kandidat[] = [ 'id' => $riId, 'jarak' => $jarak, 'sisa_kuota' => $kuota - ($terpakai[$riId] ?? 0), ]; } } if (!empty($kandidat)) { usort($kandidat, function ($a, $b) { if ($a['jarak'] == $b['jarak']) return $b['sisa_kuota'] <=> $a['sisa_kuota']; return $a['jarak'] <=> $b['jarak']; }); $riId = $kandidat[0]['id']; $terpakai[$riId]++; $update->execute(['Ditanggung', $riId, $kelId]); $jumlahDitanggung++; } else { $update->execute(['Blank Spot', null, $kelId]); $jumlahBlankSpot++; } } $pdo->commit(); json_response([ 'success' => true, 'message' => 'Analisis tanggungan selesai.', 'summary' => [ 'ditanggung' => $jumlahDitanggung, 'blank_spot' => $jumlahBlankSpot, 'menunggu_verifikasi' => $jumlahMenunggu, 'tidak_valid' => $jumlahTidakValid, ] ]); } catch (Throwable $e) { $pdo->rollBack(); json_response(['success' => false, 'message' => 'Analisis gagal: ' . $e->getMessage()], 500); }