fix exam and grading

This commit is contained in:
root
2026-06-04 13:25:31 -04:00
parent b4e6ac03c5
commit feb6be0610
22 changed files with 1288 additions and 120 deletions
@@ -4,6 +4,10 @@ namespace App\Http\Controllers\Api\Grading;
use App\Http\Controllers\Api\Core\BaseApiController;
use App\Http\Requests\Grading\BelowSixtyEmailRequest;
use App\Http\Requests\Grading\BelowSixtyDecisionDetailsRequest;
use App\Http\Requests\Grading\BelowSixtyDecisionListRequest;
use App\Http\Requests\Grading\BelowSixtyDecisionSaveRequest;
use App\Http\Requests\Grading\BelowSixtyDecisionSendRequest;
use App\Http\Requests\Grading\BelowSixtyMeetingRequest;
use App\Http\Requests\Grading\BelowSixtyMeetingSaveRequest;
use App\Http\Requests\Grading\BelowSixtySendRequest;
@@ -312,6 +316,73 @@ class GradingController extends BaseApiController
return response()->json(['ok' => true] + $data);
}
public function belowSixtyDecisions(BelowSixtyDecisionListRequest $request): JsonResponse
{
$payload = $request->validated();
$rows = $this->belowSixtyService->listDecisionRows((string) $payload['school_year']);
return response()->json([
'ok' => true,
'rows' => $rows,
'school_year' => $payload['school_year'],
'semester' => 'year',
]);
}
public function saveBelowSixtyDecision(BelowSixtyDecisionSaveRequest $request): JsonResponse
{
$userId = $this->authenticatedUserIdOrUnauthorized();
if ($userId instanceof JsonResponse) {
return $userId;
}
$payload = $request->validated();
$result = $this->belowSixtyService->saveDecision(
(int) $payload['student_id'],
(string) $payload['school_year'],
(string) ($payload['decision'] ?? ''),
(string) ($payload['notes'] ?? ''),
$userId
);
return response()->json(['ok' => true, 'decision' => $result]);
}
public function belowSixtyDecisionDetails(BelowSixtyDecisionDetailsRequest $request): JsonResponse
{
$payload = $request->validated();
$data = $this->belowSixtyService->studentDecisionDetails(
(int) $payload['student_id'],
(string) $payload['school_year']
);
return response()->json(['ok' => true] + $data);
}
public function belowSixtyDecisionEmail(BelowSixtyDecisionDetailsRequest $request): JsonResponse
{
$payload = $request->validated();
$data = $this->belowSixtyService->decisionEmailContext(
(int) $payload['student_id'],
(string) $payload['school_year']
);
return response()->json(['ok' => true] + $data);
}
public function sendBelowSixtyDecisionEmail(BelowSixtyDecisionSendRequest $request): JsonResponse
{
$payload = $request->validated();
$this->belowSixtyService->sendDecisionEmail(
(int) $payload['student_id'],
(string) $payload['school_year'],
isset($payload['subject']) ? (string) $payload['subject'] : null,
isset($payload['html']) ? (string) $payload['html'] : null
);
return response()->json(['ok' => true]);
}
public function saveBelowSixtyMeeting(BelowSixtyMeetingSaveRequest $request): JsonResponse
{
$userId = $this->authenticatedUserIdOrUnauthorized();
@@ -0,0 +1,21 @@
<?php
namespace App\Http\Requests\Grading;
use App\Http\Requests\ApiFormRequest;
class BelowSixtyDecisionDetailsRequest extends ApiFormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'student_id' => ['required', 'integer', 'min:1'],
'school_year' => ['required', 'string', 'max:50'],
];
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Requests\Grading;
use App\Http\Requests\ApiFormRequest;
class BelowSixtyDecisionListRequest extends ApiFormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'school_year' => ['required', 'string', 'max:50'],
];
}
}
@@ -0,0 +1,37 @@
<?php
namespace App\Http\Requests\Grading;
use App\Http\Requests\ApiFormRequest;
use Illuminate\Validation\Rule;
class BelowSixtyDecisionSaveRequest extends ApiFormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'student_id' => ['required', 'integer', 'min:1'],
'school_year' => ['required', 'string', 'max:50'],
'semester' => ['nullable', 'string', 'max:20'],
'decision' => [
'nullable',
'string',
'max:100',
Rule::in([
'Pass',
'Repeat Class',
'Make-up exam in fall',
'Deferred decision',
'Expel',
'Withdrawn',
]),
],
'notes' => ['nullable', 'string'],
];
}
}
@@ -0,0 +1,23 @@
<?php
namespace App\Http\Requests\Grading;
use App\Http\Requests\ApiFormRequest;
class BelowSixtyDecisionSendRequest extends ApiFormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'student_id' => ['required', 'integer', 'min:1'],
'school_year' => ['required', 'string', 'max:50'],
'subject' => ['nullable', 'string', 'max:255'],
'html' => ['nullable', 'string'],
];
}
}
@@ -10,19 +10,19 @@ class ExamDraftResource extends JsonResource
{
return [
'id' => (int) ($this['id'] ?? 0),
'teacher_id' => (int) ($this['teacher_id'] ?? 0),
'teacher_id' => (int) (($this['teacher_id'] ?? $this['author_id'] ?? 0) ?: 0),
'class_section_id' => (int) ($this['class_section_id'] ?? 0),
'class_section_name' => $this['class_section_name'] ?? null,
'semester' => $this['semester'] ?? null,
'school_year' => $this['school_year'] ?? null,
'exam_type' => $this['exam_type'] ?? null,
'draft_title' => $this['draft_title'] ?? null,
'description' => $this['description'] ?? null,
'teacher_file' => $this['teacher_file'] ?? null,
'teacher_filename' => $this['teacher_filename'] ?? null,
'description' => $this['description'] ?? ($this['author_comment'] ?? null),
'teacher_file' => $this['teacher_file'] ?? ($this['author_file'] ?? null),
'teacher_filename' => $this['teacher_filename'] ?? ($this['author_filename'] ?? null),
'status' => $this['status'] ?? null,
'admin_id' => $this['admin_id'] ?? null,
'admin_comments' => $this['admin_comments'] ?? null,
'admin_id' => $this['admin_id'] ?? ($this['reviewer_id'] ?? null),
'admin_comments' => $this['admin_comments'] ?? ($this['reviewer_comments'] ?? null),
'reviewed_at' => $this['reviewed_at'] ?? null,
'final_file' => $this['final_file'] ?? null,
'final_filename' => $this['final_filename'] ?? null,