0 && isAdmin()) {
$donation_id = intval($_GET['resend_email']);
$new_email = $_GET['email'] ?? null;
$result = sendReceiptEmail($donation_id, $new_email);
if ($result['success']) {
$message = $result['message'];
} else {
$error = $result['message'];
}
// Redirect to avoid multiple submissions
header("Location: " . SITE_URL . "/admin/donations.php?action=view&id=" . $donation_id);
exit;
}
// Handle form submissions (Admin only for create/update/delete)
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['action'])) {
switch ($_POST['action']) {
case 'create':
if (!isAdmin()) {
$error = 'You do not have permission to perform this action.';
break;
}
try {
// Validate required fields
$name = trim(sanitizeInput($_POST['name'] ?? ''));
$father_name = trim(sanitizeInput($_POST['father_name'] ?? ''));
$mobile = trim(sanitizeInput($_POST['mobile'] ?? ''));
$email = !empty($_POST['email']) ? trim(sanitizeInput($_POST['email'])) : null;
$address = trim(sanitizeInput($_POST['address'] ?? ''));
$pan_card = !empty($_POST['pan_card']) ? trim(sanitizeInput($_POST['pan_card'])) : null;
$amount = floatval($_POST['amount'] ?? 0);
$payment_method = trim(sanitizeInput($_POST['payment_method'] ?? ''));
$payment_id = !empty($_POST['payment_id']) ? trim(sanitizeInput($_POST['payment_id'])) : null;
$order_id = !empty($_POST['order_id']) ? trim(sanitizeInput($_POST['order_id'])) : null;
$status = trim(sanitizeInput($_POST['status'] ?? ''));
$user_id = !empty($_POST['user_id']) ? intval($_POST['user_id']) : 0;
// Validate inputs
$errors = [];
if (empty($name)) $errors[] = 'Name is required.';
if (empty($father_name)) $errors[] = 'Father\'s name is required.';
if (empty($mobile) || !preg_match('/^[0-9]{10,15}$/', $mobile)) $errors[] = 'Valid mobile number is required (10-15 digits).';
if (empty($address)) $errors[] = 'Address is required.';
if ($amount <= 0) $errors[] = 'Valid amount is required.';
if (!in_array($payment_method, ['online', 'offline'])) $errors[] = 'Select valid payment method (online or offline).';
if (!in_array($status, ['pending', 'completed', 'failed'])) $errors[] = 'Select valid status (pending, completed, failed).';
if ($email && !filter_var($email, FILTER_VALIDATE_EMAIL)) $errors[] = 'Enter valid email address.';
if ($pan_card && !preg_match('/^[A-Z]{5}[0-9]{4}[A-Z]{1}$/', $pan_card)) $errors[] = 'Enter valid PAN card number.';
if ($user_id > 0) {
$stmt = $db->prepare("SELECT id FROM users WHERE id = ?");
$stmt->execute([$user_id]);
if (!$stmt->fetch()) {
$errors[] = 'Invalid user ID.';
}
}
if ($order_id) {
$stmt = $db->prepare("SELECT amount, status FROM razorpay_orders WHERE order_id = ?");
$stmt->execute([$order_id]);
$razorpay_order = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$razorpay_order) {
$errors[] = 'Invalid order ID.';
} elseif ($razorpay_order['amount'] / 100 != $amount) {
$errors[] = 'Amount does not match Razorpay order.';
} elseif ($payment_id && $razorpay_order['status'] !== 'paid') {
$errors[] = 'Razorpay order has not been paid.';
}
}
if ($payment_id && $payment_method === 'offline') {
$errors[] = 'Payment ID is not applicable for offline payment.';
}
if ($payment_method === 'online' && !$order_id && !$payment_id) {
$errors[] = 'Order ID or Payment ID is required for online payment.';
}
if (!empty($errors)) {
throw new Exception(implode(' ', $errors));
}
// Handle photo upload
$photo = null;
if (!empty($_FILES['photo']['name']) && $_FILES['photo']['error'] === UPLOAD_ERR_OK) {
$uploadResult = uploadFile($_FILES['photo'], 'img/users');
if ($uploadResult['success']) {
$photo = $uploadResult['filename'];
} else {
throw new Exception('Photo upload error: ' . $uploadResult['error']);
}
}
// Handle payment proof upload
$payment_proof = null;
if (!empty($_FILES['payment_proof']['name']) && $_FILES['payment_proof']['error'] === UPLOAD_ERR_OK) {
$uploadResult = uploadFile($_FILES['payment_proof'], 'img/payments');
if ($uploadResult['success']) {
$payment_proof = $uploadResult['filename'];
} else {
throw new Exception('Payment proof upload error: ' . $uploadResult['error']);
}
}
// Insert into database
$stmt = $db->prepare("
INSERT INTO donations (
user_id, name, father_name, mobile, email, address, pan_card, amount,
photo, payment_id, order_id, payment_proof, payment_method, status, created_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
");
$stmt->execute([
$user_id, $name, $father_name, $mobile, $email, $address, $pan_card,
$amount, $photo, $payment_id, $order_id, $payment_proof, $payment_method, $status
]);
$donation_id = $db->lastInsertId();
if ($status === 'completed' && $email) {
$donationData = [
'id' => $donation_id,
'name' => $name,
'father_name' => $father_name,
'mobile' => $mobile,
'email' => $email,
'address' => $address,
'pan_card' => $pan_card,
'amount' => $amount,
'payment_method' => $payment_method,
'payment_id' => $payment_id,
'status' => $status,
'created_at' => date('Y-m-d H:i:s')
];
if (sendDonationConfirmationEmail($donationData)) {
$message = 'Donation record added successfully and email sent!';
} else {
$message = 'Donation record added successfully! (Problem sending email)';
}
} else {
$message = 'Donation record added successfully!';
}
header("Location: " . SITE_URL . "/admin/donations.php");
exit;
} catch (Exception $e) {
$error = 'Error adding donation: ' . $e->getMessage();
}
break;
case 'update':
if (!isAdmin()) {
$error = 'You do not have permission to perform this action.';
break;
}
try {
$donation_id = intval($_POST['id']);
$name = trim(sanitizeInput($_POST['name']));
$father_name = trim(sanitizeInput($_POST['father_name']));
$mobile = trim(sanitizeInput($_POST['mobile']));
$email = !empty($_POST['email']) ? trim(sanitizeInput($_POST['email'])) : null;
$address = trim(sanitizeInput($_POST['address']));
$pan_card = !empty($_POST['pan_card']) ? trim(sanitizeInput($_POST['pan_card'])) : null;
$amount = floatval($_POST['amount']);
$payment_method = trim(sanitizeInput($_POST['payment_method']));
$payment_id = !empty($_POST['payment_id']) ? trim(sanitizeInput($_POST['payment_id'])) : null;
$order_id = !empty($_POST['order_id']) ? trim(sanitizeInput($_POST['order_id'])) : null;
$status = trim(sanitizeInput($_POST['status']));
$user_id = !empty($_POST['user_id']) ? intval($_POST['user_id']) : 0;
// Validate required fields
$errors = [];
if (empty($name)) $errors[] = 'Name is required.';
if (empty($father_name)) $errors[] = 'Father\'s name is required.';
if (empty($mobile) || !preg_match('/^[0-9]{10,15}$/', $mobile)) $errors[] = 'Valid mobile number is required.';
if (empty($address)) $errors[] = 'Address is required.';
if ($amount <= 0) $errors[] = 'Valid amount is required.';
if (!in_array($payment_method, ['online', 'offline'])) $errors[] = 'Select valid payment method.';
if (!in_array($status, ['pending', 'completed', 'failed'])) $errors[] = 'Select valid status.';
if ($email && !filter_var($email, FILTER_VALIDATE_EMAIL)) $errors[] = 'Enter valid email address.';
if ($pan_card && !preg_match('/^[A-Z]{5}[0-9]{4}[A-Z]{1}$/', $pan_card)) $errors[] = 'Enter valid PAN card number.';
if ($user_id > 0) {
$stmt = $db->prepare("SELECT id FROM users WHERE id = ?");
$stmt->execute([$user_id]);
if (!$stmt->fetch()) {
$errors[] = 'Invalid user ID.';
}
}
if ($order_id) {
$stmt = $db->prepare("SELECT amount, status FROM razorpay_orders WHERE order_id = ?");
$stmt->execute([$order_id]);
$razorpay_order = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$razorpay_order) {
$errors[] = 'Invalid order ID.';
} elseif ($razorpay_order['amount'] / 100 != $amount) {
$errors[] = 'Amount does not match Razorpay order.';
} elseif ($payment_id && $razorpay_order['status'] !== 'paid') {
$errors[] = 'Razorpay order has not been paid.';
}
}
if ($payment_id && $payment_method === 'offline') {
$errors[] = 'Payment ID is not applicable for offline payment.';
}
if ($payment_method === 'online' && !$order_id && !$payment_id) {
$errors[] = 'Order ID or Payment ID is required for online payment.';
}
if (!empty($errors)) {
throw new Exception(implode(' ', $errors));
}
// Get current data
$stmt = $db->prepare("SELECT photo, payment_proof FROM donations WHERE id = ?");
$stmt->execute([$donation_id]);
$current_data = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$current_data) {
throw new Exception('Donation record not found.');
}
$photo = $current_data['photo'];
$payment_proof = $current_data['payment_proof'];
// Handle photo upload
if (!empty($_FILES['photo']['name']) && $_FILES['photo']['error'] === UPLOAD_ERR_OK) {
$uploadResult = uploadFile($_FILES['photo'], 'img/users');
if ($uploadResult['success']) {
// Delete old photo
if (!empty($photo) && file_exists('../img/users/' . $photo)) {
unlink('../img/users/' . $photo);
}
$photo = $uploadResult['filename'];
} else {
throw new Exception('Photo upload error: ' . $uploadResult['error']);
}
}
// Handle payment proof upload
if (!empty($_FILES['payment_proof']['name']) && $_FILES['payment_proof']['error'] === UPLOAD_ERR_OK) {
$uploadResult = uploadFile($_FILES['payment_proof'], 'img/payments');
if ($uploadResult['success']) {
// Delete old payment proof
if (!empty($payment_proof) && file_exists('../img/payments/' . $payment_proof)) {
unlink('../img/payments/' . $payment_proof);
}
$payment_proof = $uploadResult['filename'];
} else {
throw new Exception('Payment proof upload error: ' . $uploadResult['error']);
}
}
// Update database
$stmt = $db->prepare("
UPDATE donations SET
user_id = ?, name = ?, father_name = ?, mobile = ?, email = ?,
address = ?, pan_card = ?, amount = ?, photo = ?, payment_id = ?,
order_id = ?, payment_proof = ?, payment_method = ?, status = ?
WHERE id = ?
");
$stmt->execute([
$user_id, $name, $father_name, $mobile, $email, $address, $pan_card,
$amount, $photo, $payment_id, $order_id, $payment_proof, $payment_method,
$status, $donation_id
]);
$message = 'Donation record updated successfully!';
header("Location: " . SITE_URL . "/admin/donations.php");
exit;
} catch (Exception $e) {
$error = 'Error updating donation: ' . $e->getMessage();
}
break;
case 'update_status':
if (!isAdmin()) {
$error = 'You do not have permission to perform this action.';
break;
}
try {
$donation_id = intval($_POST['id']);
$status = trim(sanitizeInput($_POST['status']));
if (!in_array($status, ['pending', 'completed', 'failed'])) {
throw new Exception('Invalid status.');
}
$stmt = $db->prepare("SELECT * FROM donations WHERE id = ?");
$stmt->execute([$donation_id]);
$donationData = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$donationData) {
throw new Exception('Donation record not found.');
}
$stmt = $db->prepare("UPDATE donations SET status = ? WHERE id = ?");
$stmt->execute([$status, $donation_id]);
if ($status === 'completed' && !empty($donationData['email']) && $donationData['status'] !== 'completed') {
$donationData['status'] = $status; // Update status for email
if (sendDonationConfirmationEmail($donationData)) {
$message = 'Donation status updated and email sent!';
} else {
$message = 'Donation status updated! (Problem sending email)';
}
} else {
$message = 'Donation status updated!';
}
} catch (Exception $e) {
$error = 'Error updating status: ' . $e->getMessage();
}
break;
case 'delete':
if (!isAdmin()) {
$error = 'You do not have permission to perform this action.';
break;
}
try {
$delete_id = intval($_POST['id']);
// Get files before deleting
$stmt = $db->prepare("SELECT photo, payment_proof FROM donations WHERE id = ?");
$stmt->execute([$delete_id]);
$donation = $stmt->fetch(PDO::FETCH_ASSOC);
// Delete donation
$stmt = $db->prepare("DELETE FROM donations WHERE id = ?");
$stmt->execute([$delete_id]);
// Delete files if they exist
if (!empty($donation['photo']) && file_exists('../img/users/' . $donation['photo'])) {
unlink('../img/users/' . $donation['photo']);
}
if (!empty($donation['payment_proof']) && file_exists('../img/payments/' . $donation['payment_proof'])) {
unlink('../img/payments/' . $donation['payment_proof']);
}
$message = 'Donation record deleted successfully!';
} catch (Exception $e) {
$error = 'Error deleting: ' . $e->getMessage();
}
break;
}
}
}
function sendDonationConfirmationEmail($donationData) {
if (empty($donationData['email'])) {
return false; // No email provided
}
$subject = "Donation Receipt - " . ORGANIZATION_NAME;
// Get site configuration
$siteConfig = getSiteConfig();
$orgDetails = [
'organization_name' => ORGANIZATION_NAME_HINDI,
'organization_name_en' => ORGANIZATION_NAME,
'registration_info' => defined('REGISTRATION_INFO') ? REGISTRATION_INFO : '',
'email' => $siteConfig['email'] ?? '',
'helpline_no' => $siteConfig['phone1'] ?? '',
'chairman_name' => CERTIFICATE_CHAIRMAN_NAME,
'chairman_title' => CERTIFICATE_CHAIRMAN_TITLE,
'address' => $siteConfig['address'] ?? '',
'logo_path' => SITE_URL . '/img/logo.png',
'signature_path' => SITE_URL . '/img/signature.png',
'seal_path' => SITE_URL . '/img/seal.png',
'watermark_path' => SITE_URL . '/img/logo.png',
'website_url' => str_replace(['http://', 'https://'], '', SITE_URL)
];
// DYNAMIC PREFIX LOGIC: Uses ORGANIZATION_NAME_SHORT from config.php
$prefix = defined('ORGANIZATION_NAME_SHORT') ? ORGANIZATION_NAME_SHORT : 'BSF';
$receiptNumber = $prefix . '-' . date('Y') . '-' . str_pad($donationData['id'], 6, '0', STR_PAD_LEFT);
$amount = $donationData['amount'];
$donationDate = date('d-m-Y', strtotime($donationData['created_at']));
$amountInWords = numberToHindiWords($amount);
$paymentMethod = ucfirst($donationData['payment_method']);
$status = ucfirst($donationData['status']);
// Create email-optimized HTML receipt
$emailBody = '
Donation Receipt
Donation Receipt
Receipt No
Amount
Mode
Payment Status
Date
' . htmlspecialchars($receiptNumber) . '
₹' . number_format($amount, 2) . '
' . htmlspecialchars($paymentMethod) . '
' . $status . '
' . $donationDate . '
Received From
' . htmlspecialchars($donationData['name']) . '
Rupees (in words)
' . $amountInWords . ' Rupees Only
Address
' . htmlspecialchars($donationData['address']) . '
' . (!empty($donationData['pan_card']) ? '
PAN Card
' . htmlspecialchars($donationData['pan_card']) . '
' : '') . '
';
// Send email using existing sendEmail function
return sendEmail($donationData['email'], $subject, $emailBody, true);
}
// Enhanced function to send receipt via email with better error handling
function sendReceiptEmail($donationId, $recipientEmail = null) {
try {
$db = getDbConnection();
$stmt = $db->prepare("SELECT * FROM donations WHERE id = ?");
$stmt->execute([$donationId]);
$donationData = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$donationData) {
throw new Exception('Donation record not found.');
}
// Use provided email or donation email
$email = $recipientEmail ?: $donationData['email'];
if (empty($email)) {
throw new Exception('Email address not available.');
}
$donationData['email'] = $email; // Ensure email is set for the function
if (sendDonationConfirmationEmail($donationData)) {
return ['success' => true, 'message' => 'Receipt sent successfully via email.'];
} else {
throw new Exception('Problem sending email.');
}
} catch (Exception $e) {
logError('Receipt email error: ' . $e->getMessage());
return ['success' => false, 'message' => $e->getMessage()];
}
}
// Function to handle manual email sending (for admin use)
function resendReceiptEmail($donationId, $newEmail = null) {
if (!isAdmin()) {
return ['success' => false, 'message' => 'You do not have permission to perform this action.'];
}
return sendReceiptEmail($donationId, $newEmail);
}
// Get donation data for editing/viewing (restrict to own data for non-admins)
$donation_data = null;
$razorpay_data = null;
if (($action === 'edit' || $action === 'view') && $id > 0) {
if ($action === 'edit' && !isAdmin()) {
$error = 'You do not have permission to perform this action.';
$action = 'list';
} else {
$sql = "SELECT d.*, u.name as user_name, u.designation as user_designation
FROM donations d
LEFT JOIN users u ON d.user_id = u.id
WHERE d.id = ?";
$params = [$id];
if (!isAdmin()) {
$sql .= " AND d.user_id = ?";
$params[] = $_SESSION['user_id'];
}
$stmt = $db->prepare($sql);
$stmt->execute($params);
$donation_data = $stmt->fetch(PDO::FETCH_ASSOC);
if ($donation_data && $donation_data['order_id']) {
$stmt = $db->prepare("SELECT order_id, payment_id, amount, status, payment_status, created_at
FROM razorpay_orders WHERE order_id = ?");
$stmt->execute([$donation_data['order_id']]);
$razorpay_data = $stmt->fetch(PDO::FETCH_ASSOC);
}
if (!$donation_data) {
$error = 'Donation record not found or you do not have permission to access this record!';
$action = 'list';
}
}
}
// Get donations list with role-based filtering
$donations_list = [];
$filter_status = $_GET['status'] ?? '';
if ($action === 'list') {
$sql = "SELECT d.*, u.name as user_name, u.designation as user_designation
FROM donations d
LEFT JOIN users u ON d.user_id = u.id";
$params = [];
if (!isAdmin()) {
$sql .= " WHERE d.user_id = ?";
$params[] = $_SESSION['user_id'];
}
if (!empty($filter_status)) {
$sql .= (isAdmin() ? " WHERE" : " AND") . " d.status = ?";
$params[] = $filter_status;
}
$sql .= " ORDER BY d.created_at DESC";
$stmt = $db->prepare($sql);
$stmt->execute($params);
$donations_list = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// Get statistics (restrict to own data for non-admins)
$stats = [];
try {
$sql = "SELECT
COUNT(*) as total_donations,
COALESCE(SUM(amount), 0) as total_amount,
COUNT(CASE WHEN status = 'completed' THEN 1 END) as completed_donations,
COALESCE(SUM(CASE WHEN status = 'completed' THEN amount ELSE 0 END), 0) as completed_amount,
COUNT(CASE WHEN status = 'pending' THEN 1 END) as pending_donations
FROM donations";
$params = [];
if (!isAdmin()) {
$sql .= " WHERE user_id = ?";
$params[] = $_SESSION['user_id'];
}
$stmt = $db->prepare($sql);
$stmt->execute($params);
$stats = $stmt->fetch(PDO::FETCH_ASSOC);
} catch (Exception $e) {
$stats = ['total_donations' => 0, 'total_amount' => 0, 'completed_donations' => 0, 'completed_amount' => 0, 'pending_donations' => 0];
}
include 'includes/header.php';
?>
No donations found
Click the button above to add the first donation.
Photo
Donor
User
Amount
Payment Method
Status
Date
Actions
0 ? htmlspecialchars($donation['user_name'] . ' (' . ($donation['user_designation'] ?? '') . ')') : 'N/A'; ?>
₹
User:
No User
prepare("SELECT id, name, designation FROM users WHERE status = 'approved' ORDER BY name");
$stmt->execute();
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($users as $user) {
$selected = $user['id'] == $donation_data['user_id'] ? 'selected' : '';
echo "" . htmlspecialchars($user['name']) . " (" . htmlspecialchars($user['designation'] ?? '') . ") ";
}
?>
Address: *
Payment Method: *
>Online
>Offline
Status: *
>Pending
>Completed
>Failed
User:
0 ? htmlspecialchars($donation_data['user_name'] . ' (' . ($donation_data['user_designation'] ?? '') . ')') : 'N/A'; ?>
Razorpay Order Details:
Order Status:
Payment Status:
Amount (Razorpay): ₹
Date: