103 lines
3.2 KiB
PHP
103 lines
3.2 KiB
PHP
<?php
|
|
require_once __DIR__ . '/_helpers.php';
|
|
api_require_login();
|
|
api_require_role(['admin','dinas']);
|
|
|
|
function haversine_meter(float $lat1, float $lng1, float $lat2, float $lng2): float
|
|
{
|
|
$earth = 6371000;
|
|
$dLat = deg2rad($lat2 - $lat1);
|
|
$dLng = deg2rad($lng2 - $lng1);
|
|
$a = sin($dLat / 2) * sin($dLat / 2) +
|
|
cos(deg2rad($lat1)) * cos(deg2rad($lat2)) *
|
|
sin($dLng / 2) * sin($dLng / 2);
|
|
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
|
|
return $earth * $c;
|
|
}
|
|
|
|
$pdo->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);
|
|
}
|