153 lines
5.2 KiB
PHP
153 lines
5.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\Finance;
|
|
|
|
use App\Http\Controllers\Api\Core\BaseApiController;
|
|
use App\Http\Requests\Invoices\InvoiceManagementRequest;
|
|
use App\Http\Requests\Invoices\InvoiceParentRequest;
|
|
use App\Http\Requests\Invoices\InvoiceStatusRequest;
|
|
use App\Http\Resources\Invoices\InvoiceManagementParentResource;
|
|
use App\Http\Resources\Invoices\InvoiceResource;
|
|
use App\Models\Invoice;
|
|
use App\Services\Invoices\InvoiceGenerationService;
|
|
use App\Services\Invoices\InvoiceManagementService;
|
|
use App\Services\Invoices\InvoicePaymentService;
|
|
use App\Services\Invoices\InvoicePdfService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Validator;
|
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
|
|
|
class InvoiceController extends BaseApiController
|
|
{
|
|
public function __construct(
|
|
private InvoiceManagementService $management,
|
|
private InvoiceGenerationService $generation,
|
|
private InvoicePaymentService $paymentService,
|
|
private InvoicePdfService $pdfService
|
|
) {
|
|
parent::__construct();
|
|
}
|
|
|
|
public function management(InvoiceManagementRequest $request): JsonResponse
|
|
{
|
|
$schoolYear = $request->validated()['school_year'] ?? null;
|
|
$schoolYear = $schoolYear ?: $request->input('schoolYear');
|
|
$schoolYear = $schoolYear ?: $request->input('year');
|
|
|
|
$data = $this->management->getManagementData($schoolYear);
|
|
|
|
return response()->json([
|
|
'ok' => true,
|
|
'schoolYear' => $data['schoolYear'],
|
|
'schoolYears' => $data['schoolYears'],
|
|
'invoices' => InvoiceManagementParentResource::collection($data['invoices']),
|
|
]);
|
|
}
|
|
|
|
public function generate(Request $request): JsonResponse
|
|
{
|
|
$data = array_merge($request->query->all(), $request->all(), $request->json()->all());
|
|
$validator = Validator::make($data, [
|
|
'parent_id' => ['required', 'integer', 'exists:users,id'],
|
|
'school_year' => ['nullable', 'string', 'max:20'],
|
|
]);
|
|
|
|
if ($validator->fails()) {
|
|
return response()->json([
|
|
'message' => 'Validation failed.',
|
|
'errors' => $validator->errors(),
|
|
], 422);
|
|
}
|
|
|
|
$payload = $validator->validated();
|
|
$result = $this->generation->generateInvoice((int) $payload['parent_id'], $payload['school_year'] ?? null);
|
|
|
|
if (empty($result['ok'])) {
|
|
return response()->json(['ok' => false, 'message' => $result['message'] ?? 'Unable to generate invoice.'], 422);
|
|
}
|
|
|
|
return response()->json([
|
|
'ok' => true,
|
|
'updated' => $result['updated'] ?? false,
|
|
'updated_ids' => $result['updated_ids'] ?? [],
|
|
'insert_id' => $result['insert_id'] ?? null,
|
|
]);
|
|
}
|
|
|
|
public function byParent(InvoiceParentRequest $request, int $parentId): JsonResponse
|
|
{
|
|
$schoolYear = $request->validated()['school_year'] ?? null;
|
|
$invoices = Invoice::getInvoicesByParentId($parentId, $schoolYear);
|
|
|
|
return response()->json([
|
|
'ok' => true,
|
|
'invoices' => InvoiceResource::collection($invoices),
|
|
]);
|
|
}
|
|
|
|
public function parentPayment(InvoiceParentRequest $request): JsonResponse
|
|
{
|
|
$parentId = $this->authenticatedUserIdOrUnauthorized();
|
|
if ($parentId instanceof JsonResponse) {
|
|
return $parentId;
|
|
}
|
|
|
|
$schoolYear = $request->validated()['school_year'] ?? null;
|
|
$data = $this->paymentService->getParentInvoiceSummary($parentId, $schoolYear);
|
|
|
|
return response()->json([
|
|
'ok' => true,
|
|
'invoices' => InvoiceResource::collection($data['invoices']),
|
|
'schoolYears' => $data['schoolYears'],
|
|
'selectedYear' => $data['selectedYear'],
|
|
'currentSchoolYear' => $data['currentSchoolYear'],
|
|
'dueDate' => $data['dueDate'],
|
|
]);
|
|
}
|
|
|
|
public function updateStatus(InvoiceStatusRequest $request, int $invoiceId): JsonResponse
|
|
{
|
|
$status = $request->validated()['status'];
|
|
$updated = Invoice::updateInvoiceStatus($invoiceId, $status);
|
|
|
|
if (!$updated) {
|
|
return response()->json(['ok' => false, 'message' => 'Invoice not found.'], 404);
|
|
}
|
|
|
|
return response()->json(['ok' => true, 'status' => $status]);
|
|
}
|
|
|
|
public function unpaid(): JsonResponse
|
|
{
|
|
$rows = Invoice::getUnpaidInvoices();
|
|
|
|
return response()->json([
|
|
'ok' => true,
|
|
'invoices' => InvoiceResource::collection($rows),
|
|
]);
|
|
}
|
|
|
|
public function pdf(int $invoiceId): StreamedResponse
|
|
{
|
|
$pdfBytes = $this->pdfService->buildPdf($invoiceId);
|
|
|
|
return response()->streamDownload(function () use ($pdfBytes) {
|
|
echo $pdfBytes;
|
|
}, 'invoice_' . $invoiceId . '.pdf', ['Content-Type' => 'application/pdf']);
|
|
}
|
|
|
|
/**
|
|
* @return int|JsonResponse
|
|
*/
|
|
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
|
{
|
|
$userId = (int) (auth()->id() ?? 0);
|
|
if ($userId <= 0) {
|
|
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
|
|
}
|
|
|
|
return $userId;
|
|
}
|
|
}
|