update controllers logic
This commit is contained in:
@@ -0,0 +1,282 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\PrintRequests;
|
||||
|
||||
use App\Http\Controllers\Api\Core\BaseApiController;
|
||||
use App\Models\PrintRequest;
|
||||
use App\Models\User;
|
||||
use App\Services\PrintRequests\PrintRequestsPortalService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class PrintRequestsController extends BaseApiController
|
||||
{
|
||||
public function __construct(
|
||||
private PrintRequestsPortalService $portal,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function teacher(): JsonResponse
|
||||
{
|
||||
$uid = $this->getCurrentUserId();
|
||||
if (! $uid) {
|
||||
return $this->error('Unauthorized.', Response::HTTP_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
return $this->success($this->portal->teacherBootstrap($uid));
|
||||
}
|
||||
|
||||
public function admin(): JsonResponse
|
||||
{
|
||||
return $this->success([
|
||||
'print_requests' => $this->portal->adminPrintRequests(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$uid = $this->getCurrentUserId();
|
||||
if (! $uid) {
|
||||
return $this->error('Unauthorized.', Response::HTTP_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
'file' => ['required', 'file', 'max:5120', 'mimes:pdf,jpg,jpeg,png,doc,docx,txt'],
|
||||
'page_selection' => ['nullable', 'string', 'regex:/^\s*\d+(?:\s*-\s*\d+)?(?:\s*,\s*\d+(?:\s*-\s*\d+)?)*\s*$/'],
|
||||
'num_copies' => ['required', 'integer', 'min:1'],
|
||||
'required_by' => ['required', 'date'],
|
||||
'pickup_method' => ['required', 'string', 'max:255'],
|
||||
'class_id' => ['required', 'integer', 'min:1'],
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return $this->respondValidationError($validator->errors()->toArray());
|
||||
}
|
||||
|
||||
/** @var \Illuminate\Http\UploadedFile $file */
|
||||
$file = $request->file('file');
|
||||
$model = $this->portal->storeTeacherUpload($validator->validated(), $file, $uid);
|
||||
|
||||
return $this->respondCreated(
|
||||
['print_request' => $this->portal->normalizePrintRequestRow($model->toArray())],
|
||||
'Print request created successfully.'
|
||||
);
|
||||
}
|
||||
|
||||
public function teacherUpdate(Request $request, int $id): JsonResponse
|
||||
{
|
||||
$uid = $this->getCurrentUserId();
|
||||
if (! $uid) {
|
||||
return $this->error('Unauthorized.', Response::HTTP_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
$pr = PrintRequest::query()->find($id);
|
||||
if (! $pr) {
|
||||
return $this->error('Print request not found.', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (! $this->portal->teacherOwnsRequest($pr, $uid)) {
|
||||
return $this->error('You are not authorized to edit this request.', Response::HTTP_FORBIDDEN);
|
||||
}
|
||||
|
||||
if (! $this->portal->teacherMayEditOrDelete($pr)) {
|
||||
return $this->error('Cannot edit a request that is already being processed.', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$rules = [
|
||||
'num_copies' => ['required', 'integer', 'min:1'],
|
||||
'required_by' => ['required', 'date'],
|
||||
'pickup_method' => ['required', 'string', Rule::in(['Self Pickup', 'Delivered to class'])],
|
||||
'page_selection' => ['nullable', 'string', 'regex:/^\s*\d+(?:\s*-\s*\d+)?(?:\s*,\s*\d+(?:\s*-\s*\d+)?)*\s*$/'],
|
||||
];
|
||||
|
||||
if ($request->hasFile('file') && $request->file('file')->isValid()) {
|
||||
$rules['file'] = ['required', 'file', 'max:5120', 'mimes:pdf,jpg,jpeg,png,doc,docx,txt'];
|
||||
}
|
||||
|
||||
$validator = Validator::make($request->all(), $rules);
|
||||
if ($validator->fails()) {
|
||||
return $this->respondValidationError($validator->errors()->toArray());
|
||||
}
|
||||
|
||||
$data = $validator->validated();
|
||||
$newFile = ($request->hasFile('file') && $request->file('file')->isValid())
|
||||
? $request->file('file')
|
||||
: null;
|
||||
|
||||
$model = $this->portal->updateTeacherFields($pr, $data, $newFile);
|
||||
|
||||
return $this->success(
|
||||
['print_request' => $this->portal->normalizePrintRequestRow($model->toArray())],
|
||||
'Print request updated successfully.'
|
||||
);
|
||||
}
|
||||
|
||||
public function adminStatus(Request $request, int $id): JsonResponse
|
||||
{
|
||||
$uid = $this->getCurrentUserId();
|
||||
if (! $uid) {
|
||||
return $this->error('Unauthorized.', Response::HTTP_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
'status' => ['required', 'string', Rule::in(['not_assigned', 'assigned', 'done', 'delivered'])],
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
return $this->respondValidationError($validator->errors()->toArray());
|
||||
}
|
||||
|
||||
$pr = PrintRequest::query()->find($id);
|
||||
if (! $pr) {
|
||||
return $this->error('Print request not found.', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
$newStatus = (string) $validator->validated()['status'];
|
||||
|
||||
try {
|
||||
$model = $this->portal->applyAdminStatus($pr, $newStatus, $uid);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return $this->error($e->getMessage(), Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
return $this->success(
|
||||
['print_request' => $this->portal->normalizePrintRequestRow($model->toArray())],
|
||||
'Status updated successfully.'
|
||||
);
|
||||
}
|
||||
|
||||
public function destroy(int $id): JsonResponse
|
||||
{
|
||||
$uid = $this->getCurrentUserId();
|
||||
if (! $uid) {
|
||||
return $this->error('Unauthorized.', Response::HTTP_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
$pr = PrintRequest::query()->find($id);
|
||||
if (! $pr) {
|
||||
return $this->error('Print request not found.', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (! $this->portal->teacherOwnsRequest($pr, $uid)) {
|
||||
return $this->error('You are not authorized to delete this request.', Response::HTTP_FORBIDDEN);
|
||||
}
|
||||
|
||||
if (! $this->portal->teacherMayEditOrDelete($pr)) {
|
||||
return $this->error('Cannot delete a request that is already being processed.', Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$this->portal->deleteTeacherRequest($pr);
|
||||
|
||||
return $this->respondDeleted(null, 'Print request deleted successfully.');
|
||||
}
|
||||
|
||||
public function copy(int $id): JsonResponse
|
||||
{
|
||||
$uid = $this->getCurrentUserId();
|
||||
if (! $uid) {
|
||||
return $this->error('Unauthorized.', Response::HTTP_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
$pr = PrintRequest::query()->find($id);
|
||||
if (! $pr) {
|
||||
return $this->error('Print request not found.', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (! $this->portal->teacherOwnsRequest($pr, $uid)) {
|
||||
return $this->error('You are not authorized to copy this request.', Response::HTTP_FORBIDDEN);
|
||||
}
|
||||
|
||||
try {
|
||||
$model = $this->portal->copyFromExisting($pr, $uid);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return $this->error($e->getMessage(), Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
return $this->respondCreated(
|
||||
['print_request' => $this->portal->normalizePrintRequestRow($model->toArray())],
|
||||
'Print request copied successfully.'
|
||||
);
|
||||
}
|
||||
|
||||
public function handCopy(Request $request): JsonResponse
|
||||
{
|
||||
$uid = $this->getCurrentUserId();
|
||||
if (! $uid) {
|
||||
return $this->error('Unauthorized.', Response::HTTP_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
'num_copies' => ['required', 'integer', 'min:1'],
|
||||
'required_by' => ['required', 'date'],
|
||||
'pickup_method' => ['required', 'string', 'max:255'],
|
||||
'class_id' => ['required', 'integer', 'min:1'],
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return $this->respondValidationError($validator->errors()->toArray());
|
||||
}
|
||||
|
||||
$model = $this->portal->storeHandCopy($validator->validated(), $uid);
|
||||
|
||||
return $this->respondCreated(
|
||||
['print_request' => $this->portal->normalizePrintRequestRow($model->toArray())],
|
||||
'Copy request submitted. Please hand the original document to the copy center.'
|
||||
);
|
||||
}
|
||||
|
||||
public function download(int $id): BinaryFileResponse|JsonResponse
|
||||
{
|
||||
$uid = $this->getCurrentUserId();
|
||||
if (! $uid) {
|
||||
return $this->error('Unauthorized.', Response::HTTP_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
$pr = PrintRequest::query()->find($id);
|
||||
if (! $pr) {
|
||||
return $this->error('Print request not found.', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
$isAdmin = $this->userHasPrintAdminRole(Auth::user());
|
||||
if (! $this->portal->authorizeDownload($pr, $uid, $isAdmin)) {
|
||||
return $this->error('Forbidden.', Response::HTTP_FORBIDDEN);
|
||||
}
|
||||
|
||||
$path = $this->portal->absolutePathForDownload($pr);
|
||||
if ($path === null || ! is_readable($path)) {
|
||||
return $this->error('File not found.', Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
$mime = @mime_content_type($path) ?: 'application/octet-stream';
|
||||
$safe = basename($path);
|
||||
|
||||
return response()->download($path, $safe, [
|
||||
'Content-Type' => $mime,
|
||||
]);
|
||||
}
|
||||
|
||||
private function userHasPrintAdminRole(?User $user): bool
|
||||
{
|
||||
if (! $user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$roles = $user->roles()
|
||||
->pluck('roles.name')
|
||||
->map(fn ($name) => strtolower((string) $name))
|
||||
->toArray();
|
||||
|
||||
foreach (['administrator', 'admin', 'principal', 'vice_principal', 'vice-principal'] as $allowed) {
|
||||
if (in_array($allowed, $roles, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user