Files
2026-06-10 17:28:32 +07:00

240 lines
10 KiB
PHP

<?php
// ============================================================
// API: Bantuan & Histori Bantuan
// GET ?action=jenis|histori&nik=...
// POST action=salurkan
// ============================================================
require_once __DIR__ . '/../middleware/auth.php';
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { exit; }
$method = $_SERVER['REQUEST_METHOD'];
$action = $_GET['action'] ?? '';
$currentUser = getApiUser($pdo);
// ============================================================
// GET
// ============================================================
if ($method === 'GET') {
if ($action === 'jenis') {
$rows = $pdo->query("SELECT * FROM jenis_bantuan WHERE aktif=1 ORDER BY kategori, nama")->fetchAll();
jsonResponse(true, 'OK', ['data' => $rows]);
}
if ($action === 'histori') {
$nik = sanitizeStr($_GET['nik'] ?? '');
if ($nik && validateNIK($nik)) {
// Histori per penduduk
$stmt = $pdo->prepare("
SELECT hb.*, jb.nama AS nama_bantuan, jb.kategori, jb.satuan,
ri.nama AS nama_rumah_ibadah, u.nama AS disalurkan_oleh_nama
FROM histori_bantuan hb
JOIN jenis_bantuan jb ON jb.id = hb.id_jenis_bantuan
LEFT JOIN rumah_ibadah ri ON ri.id = hb.rumah_ibadah_id
LEFT JOIN users u ON u.id = hb.disalurkan_oleh
WHERE hb.nik = :nik
ORDER BY hb.tanggal DESC
");
$stmt->execute([':nik' => $nik]);
$data = $stmt->fetchAll();
// Ringkasan
$summary = [
'total_bantuan' => count($data),
'kategori' => [],
];
foreach ($data as $row) {
$summary['kategori'][$row['kategori']] = ($summary['kategori'][$row['kategori']] ?? 0) + 1;
}
jsonResponse(true, 'OK', ['data' => $data, 'summary' => $summary]);
}
// List semua histori (admin/pengurus)
if (!canViewAll($currentUser)) jsonResponse(false, 'Akses ditolak.', [], 403);
$where = [];
$params = [];
if (!empty($_GET['bulan'])) { $where[] = 'MONTH(hb.tanggal) = :bln'; $params[':bln'] = (int)$_GET['bulan']; }
if (!empty($_GET['tahun'])) { $where[] = 'YEAR(hb.tanggal) = :thn'; $params[':thn'] = (int)$_GET['tahun']; }
if (!empty($_GET['kategori'])) { $where[] = 'jb.kategori = :kat'; $params[':kat'] = $_GET['kategori']; }
$whereStr = $where ? 'WHERE ' . implode(' AND ', $where) : '';
$stmt = $pdo->prepare("
SELECT hb.id, hb.nik, p.nama_lengkap, hb.tanggal,
jb.nama AS nama_bantuan, jb.kategori,
hb.jumlah, hb.nilai_rupiah, hb.status_penyaluran,
ri.nama AS nama_ri
FROM histori_bantuan hb
JOIN penduduk p ON p.nik = hb.nik
JOIN jenis_bantuan jb ON jb.id = hb.id_jenis_bantuan
LEFT JOIN rumah_ibadah ri ON ri.id = hb.rumah_ibadah_id
$whereStr
ORDER BY hb.tanggal DESC
LIMIT 1000
");
$stmt->execute($params);
jsonResponse(true, 'OK', ['data' => $stmt->fetchAll()]);
}
if ($action === 'belum_dibantu') {
// Warga miskin yang BELUM pernah menerima bantuan
$rows = $pdo->query("
SELECT p.nik, p.nama_lengkap, p.status_ekonomi, p.kondisi_kesehatan,
p.pekerjaan, p.alamat, p.latitude, p.longitude,
k.nama_kk, k.no_kk, ri.nama AS nama_ri
FROM penduduk p
LEFT JOIN keluarga k ON k.id = p.id_keluarga
LEFT JOIN rumah_ibadah ri ON ri.id = k.rumah_ibadah_id
WHERE p.status_hidup = 'hidup'
AND p.status_ekonomi IN ('miskin', 'rentan')
AND NOT EXISTS (
SELECT 1 FROM histori_bantuan hb
WHERE hb.nik = p.nik AND hb.status_penyaluran = 'disalurkan'
)
ORDER BY
CASE p.status_ekonomi WHEN 'miskin' THEN 1 ELSE 2 END,
CASE p.kondisi_kesehatan WHEN 'sakit_parah' THEN 1 WHEN 'disabilitas' THEN 2 ELSE 3 END
")->fetchAll();
jsonResponse(true, 'OK', ['data' => $rows, 'total' => count($rows)]);
}
if ($action === 'dashboard_stats') {
// Statistik untuk dashboard
$stats = $pdo->query("
SELECT
(SELECT COUNT(*) FROM penduduk WHERE status_ekonomi='miskin' AND status_hidup='hidup') AS total_miskin,
(SELECT COUNT(*) FROM penduduk WHERE status_ekonomi='rentan' AND status_hidup='hidup') AS total_rentan,
(SELECT COUNT(*) FROM penduduk WHERE status_ekonomi='mampu' AND status_hidup='hidup') AS total_mampu,
(SELECT COUNT(*) FROM keluarga) AS total_keluarga,
(SELECT COUNT(*) FROM rumah_ibadah) AS total_rumah_ibadah,
(SELECT COUNT(*) FROM laporan WHERE status='pending') AS laporan_pending,
(SELECT COUNT(*) FROM laporan WHERE status='diproses') AS laporan_diproses,
(SELECT COUNT(*) FROM histori_bantuan WHERE MONTH(tanggal)=MONTH(CURDATE()) AND status_penyaluran='disalurkan') AS bantuan_bulan_ini,
(SELECT COUNT(*) FROM penduduk WHERE status_hidup='hidup' AND status_ekonomi IN ('miskin','rentan')
AND NOT EXISTS (SELECT 1 FROM histori_bantuan hb WHERE hb.nik=penduduk.nik AND hb.status_penyaluran='disalurkan')
) AS belum_pernah_dibantu
")->fetch();
// Bantuan per kategori bulan ini
$per_kategori = $pdo->query("
SELECT jb.kategori, COUNT(*) AS jumlah
FROM histori_bantuan hb
JOIN jenis_bantuan jb ON jb.id = hb.id_jenis_bantuan
WHERE MONTH(hb.tanggal) = MONTH(CURDATE())
AND hb.status_penyaluran = 'disalurkan'
GROUP BY jb.kategori
")->fetchAll();
jsonResponse(true, 'OK', ['data' => $stats, 'per_kategori' => $per_kategori]);
}
jsonResponse(false, 'Action tidak dikenal.', [], 400);
}
// ============================================================
// POST: salurkan bantuan
// ============================================================
if ($method === 'POST' && $action === 'salurkan') {
if (!canEdit($currentUser)) jsonResponse(false, 'Akses ditolak.', [], 403);
$body = json_decode(file_get_contents('php://input'), true) ?? $_POST;
$nik = sanitizeStr($body['nik'] ?? '');
$idJenis = (int)($body['id_jenis_bantuan'] ?? 0);
$tanggal = sanitizeStr($body['tanggal'] ?? date('Y-m-d'));
$jumlah = sanitizeStr($body['jumlah'] ?? '');
$status = sanitizeStr($body['status_penyaluran'] ?? 'dijadwalkan');
if (!validateNIK($nik)) jsonResponse(false, 'NIK tidak valid.', [], 400);
if ($idJenis <= 0) jsonResponse(false, 'Jenis bantuan harus dipilih.', [], 400);
if (!strtotime($tanggal)) jsonResponse(false, 'Format tanggal tidak valid.', [], 400);
// Cek penduduk ada
$cek = $pdo->prepare("SELECT nik, id_keluarga FROM penduduk WHERE nik = :nik AND status_hidup='hidup'");
$cek->execute([':nik' => $nik]);
$pddk = $cek->fetch();
if (!$pddk) jsonResponse(false, 'Penduduk tidak ditemukan atau sudah meninggal.', [], 404);
// Cek jenis bantuan ada
$cekJb = $pdo->prepare("SELECT id FROM jenis_bantuan WHERE id = :id AND aktif=1");
$cekJb->execute([':id' => $idJenis]);
if (!$cekJb->fetch()) jsonResponse(false, 'Jenis bantuan tidak ditemukan.', [], 404);
$buktiNama = null;
if (!empty($_FILES['bukti']['name'])) {
try { $buktiNama = uploadFile($_FILES['bukti'], UPLOAD_BUKTI); }
catch (RuntimeException $e) { jsonResponse(false, $e->getMessage(), [], 400); }
}
$stmt = $pdo->prepare("
INSERT INTO histori_bantuan
(nik, id_jenis_bantuan, id_keluarga, rumah_ibadah_id, tanggal,
jumlah, nilai_rupiah, status_penyaluran, catatan, bukti_file, disalurkan_oleh)
VALUES
(:nik,:jb,:kk,:ri,:tgl,:jml,:rp,:status,:cat,:bukti,:user)
");
$stmt->execute([
':nik' => $nik,
':jb' => $idJenis,
':kk' => $pddk['id_keluarga'],
':ri' => $currentUser['rumah_ibadah_id'],
':tgl' => $tanggal,
':jml' => $jumlah ?: null,
':rp' => !empty($body['nilai_rupiah']) ? (float)$body['nilai_rupiah'] : null,
':status' => in_array($status, ['dijadwalkan','disalurkan','dibatalkan']) ? $status : 'dijadwalkan',
':cat' => sanitizeStr($body['catatan'] ?? '') ?: null,
':bukti' => $buktiNama,
':user' => $currentUser['id'],
]);
$hbId = (int)$pdo->lastInsertId();
logAktivitas($pdo, $currentUser['id'], 'CREATE', 'histori_bantuan', (string)$hbId, null, $body);
// Notifikasi ke pimpinan
$pimpinan = $pdo->query("SELECT id FROM users WHERE role_id=3")->fetchAll();
foreach ($pimpinan as $pm) {
$pdo->prepare("INSERT INTO notifikasi (user_id, judul, isi, tipe, ref_id) VALUES (:u,:j,:i,'bantuan',:r)")
->execute([':u' => $pm['id'], ':j' => 'Bantuan Disalurkan', ':i' => "Bantuan untuk NIK $nik telah dicatat.", ':r' => $hbId]);
}
jsonResponse(true, 'Bantuan berhasil dicatat.', ['id' => $hbId], 201);
}
// ============================================================
// PUT: update status penyaluran
// ============================================================
if ($method === 'PUT') {
if (!canEdit($currentUser)) jsonResponse(false, 'Akses ditolak.', [], 403);
$id = (int)($_GET['id'] ?? 0);
$body = json_decode(file_get_contents('php://input'), true) ?? [];
$status = sanitizeStr($body['status_penyaluran'] ?? '');
if (!in_array($status, ['dijadwalkan','disalurkan','dibatalkan'])) {
jsonResponse(false, 'Status tidak valid.', [], 400);
}
$old = $pdo->prepare("SELECT * FROM histori_bantuan WHERE id = :id");
$old->execute([':id' => $id]);
if (!$old->fetch()) jsonResponse(false, 'Data tidak ditemukan.', [], 404);
$pdo->prepare("UPDATE histori_bantuan SET status_penyaluran=:s WHERE id=:id")
->execute([':s' => $status, ':id' => $id]);
logAktivitas($pdo, $currentUser['id'], 'UPDATE', 'histori_bantuan', (string)$id);
jsonResponse(true, 'Status penyaluran diperbarui.', ['id' => $id]);
}
jsonResponse(false, 'Method tidak didukung.', [], 405);