validated(); $report = $this->reportService->getReport( $payload['date_from'] ?? null, $payload['date_to'] ?? null, $payload['school_year'] ?? null ); return response()->json([ 'ok' => true, 'report' => new FinancialReportResource($report), ]); } public function summary(FinancialSummaryRequest $request): JsonResponse { $payload = $request->validated(); $summary = $this->summaryService->getSummary( $payload['date_from'] ?? null, $payload['date_to'] ?? null, $payload['school_year'] ?? null ); $schoolYears = $this->schoolYears->listYears($summary['schoolYear'] ?? null); return response()->json([ 'ok' => true, 'summary' => new FinancialSummaryResource($summary), 'schoolYears' => $schoolYears, ]); } public function unpaidParents(FinancialUnpaidParentsRequest $request): JsonResponse { $payload = $request->validated(); $data = $this->unpaidParentsService->getUnpaidParents($payload['school_year'] ?? null); return response()->json([ 'ok' => true, 'schoolYear' => $data['schoolYear'] ?? null, 'schoolYears' => $data['schoolYears'] ?? [], 'results' => FinancialUnpaidParentResource::collection($data['results'] ?? []), ]); } public function downloadCsv(FinancialReportRequest $request): StreamedResponse { $payload = $request->validated(); $report = $this->reportService->getReport( $payload['date_from'] ?? null, $payload['date_to'] ?? null, $payload['school_year'] ?? null ); $paymentsMap = []; foreach ($report['payments'] as $payment) { $invoiceId = (int) ($payment['invoice_id'] ?? 0); $paymentsMap[$invoiceId] = (float) ($payment['paid_amount'] ?? 0); } $refundsMap = []; foreach ($report['refunds'] as $refund) { $invoiceId = (int) ($refund['invoice_id'] ?? 0); $refundsMap[$invoiceId] = (float) ($refund['total_refunded'] ?? 0); } $discountsMap = []; foreach ($report['discounts'] as $discount) { $invoiceId = (int) ($discount['invoice_id'] ?? 0); $discountsMap[$invoiceId] = (float) ($discount['discount_amount'] ?? 0); } $breakdown = $report['paymentBreakdown'] ?? []; $filename = 'financial_report_' . date('Ymd_His') . '.csv'; return response()->streamDownload(function () use ($report, $paymentsMap, $refundsMap, $discountsMap, $breakdown) { $out = fopen('php://output', 'w'); fputcsv($out, ['Invoice #', 'Parent', 'School Year', 'Total', 'Paid', 'Cash', 'Credit', 'Check', 'Balance', 'Refund', 'Discount', 'Status']); $sumTotal = 0.0; $sumPaid = 0.0; $sumCash = 0.0; $sumCredit = 0.0; $sumCheck = 0.0; $sumBalance = 0.0; $sumRefund = 0.0; $sumDiscount = 0.0; foreach ($report['invoices'] as $inv) { $invoiceId = (int) ($inv['id'] ?? 0); $paid = (float) ($paymentsMap[$invoiceId] ?? 0); $bd = $breakdown[$invoiceId] ?? []; $cash = (float) ($bd['cash'] ?? 0); $credit = (float) ($bd['credit'] ?? 0); $check = (float) ($bd['check'] ?? 0); $refunded = (float) ($refundsMap[$invoiceId] ?? 0); $discount = (float) ($discountsMap[$invoiceId] ?? 0); $total = (float) ($inv['total_amount'] ?? 0); $balance = $total - $paid - $discount - $refunded; if ($balance < 0) { $balance = 0.0; } $status = $balance === 0.0 ? 'Paid' : 'Unpaid'; fputcsv($out, [ $inv['invoice_number'] ?? '', $inv['parent_name'] ?? '', $inv['school_year'] ?? '', $total, $paid, $cash, $credit, $check, $balance, $refunded, $discount, $status, ]); $sumTotal += $total; $sumPaid += $paid; $sumCash += $cash; $sumCredit += $credit; $sumCheck += $check; $sumBalance += $balance; $sumRefund += $refunded; $sumDiscount += $discount; } fputcsv($out, [ 'TOTALS', '', '', $sumTotal, $sumPaid, $sumCash, $sumCredit, $sumCheck, $sumBalance, $sumRefund, $sumDiscount, '', ]); fputcsv($out, []); fputcsv($out, ['Expenses Summary']); fputcsv($out, ['Category', 'Total Amount']); foreach ($report['expenses'] as $exp) { fputcsv($out, [ $exp['category'] ?? '', $exp['total_amount'] ?? 0, ]); } fputcsv($out, []); fputcsv($out, ['Reimbursements Summary']); fputcsv($out, ['Status', 'Total Amount']); foreach ($report['reimbursements'] as $row) { fputcsv($out, [ $row['status'] ?? '', $row['total_amount'] ?? 0, ]); } fclose($out); }, $filename, ['Content-Type' => 'text/csv']); } public function downloadPdf(FinancialReportRequest $request): StreamedResponse { $payload = $request->validated(); $summary = $this->summaryService->getSummary( $payload['date_from'] ?? null, $payload['date_to'] ?? null, $payload['school_year'] ?? null ); $pdfBytes = $this->pdfService->buildPdf($summary); $schoolYear = $summary['schoolYear'] ?? 'report'; return response()->streamDownload(function () use ($pdfBytes) { echo $pdfBytes; }, 'Financial_Report_' . $schoolYear . '.pdf', ['Content-Type' => 'application/pdf']); } }