add class progress and fix endpoints
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\ClassProgress;
|
||||
|
||||
use App\Http\Controllers\Api\BaseApiController;
|
||||
use App\Http\Requests\ClassProgress\ClassProgressIndexRequest;
|
||||
use App\Http\Requests\ClassProgress\ClassProgressMetaRequest;
|
||||
use App\Http\Requests\ClassProgress\ClassProgressStoreRequest;
|
||||
use App\Http\Requests\ClassProgress\ClassProgressUpdateRequest;
|
||||
use App\Http\Resources\ClassProgress\ClassProgressGroupCollection;
|
||||
use App\Http\Resources\ClassProgress\ClassProgressReportResource;
|
||||
use App\Http\Resources\ClassProgress\ClassProgressShowResource;
|
||||
use App\Models\ClassProgressAttachment;
|
||||
use App\Models\ClassProgressReport;
|
||||
use App\Services\ClassProgress\ClassProgressAttachmentService;
|
||||
use App\Services\ClassProgress\ClassProgressMetaService;
|
||||
use App\Services\ClassProgress\ClassProgressMutationService;
|
||||
use App\Services\ClassProgress\ClassProgressQueryService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
|
||||
class ClassProgressController extends BaseApiController
|
||||
{
|
||||
public function __construct(
|
||||
private ClassProgressQueryService $queryService,
|
||||
private ClassProgressMutationService $mutationService,
|
||||
private ClassProgressMetaService $metaService,
|
||||
private ClassProgressAttachmentService $attachmentService
|
||||
) {
|
||||
parent::__construct();
|
||||
$this->authorizeResource(ClassProgressReport::class, 'class_progress');
|
||||
}
|
||||
|
||||
public function meta(ClassProgressMetaRequest $request): JsonResponse
|
||||
{
|
||||
$classId = $request->validated('class_id');
|
||||
$sundayCount = (int) ($request->validated('sunday_count') ?? 12);
|
||||
|
||||
$payload = [
|
||||
'subject_sections' => $this->metaService->subjectSections(),
|
||||
'status_options' => $this->metaService->statusOptions(),
|
||||
'sunday_options' => $this->metaService->sundayOptions($sundayCount),
|
||||
'curriculum' => $this->metaService->curriculumOptions($classId ? (int) $classId : null),
|
||||
];
|
||||
|
||||
return $this->respondSuccess($payload, 'Progress metadata loaded.');
|
||||
}
|
||||
|
||||
public function index(ClassProgressIndexRequest $request): JsonResponse
|
||||
{
|
||||
$filters = $request->validated();
|
||||
$paginator = $this->queryService->listReports($request->user(), $filters);
|
||||
|
||||
if (!empty($filters['group_by_week'])) {
|
||||
$grouped = ClassProgressGroupCollection::fromPaginator($paginator);
|
||||
return $this->respondSuccess($grouped, 'Progress reports retrieved.');
|
||||
}
|
||||
|
||||
return $this->respondSuccess([
|
||||
'items' => ClassProgressReportResource::collection($paginator->items()),
|
||||
'pagination' => [
|
||||
'current_page' => $paginator->currentPage(),
|
||||
'per_page' => $paginator->perPage(),
|
||||
'total' => $paginator->total(),
|
||||
'last_page' => $paginator->lastPage(),
|
||||
],
|
||||
], 'Progress reports retrieved.');
|
||||
}
|
||||
|
||||
public function store(ClassProgressStoreRequest $request): JsonResponse
|
||||
{
|
||||
try {
|
||||
$filesBySubject = $request->filesBySubject();
|
||||
$reports = $this->mutationService->createReports($request->user(), $request->validated(), $filesBySubject);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return $this->respondError($e->getMessage(), 422);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Failed to create class progress reports.', [
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
return $this->respondError('Unable to save progress reports.', 500);
|
||||
}
|
||||
|
||||
return $this->respondCreated(ClassProgressReportResource::collection($reports), 'Progress reports saved.');
|
||||
}
|
||||
|
||||
public function show(ClassProgressReport $class_progress): JsonResponse
|
||||
{
|
||||
$weeklyReports = $this->queryService->weeklyReports($this->laravelRequest->user(), $class_progress);
|
||||
|
||||
return $this->respondSuccess(
|
||||
new ClassProgressShowResource([
|
||||
'report' => $class_progress,
|
||||
'weekly_reports' => $weeklyReports,
|
||||
'status_options' => $this->metaService->statusOptions(),
|
||||
]),
|
||||
'Progress report retrieved.'
|
||||
);
|
||||
}
|
||||
|
||||
public function update(ClassProgressUpdateRequest $request, ClassProgressReport $class_progress): JsonResponse
|
||||
{
|
||||
try {
|
||||
$updated = $this->mutationService->updateReport($class_progress, $request->validated(), $request->attachments());
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return $this->respondError($e->getMessage(), 422);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Failed to update class progress report.', [
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
return $this->respondError('Unable to update progress report.', 500);
|
||||
}
|
||||
|
||||
return $this->respondSuccess(new ClassProgressReportResource($updated), 'Progress report updated.');
|
||||
}
|
||||
|
||||
public function destroy(ClassProgressReport $class_progress): JsonResponse
|
||||
{
|
||||
try {
|
||||
$this->mutationService->deleteReport($class_progress);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('Failed to delete class progress report.', [
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
return $this->respondError('Unable to delete progress report.', 500);
|
||||
}
|
||||
|
||||
return $this->respondDeleted(null, 'Progress report deleted.');
|
||||
}
|
||||
|
||||
public function downloadAttachment(int $attachment): BinaryFileResponse|JsonResponse
|
||||
{
|
||||
$record = ClassProgressAttachment::query()->find($attachment);
|
||||
if (!$record || !$record->file_path) {
|
||||
return $this->respondError('Attachment not found.', 404);
|
||||
}
|
||||
|
||||
if ($record->report) {
|
||||
$this->authorize('view', $record->report);
|
||||
}
|
||||
|
||||
$path = $this->attachmentService->resolvePath($record->file_path);
|
||||
if (!$path) {
|
||||
return $this->respondError('Attachment missing.', 404);
|
||||
}
|
||||
|
||||
$downloadName = $record->original_name ?: basename($path);
|
||||
return response()->download($path, $downloadName);
|
||||
}
|
||||
|
||||
public function downloadLegacyAttachment(ClassProgressReport $class_progress): BinaryFileResponse|JsonResponse
|
||||
{
|
||||
$this->authorize('view', $class_progress);
|
||||
|
||||
if (!$class_progress->attachment_path) {
|
||||
return $this->respondError('Attachment not found.', 404);
|
||||
}
|
||||
|
||||
$path = $this->attachmentService->resolvePath($class_progress->attachment_path);
|
||||
if (!$path) {
|
||||
return $this->respondError('Attachment missing.', 404);
|
||||
}
|
||||
|
||||
return response()->download($path, basename($path));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user