Spaces:
Running
Running
File size: 7,831 Bytes
e31284f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | <?php
/**
* API Endpoint: Get Last Payment Receipt Image
*
* Returns the receipt image (PNG) of the last payment made by a student.
*
* Method: GET
* URL: /api/students/last_receipt?student_id=...
*
* Response: PNG image (binary)
*
* Error Response: JSON with error message
*/
require_once '../../db_config.php';
require_once '../../includes/ReceiptGenerator.php';
require_once '../../includes/ApiValidator.php';
require_once '../../config/api_config.php';
// Initialize validator
$validator = new ApiValidator($pdo, defined('API_KEYS') ? API_KEYS : []);
// 1. Validate Request
$validation = $validator->validateRequest(['GET']);
if (!$validation['valid']) {
http_response_code($validation['http_code']);
header('Content-Type: application/json');
echo json_encode(['status' => 'error', 'message' => $validation['error']]);
exit;
}
// 2. Validate Input Parameters
$studentId = trim($_GET['student_id'] ?? '');
if (empty($studentId)) {
http_response_code(400);
header('Content-Type: application/json');
echo json_encode(['status' => 'error', 'message' => 'Student ID is required']);
exit;
}
// 3. Validate Student Exists
$studentCheck = $validator->validateStudentExists($studentId);
if (!$studentCheck['valid']) {
http_response_code($studentCheck['http_code']);
header('Content-Type: application/json');
echo json_encode(['status' => 'error', 'message' => $studentCheck['error']]);
exit;
}
// Prevent output from messing up image headers
ob_start();
ini_set('display_errors', 0);
error_reporting(E_ALL & ~E_DEPRECATED & ~E_NOTICE);
try {
// 4. Fetch Last Payment Receipt Number
$sqlLastReceipt = "SELECT receipt_no, payment_date
FROM tb_account_payment_registers
WHERE student_id = :student_id
ORDER BY payment_date DESC, id DESC
LIMIT 1";
$stmt = $pdo->prepare($sqlLastReceipt);
$stmt->execute(['student_id' => $studentId]);
$lastPayment = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$lastPayment) {
http_response_code(404);
header('Content-Type: application/json');
echo json_encode([
'status' => 'error',
'message' => 'No payment records found for this student'
]);
exit;
}
$receiptNo = $lastPayment['receipt_no'];
$paymentDate = $lastPayment['payment_date'];
// 5. Fetch Receipt Meta Info (Student, Date)
$sqlInfo = "SELECT pr.student_id, pr.payment_date,
sr.last_name, sr.first_name, sr.other_name, sr.student_code,
al.level_name
FROM tb_account_payment_registers pr
JOIN tb_student_registrations sr ON pr.student_id = sr.id
LEFT JOIN tb_academic_levels al ON sr.level_id = al.id
WHERE pr.receipt_no = :receipt_no
LIMIT 1";
$stmt = $pdo->prepare($sqlInfo);
$stmt->execute(['receipt_no' => $receiptNo]);
$receiptInfo = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$receiptInfo) {
http_response_code(500);
header('Content-Type: application/json');
echo json_encode([
'status' => 'error',
'message' => 'Receipt information not found'
]);
exit;
}
$studentId = $receiptInfo['student_id'];
// 6. Fetch All Fees for Student (from receivables)
$sqlFees = "SELECT ar.fee_id, ar.actual_value as amount_billed,
ar.academic_session, ar.term_of_session,
sf.description as fee_description
FROM tb_account_receivables ar
JOIN tb_account_school_fees sf ON ar.fee_id = sf.id
WHERE ar.student_id = :sid
ORDER BY ar.academic_session ASC, ar.term_of_session ASC";
$stmtFees = $pdo->prepare($sqlFees);
$stmtFees->execute(['sid' => $studentId]);
$allFees = $stmtFees->fetchAll(PDO::FETCH_ASSOC);
$allocations = [];
$receiptTotalPaid = 0;
foreach ($allFees as $fee) {
// Calculate Paid To Date (up to this receipt's date)
$sqlPaid = "SELECT SUM(amount_paid) as total_paid
FROM tb_account_payment_registers
WHERE student_id = :sid
AND fee_id = :fid
AND academic_session = :as
AND term_of_session = :ts
AND payment_date <= :pd";
$stmtPaid = $pdo->prepare($sqlPaid);
$stmtPaid->execute([
'sid' => $studentId,
'fid' => $fee['fee_id'],
'as' => $fee['academic_session'],
'ts' => $fee['term_of_session'],
'pd' => $paymentDate
]);
$paidResult = $stmtPaid->fetch(PDO::FETCH_ASSOC);
$paidToDate = floatval($paidResult['total_paid'] ?? 0);
// Calculate Amount paid IN THIS RECEIPT (for total calculation)
$sqlReceiptPay = "SELECT SUM(amount_paid) as receipt_paid
FROM tb_account_payment_registers
WHERE receipt_no = :rno
AND fee_id = :fid
AND academic_session = :as
AND term_of_session = :ts";
$stmtReceiptPay = $pdo->prepare($sqlReceiptPay);
$stmtReceiptPay->execute([
'rno' => $receiptNo,
'fid' => $fee['fee_id'],
'as' => $fee['academic_session'],
'ts' => $fee['term_of_session']
]);
$receiptPayResult = $stmtReceiptPay->fetch(PDO::FETCH_ASSOC);
$paidInReceipt = floatval($receiptPayResult['receipt_paid'] ?? 0);
$receiptTotalPaid += $paidInReceipt;
$balance = floatval($fee['amount_billed']) - $paidToDate;
// Condition: Show if (Balance > 0) OR (PaidInReceipt > 0)
// Helps filter out old fully paid fees, but keeps current payments even if they zeroed the balance
if ($balance > 0.001 || $paidInReceipt > 0.001) {
$allocations[] = [
'description' => $fee['fee_description'],
'academic_session' => $fee['academic_session'],
'term_of_session' => $fee['term_of_session'],
'amount_billed' => floatval($fee['amount_billed']),
'amount' => $paidInReceipt,
'total_paid_to_date' => $paidToDate,
'balance' => $balance
];
}
}
// 7. Prepare data structure for generator
$data = [
'receipt_no' => $receiptNo,
'student_name' => trim($receiptInfo['last_name'] . ' ' . $receiptInfo['first_name'] . ' ' . ($receiptInfo['other_name'] ?? '')),
'student_code' => $receiptInfo['student_code'],
'level_name' => $receiptInfo['level_name'] ?? '',
'payment_date' => $paymentDate,
'total_paid' => $receiptTotalPaid,
'allocations' => $allocations
];
// 8. Generate Image
$generator = new ReceiptGenerator();
$imageData = $generator->generate($data);
// 9. Output Image
ob_end_clean(); // Discard any warnings/output buffered so far
header('Content-Type: image/png');
header('Content-Disposition: inline; filename="receipt_' . $receiptNo . '.png"');
header('Content-Length: ' . strlen($imageData));
echo $imageData;
} catch (Exception $e) {
ob_end_clean();
http_response_code(500);
header('Content-Type: application/json');
echo json_encode([
'status' => 'error',
'message' => 'Error generating receipt: ' . $e->getMessage()
]);
}
|