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