Files
2026-06-10 18:54:25 +07:00

217 lines
9.6 KiB
PHP

<?php
// api/kontribusi.php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit;
}
require_once '../config/db.php';
require_once 'middleware.php';
$method = $_SERVER['REQUEST_METHOD'];
try {
switch ($method) {
case 'GET':
// Wajib login untuk melihat riwayat kontribusi
$currentUser = requireAuth(['admin', 'koordinator', 'kontributor']);
if ($currentUser['role'] === 'kontributor') {
// Hanya riwayat kontribusi milik sendiri
$stmt = $pdo->prepare("
SELECT ko.id, ko.user_id, ko.kebutuhan_id, ko.status, ko.created_at, ko.updated_at,
ko.jumlah,
ko.jenis_kontribusi AS tipe_kontribusi,
ko.detail_barang_jasa AS catatan,
k.jenis_bantuan,
ri.nama AS nama_rumah_ibadah,
ri.nama AS nama_ibadah
FROM kontribusi ko
JOIN kebutuhan k ON ko.kebutuhan_id = k.id
JOIN rumah_ibadah ri ON k.rumah_ibadah_id = ri.id
WHERE ko.user_id = ?
ORDER BY ko.created_at DESC
");
$stmt->execute([$currentUser['id']]);
$rows = $stmt->fetchAll();
} else {
// Admin atau Koordinator melihat kontribusi
$where = "";
$params = [];
if ($currentUser['role'] === 'koordinator') {
$where = "WHERE k.rumah_ibadah_id = ?";
$params[] = $currentUser['rumah_ibadah_id'];
}
$stmt = $pdo->prepare("
SELECT ko.id, ko.user_id, ko.kebutuhan_id, ko.status, ko.created_at, ko.updated_at,
ko.jumlah,
ko.jenis_kontribusi AS tipe_kontribusi,
ko.detail_barang_jasa AS catatan,
k.jenis_bantuan,
ri.nama AS nama_rumah_ibadah,
ri.nama AS nama_ibadah,
u.username AS nama_kontributor,
u.email AS kontak_kontributor
FROM kontribusi ko
JOIN kebutuhan k ON ko.kebutuhan_id = k.id
JOIN rumah_ibadah ri ON k.rumah_ibadah_id = ri.id
JOIN users u ON ko.user_id = u.id
$where
ORDER BY ko.created_at DESC
");
$stmt->execute($params);
$rows = $stmt->fetchAll();
}
echo json_encode(['success' => true, 'data' => $rows]);
break;
case 'POST':
// Wajib login sebagai Kontributor untuk berdonasi
$currentUser = requireAuth(['kontributor']);
$body = json_decode(file_get_contents('php://input'), true) ?: $_POST;
$kebutuhanId = (int)($body['kebutuhan_id'] ?? 0);
$jenisKontribusi = trim($body['jenis_kontribusi'] ?? $body['tipe_kontribusi'] ?? ''); // uang/barang/jasa
$jumlahDonasi = (float)($body['jumlah'] ?? 0);
$detail = trim($body['detail_barang_jasa'] ?? $body['catatan'] ?? '');
if (!$kebutuhanId || !$jenisKontribusi || $jumlahDonasi <= 0) {
http_response_code(400);
echo json_encode(['success' => false, 'message' => 'Input data donasi tidak lengkap/valid.']);
exit;
}
// ════════════════════════════════════════════════════════════════════════════
// VALIDASI SISA KEBUTUHAN
// ════════════════════════════════════════════════════════════════════════════
$stmt = $pdo->prepare("
SELECT k.jumlah_dibutuhkan, k.kategori,
COALESCE(SUM(CASE WHEN ko.status = 'confirmed' THEN ko.jumlah ELSE 0 END), 0) AS jumlah_terkumpul
FROM kebutuhan k
LEFT JOIN kontribusi ko ON k.id = ko.kebutuhan_id
WHERE k.id = ?
GROUP BY k.id
");
$stmt->execute([$kebutuhanId]);
$kebutuhan = $stmt->fetch();
if (!$kebutuhan) {
http_response_code(404);
echo json_encode(['success' => false, 'message' => 'Data kebutuhan bantuan tidak ditemukan.']);
exit;
}
// Hitung sisa kebutuhan secara dinamis
$sisaKebutuhan = (float)$kebutuhan['jumlah_dibutuhkan'] - (float)$kebutuhan['jumlah_terkumpul'];
if ($jumlahDonasi > $sisaKebutuhan) {
http_response_code(400);
echo json_encode([
'success' => false,
'message' => sprintf(
'Donasi ditolak! Jumlah kontribusi (%.2f) melebihi sisa kebutuhan bantuan saat ini (%.2f).',
$jumlahDonasi,
$sisaKebutuhan
)
]);
exit;
}
// Simpan kontribusi (default status = pending)
$stmt = $pdo->prepare("
INSERT INTO kontribusi (user_id, kebutuhan_id, jenis_kontribusi, jumlah, detail_barang_jasa, status)
VALUES (?, ?, ?, ?, ?, 'pending')
");
$stmt->execute([$currentUser['id'], $kebutuhanId, $jenisKontribusi, $jumlahDonasi, $detail]);
echo json_encode([
'success' => true,
'message' => 'Terima kasih atas kontribusi Anda! Status kontribusi saat ini menunggu verifikasi (pending).',
'id' => $pdo->lastInsertId()
]);
break;
case 'PUT':
// Konfirmasi kontribusi (pending -> confirmed)
// Hanya Admin atau Koordinator terkait
$currentUser = requireAuth(['admin', 'koordinator']);
$body = json_decode(file_get_contents('php://input'), true) ?: $_POST;
$kontribusiId = (int)($body['id'] ?? 0);
$newStatus = trim($body['status'] ?? 'pending'); // pending/confirmed
if (!$kontribusiId || !in_array($newStatus, ['pending', 'confirmed'])) {
http_response_code(400);
echo json_encode(['success' => false, 'message' => 'Parameter input status tidak valid.']);
exit;
}
// Ambil detail kontribusi
$stmt = $pdo->prepare("
SELECT ko.jumlah, ko.status AS status_sebelumnya, ko.kebutuhan_id, k.rumah_ibadah_id
FROM kontribusi ko
JOIN kebutuhan k ON ko.kebutuhan_id = k.id
WHERE ko.id = ?
");
$stmt->execute([$kontribusiId]);
$kontribusi = $stmt->fetch();
if (!$kontribusi) {
http_response_code(404);
echo json_encode(['success' => false, 'message' => 'Data kontribusi tidak ditemukan.']);
exit;
}
// Batasan wilayah untuk Koordinator
if ($currentUser['role'] === 'koordinator' && $currentUser['rumah_ibadah_id'] != $kontribusi['rumah_ibadah_id']) {
http_response_code(403);
echo json_encode(['success' => false, 'message' => 'Koordinator hanya berhak mengonfirmasi donasi untuk rumah ibadahnya sendiri.']);
exit;
}
// Jika status dirubah ke 'confirmed' dari 'pending'
if ($newStatus === 'confirmed' && $kontribusi['status_sebelumnya'] !== 'confirmed') {
$stmt = $pdo->prepare("
SELECT k.jumlah_dibutuhkan,
COALESCE(SUM(CASE WHEN ko.status = 'confirmed' THEN ko.jumlah ELSE 0 END), 0) AS jumlah_terkumpul
FROM kebutuhan k
LEFT JOIN kontribusi ko ON k.id = ko.kebutuhan_id
WHERE k.id = ?
GROUP BY k.id
");
$stmt->execute([$kontribusi['kebutuhan_id']]);
$kebutuhan = $stmt->fetch();
$sisaKebutuhan = (float)$kebutuhan['jumlah_dibutuhkan'] - (float)$kebutuhan['jumlah_terkumpul'];
if ($kontribusi['jumlah'] > $sisaKebutuhan) {
http_response_code(400);
echo json_encode([
'success' => false,
'message' => 'Gagal konfirmasi! Total confirmed donasi melebihi kapasitas kebutuhan.'
]);
exit;
}
}
$stmt = $pdo->prepare("UPDATE kontribusi SET status = ? WHERE id = ?");
$stmt->execute([$newStatus, $kontribusiId]);
echo json_encode(['success' => true, 'message' => 'Status kontribusi berhasil diperbarui ke ' . $newStatus]);
break;
default:
http_response_code(405);
echo json_encode(['error' => 'Method not allowed']);
}
} catch (Exception $e) {
http_response_code(500);
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}