add controllers, servoices
This commit is contained in:
@@ -0,0 +1,218 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Finance;
|
||||
|
||||
use App\Http\Controllers\Api\BaseApiController;
|
||||
use App\Http\Requests\Finance\FinancialReportRequest;
|
||||
use App\Http\Requests\Finance\FinancialSummaryRequest;
|
||||
use App\Http\Requests\Finance\FinancialUnpaidParentsRequest;
|
||||
use App\Http\Resources\Finance\FinancialReportResource;
|
||||
use App\Http\Resources\Finance\FinancialSummaryResource;
|
||||
use App\Http\Resources\Finance\FinancialUnpaidParentResource;
|
||||
use App\Services\Finance\FinancialPdfReportService;
|
||||
use App\Services\Finance\FinancialReportService;
|
||||
use App\Services\Finance\FinancialSchoolYearService;
|
||||
use App\Services\Finance\FinancialSummaryService;
|
||||
use App\Services\Finance\FinancialUnpaidParentsService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class FinancialController extends BaseApiController
|
||||
{
|
||||
public function __construct(
|
||||
private FinancialReportService $reportService,
|
||||
private FinancialSummaryService $summaryService,
|
||||
private FinancialUnpaidParentsService $unpaidParentsService,
|
||||
private FinancialSchoolYearService $schoolYears,
|
||||
private FinancialPdfReportService $pdfService
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function report(FinancialReportRequest $request): JsonResponse
|
||||
{
|
||||
$payload = $request->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']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user