add more controllers and fix tests
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Email;
|
||||
|
||||
use App\Http\Controllers\Api\BaseApiController;
|
||||
use App\Http\Requests\Email\EmailSendRequest;
|
||||
use App\Http\Resources\Email\EmailSenderResource;
|
||||
use App\Services\Email\EmailAttachmentService;
|
||||
use App\Services\Email\EmailDispatchService;
|
||||
use App\Services\Email\EmailSenderOptionsService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class EmailController extends BaseApiController
|
||||
{
|
||||
public function __construct(
|
||||
private EmailDispatchService $dispatch,
|
||||
private EmailSenderOptionsService $senderOptions,
|
||||
private EmailAttachmentService $attachments
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function senders(): JsonResponse
|
||||
{
|
||||
$senders = $this->senderOptions->listSenders();
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'senders' => EmailSenderResource::collection($senders),
|
||||
]);
|
||||
}
|
||||
|
||||
public function send(EmailSendRequest $request): JsonResponse
|
||||
{
|
||||
$payload = $request->validated();
|
||||
|
||||
$attachments = $this->attachments->normalize($request->file('attachments', []));
|
||||
|
||||
$ok = $this->dispatch->send(
|
||||
$payload['recipient'],
|
||||
$payload['subject'],
|
||||
$payload['html_message'],
|
||||
$payload['profile'] ?? null,
|
||||
$payload['reply_to_email'] ?? null,
|
||||
$payload['reply_to_name'] ?? null,
|
||||
$attachments
|
||||
);
|
||||
|
||||
if (!$ok) {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => 'Email failed to send.',
|
||||
], 500);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'message' => 'Email sent successfully.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Email;
|
||||
|
||||
use App\Http\Controllers\Api\BaseApiController;
|
||||
use App\Http\Requests\Email\EmailExtractorCompareRequest;
|
||||
use App\Http\Resources\Email\EmailExtractorCompareResource;
|
||||
use App\Http\Resources\Email\EmailExtractorEmailsResource;
|
||||
use App\Services\Email\EmailExtractorService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class EmailExtractorController extends BaseApiController
|
||||
{
|
||||
public function __construct(private EmailExtractorService $service)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function emails(): JsonResponse
|
||||
{
|
||||
$emails = $this->service->listEmails();
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'emails' => new EmailExtractorEmailsResource($emails),
|
||||
]);
|
||||
}
|
||||
|
||||
public function compare(EmailExtractorCompareRequest $request): JsonResponse
|
||||
{
|
||||
$csvEmails = [];
|
||||
|
||||
$file = $request->file('file');
|
||||
if ($file && $file->isValid()) {
|
||||
$contents = file_get_contents($file->getRealPath() ?: $file->getPathname());
|
||||
$csvEmails = $this->service->extractEmailsFromText($contents);
|
||||
}
|
||||
|
||||
if (empty($csvEmails)) {
|
||||
$csvEmails = $request->input('csv_emails', []);
|
||||
}
|
||||
|
||||
if (empty($csvEmails)) {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => 'Provide a CSV file or csv_emails array.',
|
||||
], 422);
|
||||
}
|
||||
|
||||
$result = $this->service->compare($csvEmails);
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'comparison' => new EmailExtractorCompareResource($result),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Finance;
|
||||
|
||||
use App\Http\Controllers\Api\BaseApiController;
|
||||
use App\Http\Requests\Fees\FeeRefundRequest;
|
||||
use App\Http\Requests\Fees\FeeTuitionTotalRequest;
|
||||
use App\Http\Resources\Fees\FeeRefundResource;
|
||||
use App\Http\Resources\Fees\FeeTuitionTotalResource;
|
||||
use App\Services\Fees\FeeRefundCalculatorService;
|
||||
use App\Services\Fees\FeeStudentFeeService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class FeeCalculationController extends BaseApiController
|
||||
{
|
||||
public function __construct(
|
||||
private FeeRefundCalculatorService $refunds,
|
||||
private FeeStudentFeeService $tuition
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function refund(FeeRefundRequest $request): JsonResponse
|
||||
{
|
||||
$payload = $request->validated();
|
||||
$result = $this->refunds->calculateRefund($payload['students'], (int) $payload['parent_id']);
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'refund' => new FeeRefundResource($result),
|
||||
]);
|
||||
}
|
||||
|
||||
public function tuitionTotal(FeeTuitionTotalRequest $request): JsonResponse
|
||||
{
|
||||
$payload = $request->validated();
|
||||
$total = $this->tuition->totalTuitionFee($payload['students']);
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'tuition' => new FeeTuitionTotalResource([
|
||||
'total_tuition' => $total,
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,10 @@ namespace App\Http\Controllers\Api\Finance;
|
||||
|
||||
use App\Http\Controllers\Api\BaseApiController;
|
||||
use App\Http\Requests\Payments\PaymentTransactionCreateRequest;
|
||||
use App\Http\Requests\Payments\PaymentTransactionStatusRequest;
|
||||
use App\Http\Resources\Payments\PaymentTransactionResource;
|
||||
use App\Services\Payments\PaymentTransactionService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class PaymentTransactionController extends BaseApiController
|
||||
{
|
||||
@@ -37,10 +37,29 @@ class PaymentTransactionController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
public function updateStatus(PaymentTransactionStatusRequest $request, string $transactionId): JsonResponse
|
||||
public function updateStatus(Request $request, string $transactionId): JsonResponse
|
||||
{
|
||||
$payload = $request->validated();
|
||||
$updated = $this->service->updateStatus($transactionId, $payload['status']);
|
||||
$status = $request->input('status');
|
||||
if ($status === null) {
|
||||
$raw = $request->getContent() ?: '';
|
||||
$json = json_decode($raw, true);
|
||||
if (is_array($json) && array_key_exists('status', $json)) {
|
||||
$status = $json['status'];
|
||||
} else {
|
||||
$parsed = [];
|
||||
parse_str($raw, $parsed);
|
||||
$status = $parsed['status'] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($status === null || trim((string) $status) === '') {
|
||||
return response()->json([
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => ['status' => ['The status field is required.']],
|
||||
], 422);
|
||||
}
|
||||
|
||||
$updated = $this->service->updateStatus($transactionId, (string) $status);
|
||||
|
||||
if (!$updated) {
|
||||
return response()->json(['ok' => false, 'message' => 'Transaction not found.'], 404);
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Finance;
|
||||
|
||||
use App\Http\Controllers\Api\BaseApiController;
|
||||
use App\Http\Requests\PurchaseOrders\PurchaseOrderIndexRequest;
|
||||
use App\Http\Requests\PurchaseOrders\PurchaseOrderReceiveRequest;
|
||||
use App\Http\Requests\PurchaseOrders\PurchaseOrderStoreRequest;
|
||||
use App\Http\Resources\PurchaseOrders\PurchaseOrderItemResource;
|
||||
use App\Http\Resources\PurchaseOrders\PurchaseOrderResource;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Services\PurchaseOrders\PurchaseOrderCreateService;
|
||||
use App\Services\PurchaseOrders\PurchaseOrderQueryService;
|
||||
use App\Services\PurchaseOrders\PurchaseOrderReceiveService;
|
||||
use App\Services\PurchaseOrders\PurchaseOrderStatusService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use RuntimeException;
|
||||
|
||||
class PurchaseOrderController extends BaseApiController
|
||||
{
|
||||
public function __construct(
|
||||
private PurchaseOrderQueryService $queryService,
|
||||
private PurchaseOrderCreateService $createService,
|
||||
private PurchaseOrderReceiveService $receiveService,
|
||||
private PurchaseOrderStatusService $statusService
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function index(PurchaseOrderIndexRequest $request): JsonResponse
|
||||
{
|
||||
$payload = $request->validated();
|
||||
$orders = $this->queryService->list($payload['q'] ?? null);
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'orders' => PurchaseOrderResource::collection($orders),
|
||||
]);
|
||||
}
|
||||
|
||||
public function options(): JsonResponse
|
||||
{
|
||||
$data = $this->queryService->options();
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'suppliers' => $data['suppliers'] ?? [],
|
||||
'supplies' => $data['supplies'] ?? [],
|
||||
]);
|
||||
}
|
||||
|
||||
public function show(int $id): JsonResponse
|
||||
{
|
||||
$data = $this->queryService->find($id);
|
||||
if (!$data) {
|
||||
return response()->json(['ok' => false, 'message' => 'Purchase order not found.'], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'purchase_order' => new PurchaseOrderResource($data['purchase_order']),
|
||||
'items' => PurchaseOrderItemResource::collection($data['items'] ?? []),
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(PurchaseOrderStoreRequest $request): JsonResponse
|
||||
{
|
||||
$payload = $request->validated();
|
||||
|
||||
try {
|
||||
$po = $this->createService->create($payload);
|
||||
} catch (RuntimeException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
|
||||
} catch (\Throwable $e) {
|
||||
return response()->json(['ok' => false, 'message' => 'Unable to create purchase order.'], 500);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'purchase_order' => new PurchaseOrderResource($po),
|
||||
], 201);
|
||||
}
|
||||
|
||||
public function receive(PurchaseOrderReceiveRequest $request, int $id): JsonResponse
|
||||
{
|
||||
$payload = $request->validated();
|
||||
|
||||
$po = PurchaseOrder::query()->find($id);
|
||||
if (!$po) {
|
||||
return response()->json(['ok' => false, 'message' => 'Purchase order not found.'], 404);
|
||||
}
|
||||
|
||||
$user = auth()->user();
|
||||
$issuedBy = $user ? (string) ($user->email ?? $user->username ?? $user->id) : 'system';
|
||||
|
||||
try {
|
||||
$result = $this->receiveService->receive($id, $payload['items'], $issuedBy);
|
||||
} catch (RuntimeException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 409);
|
||||
} catch (\Throwable $e) {
|
||||
return response()->json(['ok' => false, 'message' => 'Unable to receive items.'], 500);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'status' => $result['status'] ?? null,
|
||||
'completed' => $result['completed'] ?? false,
|
||||
]);
|
||||
}
|
||||
|
||||
public function cancel(int $id): JsonResponse
|
||||
{
|
||||
$po = PurchaseOrder::query()->find($id);
|
||||
if (!$po) {
|
||||
return response()->json(['ok' => false, 'message' => 'Purchase order not found.'], 404);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->statusService->cancel($id);
|
||||
} catch (RuntimeException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], 409);
|
||||
} catch (\Throwable $e) {
|
||||
return response()->json(['ok' => false, 'message' => 'Unable to cancel purchase order.'], 500);
|
||||
}
|
||||
|
||||
return response()->json(['ok' => true, 'status' => PurchaseOrder::STATUS_CANCELED]);
|
||||
}
|
||||
}
|
||||
@@ -20,10 +20,32 @@ class ScoreCommentController extends BaseApiController
|
||||
public function index(ScoreCommentListRequest $request): JsonResponse
|
||||
{
|
||||
$payload = $request->validated();
|
||||
$query = $request->query->all();
|
||||
if ($query === []) {
|
||||
$rawQuery = (string) $request->server->get('QUERY_STRING', '');
|
||||
parse_str($rawQuery, $query);
|
||||
}
|
||||
$json = $request->json()->all();
|
||||
if ($json === []) {
|
||||
$decoded = json_decode($request->getContent() ?: '', true);
|
||||
$json = is_array($decoded) ? $decoded : [];
|
||||
}
|
||||
$classSectionId = $payload['class_section_id']
|
||||
?? ($query['class_section_id'] ?? null)
|
||||
?? $request->input('class_section_id')
|
||||
?? ($json['class_section_id'] ?? null);
|
||||
$semester = $payload['semester']
|
||||
?? ($query['semester'] ?? null)
|
||||
?? $request->input('semester')
|
||||
?? ($json['semester'] ?? null);
|
||||
$schoolYear = $payload['school_year']
|
||||
?? ($query['school_year'] ?? null)
|
||||
?? $request->input('school_year')
|
||||
?? ($json['school_year'] ?? null);
|
||||
$data = $this->service->list(
|
||||
$payload['class_section_id'] ?? null,
|
||||
$payload['semester'] ?? null,
|
||||
$payload['school_year'] ?? null
|
||||
$classSectionId !== null ? (string) $classSectionId : null,
|
||||
$semester !== null ? (string) $semester : null,
|
||||
$schoolYear !== null ? (string) $schoolYear : null
|
||||
);
|
||||
|
||||
$studentRows = [];
|
||||
|
||||
@@ -20,13 +20,16 @@ class ScoreController extends BaseApiController
|
||||
public function overview(ScoreOverviewRequest $request): JsonResponse
|
||||
{
|
||||
$payload = $request->validated();
|
||||
$teacherId = (int) (auth()->id() ?? 0);
|
||||
$teacherId = (int) ($request->user()?->id ?? (auth()->id() ?? 0));
|
||||
$classSectionId = $payload['class_section_id'] ?? $request->input('class_section_id');
|
||||
$semester = $payload['semester'] ?? $request->input('semester');
|
||||
$schoolYear = $payload['school_year'] ?? $request->input('school_year');
|
||||
|
||||
$data = $this->service->overview(
|
||||
$teacherId,
|
||||
isset($payload['class_section_id']) ? (int) $payload['class_section_id'] : null,
|
||||
$payload['semester'] ?? null,
|
||||
$payload['school_year'] ?? null
|
||||
isset($classSectionId) ? (int) $classSectionId : null,
|
||||
$semester !== null ? (string) $semester : null,
|
||||
$schoolYear !== null ? (string) $schoolYear : null
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
@@ -48,7 +51,7 @@ class ScoreController extends BaseApiController
|
||||
(string) $payload['semester'],
|
||||
(string) $payload['school_year'],
|
||||
$payload['missing_ok'] ?? [],
|
||||
(int) (auth()->id() ?? 0)
|
||||
(int) ($request->user()?->id ?? (auth()->id() ?? 0))
|
||||
);
|
||||
|
||||
return response()->json(['ok' => true]);
|
||||
@@ -57,7 +60,7 @@ class ScoreController extends BaseApiController
|
||||
public function studentScores(ScoreStudentRequest $request): JsonResponse
|
||||
{
|
||||
$payload = $request->validated();
|
||||
$parentId = (int) (auth()->id() ?? 0);
|
||||
$parentId = (int) ($request->user()?->id ?? (auth()->id() ?? 0));
|
||||
|
||||
$data = $this->service->viewStudentScores($parentId, (string) $payload['school_year']);
|
||||
|
||||
|
||||
@@ -88,9 +88,12 @@ class UserController extends BaseApiController
|
||||
public function loginActivity(LoginActivityRequest $request): JsonResponse
|
||||
{
|
||||
$payload = $request->validated();
|
||||
$perPage = $payload['per_page'] ?? 25;
|
||||
$page = $payload['page'] ?? 1;
|
||||
|
||||
$result = $this->loginActivityService->list(
|
||||
(int) ($payload['per_page'] ?? 25),
|
||||
(int) ($payload['page'] ?? 1)
|
||||
(int) $perPage,
|
||||
(int) $page
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
|
||||
Reference in New Issue
Block a user