RegistrationStatus::class, 'semester_number' => 'integer', 'signed_at' => 'datetime', 'reviewed_at' => 'datetime', ]; } public function registerMediaCollections(): void { $this->addMediaCollection('signature')->singleFile(); $this->addMediaCollection('kaprodi_signature')->singleFile(); $this->addMediaCollection('advisor_signature')->singleFile(); } public function student(): BelongsTo { return $this->belongsTo(Student::class); } public function academicTerm(): BelongsTo { return $this->belongsTo(AcademicTerm::class); } public function reviewer(): BelongsTo { return $this->belongsTo(User::class, 'reviewed_by'); } public function courseRegistrations(): HasMany { return $this->hasMany(CourseRegistration::class, 'submission_id'); } public function logs(): HasMany { return $this->hasMany(CourseRegistrationSubmissionLog::class, 'submission_id'); } protected function signatureUrl(): Attribute { return Attribute::make( get: fn () => $this->getFirstMediaUrl('signature') ?: null, ); } protected function kaprodiSignatureUrl(): Attribute { return Attribute::make( get: fn () => $this->getFirstMediaUrl('kaprodi_signature') ?: null, ); } protected function advisorSignatureUrl(): Attribute { return Attribute::make( get: fn () => $this->getFirstMediaUrl('advisor_signature') ?: null, ); } public static function semesterKey(?int $semesterNumber): string { return $semesterNumber === null ? 'lainnya' : (string) $semesterNumber; } public static function parseSemesterKey(string $semester): ?int { return $semester === 'lainnya' ? null : (int) $semester; } }