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()]); }