fix parent pages and teachers and admin
API CI/CD / Validate (composer + pint) (push) Successful in 3m8s
API CI/CD / Build frontend assets (push) Successful in 1m2s
API CI/CD / Test (PHPUnit) (push) Failing after 6m5s
API CI/CD / Security audit (push) Failing after 52s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
API CI/CD / Validate (composer + pint) (push) Successful in 3m8s
API CI/CD / Build frontend assets (push) Successful in 1m2s
API CI/CD / Test (PHPUnit) (push) Failing after 6m5s
API CI/CD / Security audit (push) Failing after 52s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
This commit is contained in:
@@ -97,13 +97,22 @@ class ClassProgressController extends BaseApiController
|
||||
return $auth;
|
||||
}
|
||||
|
||||
if ($this->isLegacyTeacherProgressListRoute($request) && ! $this->hasAnyRole($auth, ['teacher', 'administrator', 'admin'])) {
|
||||
if ($this->isLegacyTeacherProgressListRoute($request) && ! $this->hasAnyRole($auth, ['teacher', 'teacher_assistant', 'ta', 'administrator', 'admin'])) {
|
||||
return $this->respondError('Forbidden.', Response::HTTP_FORBIDDEN);
|
||||
}
|
||||
|
||||
$filters = $request->validated();
|
||||
$meta = $this->queryService->meta($filters['school_year'] ?? null, $filters['semester'] ?? null);
|
||||
$filters['school_year'] = $filters['school_year'] ?? ($meta['school_year'] ?? null);
|
||||
if ($this->isLegacyTeacherProgressListRoute($request) && empty($filters['class_section_id'])) {
|
||||
$resolvedClassSectionId = $this->resolveTeacherHistoryClassSectionId($auth, $filters);
|
||||
if ($resolvedClassSectionId instanceof JsonResponse) {
|
||||
return $resolvedClassSectionId;
|
||||
}
|
||||
if ($resolvedClassSectionId > 0) {
|
||||
$filters['class_section_id'] = $resolvedClassSectionId;
|
||||
}
|
||||
}
|
||||
if ($this->isAdminProgressAliasRoute($request)) {
|
||||
$filters['group_by_week'] = true;
|
||||
}
|
||||
@@ -136,7 +145,12 @@ class ClassProgressController extends BaseApiController
|
||||
|
||||
try {
|
||||
$filesBySubject = $request->filesBySubject();
|
||||
$reports = $this->mutationService->createReports($auth, $request->validated(), $filesBySubject);
|
||||
$payload = $this->resolveTeacherStorePayload($auth, $request->validated());
|
||||
if ($payload instanceof JsonResponse) {
|
||||
return $payload;
|
||||
}
|
||||
|
||||
$reports = $this->mutationService->createReports($auth, $payload, $filesBySubject);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
if ($e->getMessage() === 'CONFIRM_OVERWRITE') {
|
||||
return response()->json([
|
||||
@@ -278,6 +292,100 @@ class ClassProgressController extends BaseApiController
|
||||
|| $request->is('api/v1/admin/progress');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $payload
|
||||
* @return array<string, mixed>|JsonResponse
|
||||
*/
|
||||
private function resolveTeacherStorePayload(User $user, array $payload): array|JsonResponse
|
||||
{
|
||||
if ($this->hasAnyRole($user, ['administrator', 'admin', 'principal', 'vice_principal', 'vice-principal'])) {
|
||||
return $payload;
|
||||
}
|
||||
|
||||
if (! $this->hasAnyRole($user, ['teacher', 'teacher_assistant', 'ta'])) {
|
||||
return $payload;
|
||||
}
|
||||
|
||||
$assignments = $this->queryService->teacherAssignments(
|
||||
$user,
|
||||
$payload['school_year'] ?? null,
|
||||
$payload['semester'] ?? null
|
||||
);
|
||||
|
||||
if ($assignments === []) {
|
||||
return $this->respondError('No class section assigned to this teacher.', Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
$postedSectionId = (int) ($payload['class_section_id'] ?? 0);
|
||||
$assignment = null;
|
||||
if ($postedSectionId > 0) {
|
||||
$assignment = collect($assignments)->first(function (array $assignment) use ($postedSectionId) {
|
||||
return (int) ($assignment['class_section_id'] ?? 0) === $postedSectionId
|
||||
|| (int) ($assignment['class_section_pk'] ?? 0) === $postedSectionId;
|
||||
});
|
||||
}
|
||||
|
||||
if (! $assignment) {
|
||||
$sessionClassSectionId = (int) session('class_section_id', 0);
|
||||
if ($sessionClassSectionId > 0) {
|
||||
$assignment = collect($assignments)->first(function (array $assignment) use ($sessionClassSectionId) {
|
||||
return (int) ($assignment['class_section_id'] ?? 0) === $sessionClassSectionId
|
||||
|| (int) ($assignment['class_section_pk'] ?? 0) === $sessionClassSectionId;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$assignment ??= $assignments[0];
|
||||
$payload['class_section_id'] = (int) ($assignment['class_section_id'] ?? 0);
|
||||
|
||||
if (empty($payload['school_year']) && ! empty($assignment['school_year'])) {
|
||||
$payload['school_year'] = $assignment['school_year'];
|
||||
}
|
||||
if (empty($payload['semester']) && ! empty($assignment['semester'])) {
|
||||
$payload['semester'] = $assignment['semester'];
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $filters
|
||||
*/
|
||||
private function resolveTeacherHistoryClassSectionId(User $user, array $filters): int|JsonResponse
|
||||
{
|
||||
if ($this->hasAnyRole($user, ['administrator', 'admin', 'principal', 'vice_principal', 'vice-principal'])) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$assignments = $this->queryService->teacherAssignments(
|
||||
$user,
|
||||
$filters['school_year'] ?? null,
|
||||
$filters['semester'] ?? null
|
||||
);
|
||||
$assignedSectionIds = collect($assignments)
|
||||
->pluck('class_section_id')
|
||||
->map(fn ($id) => (int) $id)
|
||||
->filter(fn ($id) => $id > 0)
|
||||
->unique()
|
||||
->values()
|
||||
->all();
|
||||
|
||||
if ($assignedSectionIds === []) {
|
||||
return $this->respondError('No class section assigned to this teacher.', Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
if (count($assignedSectionIds) === 1) {
|
||||
return (int) $assignedSectionIds[0];
|
||||
}
|
||||
|
||||
$sessionClassSectionId = (int) session('class_section_id', 0);
|
||||
if ($sessionClassSectionId > 0 && in_array($sessionClassSectionId, $assignedSectionIds, true)) {
|
||||
return $sessionClassSectionId;
|
||||
}
|
||||
|
||||
return (int) $assignedSectionIds[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<string> $roles
|
||||
*/
|
||||
|
||||
@@ -80,6 +80,21 @@ class ParentController extends BaseApiController
|
||||
]);
|
||||
}
|
||||
|
||||
public function statement(ParentInvoiceRequest $request): JsonResponse
|
||||
{
|
||||
$guard = $this->parentIdOrUnauthorized();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$schoolYear = $request->validated()['school_year'] ?? null;
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'data' => $this->invoiceService->statement($guard, $schoolYear),
|
||||
]);
|
||||
}
|
||||
|
||||
public function enrollments(ParentEnrollmentRequest $request): JsonResponse
|
||||
{
|
||||
$guard = $this->parentIdOrUnauthorized();
|
||||
|
||||
@@ -9,6 +9,8 @@ use App\Services\Files\ExamDraftDownloadNameService;
|
||||
use App\Services\Files\FileServeService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class FilesController extends BaseApiController
|
||||
{
|
||||
@@ -71,6 +73,7 @@ class FilesController extends BaseApiController
|
||||
|
||||
public function examDraftFinal(FileNameRequest $request, string $name): Response|JsonResponse
|
||||
{
|
||||
$name = $this->resolveFinalExamFileName($name);
|
||||
$downloadName = $this->draftNameService->build($name, 'finals');
|
||||
|
||||
return $this->serveFile(
|
||||
@@ -102,4 +105,37 @@ class FilesController extends BaseApiController
|
||||
|
||||
return $this->fileService->serveInline($baseDir, $name, $allowedExtensions, $request, $downloadName, $nosniff);
|
||||
}
|
||||
|
||||
private function resolveFinalExamFileName(string $name): string
|
||||
{
|
||||
if (! ctype_digit($name) || ! Schema::hasTable('exam_drafts')) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
$query = DB::table('exam_drafts')->where('id', (int) $name);
|
||||
if (Schema::hasColumn('exam_drafts', 'final_pdf_file')) {
|
||||
$query->select('final_file', 'final_pdf_file');
|
||||
} else {
|
||||
$query->select('final_file');
|
||||
}
|
||||
|
||||
$row = $query->first();
|
||||
if (! $row) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
$pdfFile = trim((string) ($row->final_pdf_file ?? ''));
|
||||
if ($this->looksLikeExamFileName($pdfFile)) {
|
||||
return $pdfFile;
|
||||
}
|
||||
|
||||
$finalFile = trim((string) ($row->final_file ?? ''));
|
||||
|
||||
return $this->looksLikeExamFileName($finalFile) ? $finalFile : $name;
|
||||
}
|
||||
|
||||
private function looksLikeExamFileName(string $name): bool
|
||||
{
|
||||
return preg_match('/\.(doc|docx|pdf)\z/i', $name) === 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@ class TeacherController extends BaseApiController
|
||||
$studentsBySection[(string) $sectionId] = TeacherStudentResource::collection($students);
|
||||
}
|
||||
|
||||
$this->storeActiveClassInSession($data);
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'teacher' => $teacher,
|
||||
@@ -91,6 +93,8 @@ class TeacherController extends BaseApiController
|
||||
], 422);
|
||||
}
|
||||
|
||||
$this->storeActiveClassInSession($data);
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'active_class_section_id' => $requested,
|
||||
@@ -162,4 +166,18 @@ class TeacherController extends BaseApiController
|
||||
|
||||
return $userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
private function storeActiveClassInSession(array $data): void
|
||||
{
|
||||
$classSectionId = (int) ($data['active_class_section_id'] ?? 0);
|
||||
if ($classSectionId <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
session()->put('class_section_id', $classSectionId);
|
||||
session()->put('class_section_name', $data['class_section_name'] ?? null);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user