Compare commits
10 Commits
34733ed65e
...
c8bb62e9f2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8bb62e9f2 | ||
| b98c57d565 | |||
|
|
f057b0c283 | ||
| 15bab26439 | |||
|
|
38d381b388 | ||
| babc8b2bd3 | |||
|
|
f6efb0d61e | ||
| 6b0e5bb040 | |||
|
|
d65bf05e47 | ||
| 017a49350c |
81
app/Filament/Imports/StudentImporter.php
Normal file
81
app/Filament/Imports/StudentImporter.php
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Imports;
|
||||||
|
|
||||||
|
use App\Models\Student;
|
||||||
|
use App\Models\User;
|
||||||
|
use Filament\Actions\Imports\ImportColumn;
|
||||||
|
use Filament\Actions\Imports\Importer;
|
||||||
|
use Filament\Actions\Imports\Models\Import;
|
||||||
|
use Filament\Actions\Imports\Exceptions\RowImportFailedException;
|
||||||
|
|
||||||
|
class StudentImporter extends Importer
|
||||||
|
{
|
||||||
|
protected static ?string $model = Student::class;
|
||||||
|
|
||||||
|
public static function getColumns(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
ImportColumn::make('full_name')
|
||||||
|
->requiredMapping()
|
||||||
|
->rules(['required', 'max:255']),
|
||||||
|
ImportColumn::make('nis')
|
||||||
|
->rules(['required','max:255']),
|
||||||
|
ImportColumn::make('nisn')
|
||||||
|
->rules(['required','max:255']),
|
||||||
|
ImportColumn::make('gender')
|
||||||
|
->requiredMapping()
|
||||||
|
->rules(['required', 'max:255']),
|
||||||
|
ImportColumn::make('birth_date')
|
||||||
|
->rules(['date']),
|
||||||
|
ImportColumn::make('birth_place')
|
||||||
|
->rules(['max:255']),
|
||||||
|
ImportColumn::make('address'),
|
||||||
|
ImportColumn::make('religion'),
|
||||||
|
ImportColumn::make('phone')
|
||||||
|
->rules(['required','max:255']),
|
||||||
|
ImportColumn::make('email')
|
||||||
|
->rules(['email', 'max:255']),
|
||||||
|
ImportColumn::make('parent_name')
|
||||||
|
->rules(['required','max:255']),
|
||||||
|
ImportColumn::make('parent_phone')
|
||||||
|
->rules(['required','max:255']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resolveRecord(): ?Student
|
||||||
|
{
|
||||||
|
// Cek duplikat NIS
|
||||||
|
if (Student::where('nis', $this->data['nis'])->exists()) {
|
||||||
|
throw new RowImportFailedException('NIS sudah terdaftar');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cek duplikat NISN
|
||||||
|
if (Student::where('nisn', $this->data['nisn'])->exists()) {
|
||||||
|
throw new RowImportFailedException('NISN sudah terdaftar');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cek duplikat phone
|
||||||
|
if (Student::where('phone', $this->data['phone'])->exists()) {
|
||||||
|
throw new RowImportFailedException('Nomor telepon sudah terdaftar');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cek duplikat email di tabel users
|
||||||
|
if (User::where('email', $this->data['email'])->exists()) {
|
||||||
|
throw new RowImportFailedException('Email sudah digunakan');
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Student();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getCompletedNotificationBody(Import $import): string
|
||||||
|
{
|
||||||
|
$body = 'Your student import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.';
|
||||||
|
|
||||||
|
if ($failedRowsCount = $import->getFailedRowsCount()) {
|
||||||
|
$body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to import.';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $body;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,14 +3,22 @@
|
|||||||
namespace App\Filament\Pages;
|
namespace App\Filament\Pages;
|
||||||
|
|
||||||
use App\Models\AcademicYear;
|
use App\Models\AcademicYear;
|
||||||
|
use App\Models\Assessment;
|
||||||
use App\Models\ClassRoom;
|
use App\Models\ClassRoom;
|
||||||
use App\Models\ClassSubject;
|
use App\Models\ClassSubject;
|
||||||
|
use App\Models\CompetencyAchievement;
|
||||||
|
use App\Models\ExtracurricularAssessment;
|
||||||
|
use App\Models\HomeRoomTeacher;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Models\SchoolInformation;
|
use App\Models\SchoolInformation;
|
||||||
|
use App\Models\Subject;
|
||||||
|
use App\Models\TeacherSubject;
|
||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
use Filament\Pages\Page;
|
use Filament\Pages\Page;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use function PHPUnit\Framework\isEmpty;
|
use function PHPUnit\Framework\isEmpty;
|
||||||
|
use function Symfony\Component\String\s;
|
||||||
|
use Barryvdh\DomPDF\Facade\Pdf;
|
||||||
|
|
||||||
Carbon::setLocale('id');
|
Carbon::setLocale('id');
|
||||||
|
|
||||||
@ -30,12 +38,33 @@ class ReportPreview extends Page
|
|||||||
|
|
||||||
public $table = [];
|
public $table = [];
|
||||||
|
|
||||||
|
public $sakit = 0;
|
||||||
|
public $izin = 0;
|
||||||
|
public $tanpa_keterangan = 0;
|
||||||
|
|
||||||
|
public $home_room_teacher;
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
$this->loadData();
|
$this->loadData();
|
||||||
$this->loadAssessment();
|
$this->loadAssessment();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function saveAttendance()
|
||||||
|
{
|
||||||
|
$this->validate([
|
||||||
|
'sakit' => 'required|integer|min:0',
|
||||||
|
'izin' => 'required|integer|min:0',
|
||||||
|
'tanpa_keterangan' => 'required|integer|min:0',
|
||||||
|
]);
|
||||||
|
|
||||||
|
Notification::make()
|
||||||
|
->title('Data Kehadiran Disimpan')
|
||||||
|
->success()
|
||||||
|
->send();
|
||||||
|
}
|
||||||
|
|
||||||
protected function loadData() : void
|
protected function loadData() : void
|
||||||
{
|
{
|
||||||
$this->student = Student::find(request()->query('studentId'));
|
$this->student = Student::find(request()->query('studentId'));
|
||||||
@ -68,29 +97,81 @@ class ReportPreview extends Page
|
|||||||
$semester = request()->query('semester');
|
$semester = request()->query('semester');
|
||||||
$year_id = request()->query('yearId');
|
$year_id = request()->query('yearId');
|
||||||
|
|
||||||
// Class Student Mapping
|
// Assessment Mapping
|
||||||
$classSubjects = ClassSubject::with(['subject', 'class', 'academicYear'])
|
$assessments = Assessment::where('semester', $this->semester)
|
||||||
->where('class_room_id', $class_id)
|
->whereHas('teacherSubject', function($query) use ($class_id, $year_id) {
|
||||||
->where('academic_year_id', $year_id)
|
$query->where('academic_year_id', $year_id)
|
||||||
|
->where('class_id', $class_id);
|
||||||
|
})
|
||||||
|
->where('student_id', $this->student->id)
|
||||||
|
->with('teacherSubject.subject', 'student')
|
||||||
->get()
|
->get()
|
||||||
->sortByDesc(function ($item) {
|
->map(function ($as) use ($class_id) {
|
||||||
return $item->subject->name;
|
$subject = $as->teacherSubject->subject ?? null;
|
||||||
|
|
||||||
|
if (!$subject) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$competencyAchievements = CompetencyAchievement::where('class_room_id', $class_id)
|
||||||
|
->where('subject_id', $subject->id)
|
||||||
|
->where('min_score', '<=', $as->score)
|
||||||
|
->where('max_score', '>=', $as->score)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
return [
|
||||||
|
"score" => $as->score,
|
||||||
|
"subject" => $subject->name,
|
||||||
|
"category" => $subject->category,
|
||||||
|
"competency_achievement" => $competencyAchievements ? $this->student->full_name . '' . $competencyAchievements->description : '-',
|
||||||
|
];
|
||||||
|
})
|
||||||
|
->filter() // Hapus null jika ada
|
||||||
|
->sortByDesc('subject')
|
||||||
|
->sortBy(function ($item) {
|
||||||
|
return $item['category'] === 'umum' ? 0 : 1;
|
||||||
|
})
|
||||||
|
->values()
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$this->table["assessments"]['umum'] = array_filter($assessments, function ($item) {
|
||||||
|
return $item["category"] === "umum";
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->table["assessments"]['muatan lokal'] = array_filter($assessments, function ($item) {
|
||||||
|
return $item["category"] === "muatan lokal";
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->table["assessments"]['seni'] = array_filter($assessments, function ($item) {
|
||||||
|
return $item["category"] === "seni";
|
||||||
|
});
|
||||||
|
|
||||||
|
$extracurricular = ExtracurricularAssessment::with('classStudent','extracurricular')
|
||||||
|
->where('semester', $this->semester)
|
||||||
|
->whereHas('classStudent', function($query) use ($class_id, $year_id) {
|
||||||
|
$query->where('academic_year_id', $year_id)
|
||||||
|
->where('class_room_id', $class_id)
|
||||||
|
->where('student_id', $this->student->id);
|
||||||
|
})
|
||||||
|
->get()
|
||||||
|
->map(function ($as) {
|
||||||
|
return [
|
||||||
|
"name" => $as->extracurricular->name,
|
||||||
|
"predicate" => $as->predicate,
|
||||||
|
"description" => $as->description,
|
||||||
|
];
|
||||||
})
|
})
|
||||||
->toArray();
|
->toArray();
|
||||||
|
|
||||||
|
$this->table["extracurricular"] = $extracurricular;
|
||||||
|
|
||||||
$subjects = [];
|
$homeRoom = HomeRoomTeacher::with(['teacher'])
|
||||||
|
->where('class_room_id', $this->class->id)
|
||||||
|
->where('academic_year_id', $this->academic_year->id)
|
||||||
|
->firstOrFail()
|
||||||
|
->toArray();
|
||||||
|
|
||||||
foreach ($classSubjects as $classSubject) {
|
$this->home_room_teacher = $homeRoom ?? [];
|
||||||
$category = strtolower($classSubject['subject']['category']);
|
|
||||||
$subjectName = $classSubject['subject']['name'];
|
|
||||||
$subjectId = $classSubject['subject']['id'];
|
|
||||||
$subjects[$category][$subjectId] = $subjectName;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->table["subjects"] = $subjects;
|
|
||||||
|
|
||||||
// dd($subjects);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function extractClassLetter($className)
|
public function extractClassLetter($className)
|
||||||
|
|||||||
@ -22,6 +22,16 @@ class SchoolInformation extends Page implements HasForms
|
|||||||
protected static ?string $navigationGroup = 'Settings';
|
protected static ?string $navigationGroup = 'Settings';
|
||||||
protected static ?int $navigationSort = 999; // Biar muncul paling bawah
|
protected static ?int $navigationSort = 999; // Biar muncul paling bawah
|
||||||
|
|
||||||
|
public static function canAccess(): bool
|
||||||
|
{
|
||||||
|
return auth()->user()?->can('page_SchoolInformation');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function shouldRegisterNavigation(): bool
|
||||||
|
{
|
||||||
|
return auth()->user()?->can('page_SchoolInformation');
|
||||||
|
}
|
||||||
|
|
||||||
public ?array $data = [];
|
public ?array $data = [];
|
||||||
|
|
||||||
public ?SchoolInformationModel $record = null;
|
public ?SchoolInformationModel $record = null;
|
||||||
|
|||||||
@ -7,6 +7,7 @@ use App\Models\Assessment;
|
|||||||
use App\Models\ClassRoom;
|
use App\Models\ClassRoom;
|
||||||
use App\Models\ClassStudent;
|
use App\Models\ClassStudent;
|
||||||
use App\Models\ClassSubject;
|
use App\Models\ClassSubject;
|
||||||
|
use App\Models\HomeRoomTeacher;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Models\Subject;
|
use App\Models\Subject;
|
||||||
use App\Models\TeacherSubject;
|
use App\Models\TeacherSubject;
|
||||||
@ -32,12 +33,30 @@ class StudentReport extends Page
|
|||||||
|
|
||||||
public static function canAccess(): bool
|
public static function canAccess(): bool
|
||||||
{
|
{
|
||||||
return auth()->user()->hasAnyRole(['super_admin']);
|
$user = auth()->user();
|
||||||
|
|
||||||
|
if ($user->hasRole('parent')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$isHomeRoomTeacher = HomeRoomTeacher::where('teacher_id', $user->id)->exists();
|
||||||
|
|
||||||
|
return $user->can('page_SchoolInformation') || $isHomeRoomTeacher;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function shouldRegisterNavigation(): bool
|
public static function shouldRegisterNavigation(): bool
|
||||||
{
|
{
|
||||||
return auth()->user()->hasAnyRole(['super_admin']);
|
$user = auth()->user();
|
||||||
|
|
||||||
|
if ($user->hasRole('parent')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Untuk teacher (wali kelas)
|
||||||
|
$isHomeRoomTeacher = HomeRoomTeacher::where('teacher_id', $user->id)->exists();
|
||||||
|
|
||||||
|
// Atau punya permission khusus
|
||||||
|
return $user->can('page_SchoolInformation') || $isHomeRoomTeacher;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function mount(): void
|
public function mount(): void
|
||||||
@ -54,9 +73,33 @@ class StudentReport extends Page
|
|||||||
Select::make('class_id')
|
Select::make('class_id')
|
||||||
->label('Class')
|
->label('Class')
|
||||||
->required()
|
->required()
|
||||||
->options(ClassRoom::pluck('class_name', 'id')->toArray())
|
->options(function () {
|
||||||
|
$query = ClassRoom::query();
|
||||||
|
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
if ($user->hasAnyRole(['teacher'])) {
|
||||||
|
$homeRoomTeacher = HomeRoomTeacher::where('teacher_id', $user->id)->first();
|
||||||
|
if ($homeRoomTeacher) {
|
||||||
|
$query->where('id', $homeRoomTeacher->class_room_id);
|
||||||
|
}
|
||||||
|
} else if ($user->hasAnyRole(['parent'])) {
|
||||||
|
$student = Student::where("email", $user->email)->first(); // Changed from student email to parent_email
|
||||||
|
|
||||||
|
if ($student) {
|
||||||
|
$classStudentIds = ClassStudent::where("student_id", $student->id)
|
||||||
|
->pluck('class_room_id')
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$query->whereIn("id", $classStudentIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query->pluck('class_name', 'id')->toArray();
|
||||||
|
})
|
||||||
->searchable()
|
->searchable()
|
||||||
->reactive()
|
->native(false)
|
||||||
->afterStateUpdated(function ($state) {
|
->afterStateUpdated(function ($state) {
|
||||||
$this->class_id = $state;
|
$this->class_id = $state;
|
||||||
$this->data['class_id'] = $state; // Update data array
|
$this->data['class_id'] = $state; // Update data array
|
||||||
@ -98,6 +141,15 @@ class StudentReport extends Page
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
$isParent = $user->hasRole('parent');
|
||||||
|
$studentId = null;
|
||||||
|
if ($isParent) {
|
||||||
|
$student = Student::where('email', $user->email)->first();
|
||||||
|
$studentId = $student->id ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
$groupedAssessment = [];
|
$groupedAssessment = [];
|
||||||
|
|
||||||
$assessments = Assessment::where('semester', $this->semester)
|
$assessments = Assessment::where('semester', $this->semester)
|
||||||
@ -105,6 +157,9 @@ class StudentReport extends Page
|
|||||||
$query->where('academic_year_id', $this->academic_year)
|
$query->where('academic_year_id', $this->academic_year)
|
||||||
->where('class_id', $this->class_id);
|
->where('class_id', $this->class_id);
|
||||||
})
|
})
|
||||||
|
->when($isParent && $studentId, function($query) use ($studentId) {
|
||||||
|
$query->where('student_id', $studentId); // Tambahan filter untuk parent
|
||||||
|
})
|
||||||
->with('teacherSubject', 'student')
|
->with('teacherSubject', 'student')
|
||||||
->get()
|
->get()
|
||||||
->toArray();
|
->toArray();
|
||||||
@ -131,6 +186,9 @@ class StudentReport extends Page
|
|||||||
$students = ClassStudent::with(['class', 'academicYear', 'student'])
|
$students = ClassStudent::with(['class', 'academicYear', 'student'])
|
||||||
->where('class_room_id', $this->class_id)
|
->where('class_room_id', $this->class_id)
|
||||||
->where('academic_year_id', $this->academic_year)
|
->where('academic_year_id', $this->academic_year)
|
||||||
|
->when($isParent && $studentId, function($query) use ($studentId) {
|
||||||
|
$query->where('student_id', $studentId); // Tambahan filter untuk parent
|
||||||
|
})
|
||||||
->get()
|
->get()
|
||||||
->map(function($student) {
|
->map(function($student) {
|
||||||
return $student['student'];
|
return $student['student'];
|
||||||
|
|||||||
@ -7,6 +7,7 @@ use App\Filament\Resources\AcademicYearResource\RelationManagers;
|
|||||||
use App\Models\AcademicYear;
|
use App\Models\AcademicYear;
|
||||||
use Filament\Forms;
|
use Filament\Forms;
|
||||||
use Filament\Forms\Form;
|
use Filament\Forms\Form;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
use Filament\Resources\Resource;
|
use Filament\Resources\Resource;
|
||||||
use Filament\Tables;
|
use Filament\Tables;
|
||||||
use Filament\Tables\Table;
|
use Filament\Tables\Table;
|
||||||
@ -41,7 +42,9 @@ class AcademicYearResource extends Resource
|
|||||||
return $table
|
return $table
|
||||||
->columns([
|
->columns([
|
||||||
Tables\Columns\TextColumn::make('name')
|
Tables\Columns\TextColumn::make('name')
|
||||||
->searchable(),
|
->searchable()
|
||||||
|
->weight(fn (AcademicYear $record) => $record->is_active ? 'bold' : 'normal')
|
||||||
|
->color(fn (AcademicYear $record) => $record->is_active ? 'success' : null),
|
||||||
Tables\Columns\IconColumn::make('is_active')
|
Tables\Columns\IconColumn::make('is_active')
|
||||||
->boolean(),
|
->boolean(),
|
||||||
Tables\Columns\TextColumn::make('start_date')
|
Tables\Columns\TextColumn::make('start_date')
|
||||||
@ -68,6 +71,22 @@ class AcademicYearResource extends Resource
|
|||||||
])
|
])
|
||||||
->actions([
|
->actions([
|
||||||
Tables\Actions\EditAction::make(),
|
Tables\Actions\EditAction::make(),
|
||||||
|
Tables\Actions\Action::make('toggleActive')
|
||||||
|
->label('Toggle Active')
|
||||||
|
->icon('heroicon-o-power')
|
||||||
|
->action(function (AcademicYear $record) {
|
||||||
|
// If setting to active, deactivate all others
|
||||||
|
if ($record->is_active) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Info')
|
||||||
|
->body('The school year is active')
|
||||||
|
->info()
|
||||||
|
->send();
|
||||||
|
} else {
|
||||||
|
AcademicYear::where('is_active', true)->update(['is_active' => false]);
|
||||||
|
$record->update(['is_active' => true]);
|
||||||
|
}
|
||||||
|
}),
|
||||||
])
|
])
|
||||||
->bulkActions([
|
->bulkActions([
|
||||||
Tables\Actions\BulkActionGroup::make([
|
Tables\Actions\BulkActionGroup::make([
|
||||||
|
|||||||
@ -7,9 +7,11 @@ use App\Filament\Resources\AssessmentResource\RelationManagers;
|
|||||||
use App\Models\Assessment;
|
use App\Models\Assessment;
|
||||||
use App\Models\AssessmentComponent;
|
use App\Models\AssessmentComponent;
|
||||||
use App\Models\ClassStudent;
|
use App\Models\ClassStudent;
|
||||||
|
use App\Models\HomeRoomTeacher;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Models\TeacherSubject;
|
use App\Models\TeacherSubject;
|
||||||
use Filament\Forms;
|
use Filament\Forms;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
use Filament\Forms\Form;
|
use Filament\Forms\Form;
|
||||||
use Filament\Resources\Resource;
|
use Filament\Resources\Resource;
|
||||||
use Filament\Tables;
|
use Filament\Tables;
|
||||||
@ -29,14 +31,56 @@ class AssessmentResource extends Resource
|
|||||||
{
|
{
|
||||||
return $form
|
return $form
|
||||||
->schema([
|
->schema([
|
||||||
Forms\Components\Select::make('teacher_subject_id')
|
// Forms\Components\Select::make('teacher_subject_id')
|
||||||
|
// ->label('Teacher Subject')
|
||||||
|
// ->required()
|
||||||
|
// ->relationship('teacherSubject', 'id')
|
||||||
|
// ->getOptionLabelFromRecordUsing(fn (TeacherSubject $record) =>
|
||||||
|
// $record->teacher->name . ' - ' . $record->subject->name . ' - ' . $record->class->class_name . ' - ' . $record->academicYear->name)
|
||||||
|
// ->searchable()
|
||||||
|
// ->preload()
|
||||||
|
// ->afterStateUpdated(function (callable $set, $state) {
|
||||||
|
// if ($state) {
|
||||||
|
// $teacherSubject = TeacherSubject::find($state);
|
||||||
|
// if ($teacherSubject) {
|
||||||
|
// $set('student_id', null);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// ->required(),
|
||||||
|
|
||||||
|
Select::make('teacher_subject_id')
|
||||||
->label('Teacher Subject')
|
->label('Teacher Subject')
|
||||||
->required()
|
->required()
|
||||||
->relationship('teacherSubject', 'id')
|
->options(function () {
|
||||||
->getOptionLabelFromRecordUsing(fn (TeacherSubject $record) =>
|
$user = auth()->user();
|
||||||
$record->teacher->name . ' - ' . $record->subject->name . ' - ' . $record->class->class_name . ' - ' . $record->academicYear->name)
|
$query = TeacherSubject::with(['teacher', 'subject', 'class', 'academicYear']);
|
||||||
|
|
||||||
|
if ($user->hasRole('teacher')) {
|
||||||
|
// Ambil ID kelas dimana user menjadi wali kelas
|
||||||
|
$homeRoomClassIds = HomeRoomTeacher::where('teacher_id', $user->id)
|
||||||
|
->pluck('class_room_id')
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$query->where(function($q) use ($user, $homeRoomClassIds) {
|
||||||
|
// Mata pelajaran yang diajarkan oleh guru ini
|
||||||
|
$q->where('teacher_id', $user->id)
|
||||||
|
// ATAU kelas dimana dia menjadi wali kelas
|
||||||
|
->orWhereIn('class_id', $homeRoomClassIds);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query->get()->mapWithKeys(fn ($item) => [
|
||||||
|
$item->id => sprintf('%s - %s - %s - %s',
|
||||||
|
$item->teacher->name,
|
||||||
|
$item->subject->name,
|
||||||
|
$item->class->class_name,
|
||||||
|
$item->academicYear->name
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
})
|
||||||
->searchable()
|
->searchable()
|
||||||
->preload()
|
->live()
|
||||||
->afterStateUpdated(function (callable $set, $state) {
|
->afterStateUpdated(function (callable $set, $state) {
|
||||||
if ($state) {
|
if ($state) {
|
||||||
$teacherSubject = TeacherSubject::find($state);
|
$teacherSubject = TeacherSubject::find($state);
|
||||||
@ -44,8 +88,7 @@ class AssessmentResource extends Resource
|
|||||||
$set('student_id', null);
|
$set('student_id', null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
->required(),
|
|
||||||
|
|
||||||
Forms\Components\Select::make('student_id')
|
Forms\Components\Select::make('student_id')
|
||||||
->label('Student')
|
->label('Student')
|
||||||
@ -128,7 +171,7 @@ class AssessmentResource extends Resource
|
|||||||
])
|
])
|
||||||
->bulkActions([
|
->bulkActions([
|
||||||
Tables\Actions\BulkActionGroup::make([
|
Tables\Actions\BulkActionGroup::make([
|
||||||
Tables\Actions\DeleteBulkAction::make(),
|
Tables\Actions\DeleteBulkAction::make()->visible(fn () => auth()->user()->hasRole('admin') || auth()->user()->hasRole('teacher')),
|
||||||
]),
|
]),
|
||||||
])
|
])
|
||||||
->emptyStateActions([
|
->emptyStateActions([
|
||||||
|
|||||||
@ -3,21 +3,43 @@
|
|||||||
namespace App\Filament\Resources\AssessmentResource\Pages;
|
namespace App\Filament\Resources\AssessmentResource\Pages;
|
||||||
|
|
||||||
use App\Filament\Resources\AssessmentResource;
|
use App\Filament\Resources\AssessmentResource;
|
||||||
|
use App\Models\Assessment;
|
||||||
|
use App\Models\HomeRoomTeacher;
|
||||||
use Filament\Actions;
|
use Filament\Actions;
|
||||||
use Filament\Resources\Pages\ListRecords;
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
class ListAssessments extends ListRecords
|
class ListAssessments extends ListRecords
|
||||||
{
|
{
|
||||||
protected static string $resource = AssessmentResource::class;
|
protected static string $resource = AssessmentResource::class;
|
||||||
|
|
||||||
|
protected function getTableQuery(): Builder
|
||||||
|
{
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
if ($user->hasRole('teacher')) {
|
||||||
|
$homeRoomClassIds = HomeRoomTeacher::where('teacher_id', $user->id)
|
||||||
|
->pluck('class_room_id')
|
||||||
|
->toArray();
|
||||||
|
return Assessment::with('teacherSubject', 'student')
|
||||||
|
->whereHas('teacherSubject', function (Builder $query) use ($homeRoomClassIds, $user) {
|
||||||
|
$query->where('teacher_id', $user->id)
|
||||||
|
->orWhereIn('class_id', $homeRoomClassIds);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Assessment::query();
|
||||||
|
}
|
||||||
|
|
||||||
protected function getHeaderActions(): array
|
protected function getHeaderActions(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
Actions\CreateAction::make(),
|
Actions\CreateAction::make()->visible(fn () => auth()->user()->hasRole('admin')),
|
||||||
Actions\Action::make('multiple')
|
Actions\Action::make('multiple')
|
||||||
->label('Multiple Assessments')
|
->label('Multiple Assessments')
|
||||||
->url('assessments/multiple')
|
->url('assessments/multiple')
|
||||||
->icon('heroicon-o-user-group'),
|
->icon('heroicon-o-user-group')
|
||||||
|
->visible(fn () => auth()->user()->hasRole('admin') || auth()->user()->hasRole('teacher')),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ use App\Filament\Resources\AssessmentResource;
|
|||||||
use App\Models\Assessment;
|
use App\Models\Assessment;
|
||||||
use App\Models\Attendances;
|
use App\Models\Attendances;
|
||||||
use App\Models\ClassStudent;
|
use App\Models\ClassStudent;
|
||||||
|
use App\Models\HomeRoomTeacher;
|
||||||
use Filament\Actions;
|
use Filament\Actions;
|
||||||
use Filament\Forms\Components\Select;
|
use Filament\Forms\Components\Select;
|
||||||
use Filament\Resources\Pages\page;
|
use Filament\Resources\Pages\page;
|
||||||
@ -43,17 +44,51 @@ class MultipleAssessments extends page
|
|||||||
return [
|
return [
|
||||||
Forms\Components\Grid::make(2)
|
Forms\Components\Grid::make(2)
|
||||||
->schema([
|
->schema([
|
||||||
Forms\Components\Select::make('teacherSubjectId')
|
// Forms\Components\Select::make('teacherSubjectId')
|
||||||
|
// ->label('Teacher Subject')
|
||||||
|
// ->options(
|
||||||
|
// TeacherSubject::with(['teacher', 'subject', 'class', 'academicYear'])->get()->mapWithKeys(function ($item) {
|
||||||
|
// return [
|
||||||
|
// $item->id => "{$item->teacher->name} - {$item->subject->name} - {$item->class->class_name} - {$item->academicYear->name}"
|
||||||
|
// ];
|
||||||
|
// })->toArray()
|
||||||
|
// )
|
||||||
|
// ->searchable()
|
||||||
|
// ->reactive()
|
||||||
|
// ->afterStateUpdated(function ($state) {
|
||||||
|
// $this->teacherSubjectId = $state;
|
||||||
|
// $this->loadStudents();
|
||||||
|
// }),
|
||||||
|
|
||||||
|
Select::make('teacherSubjectId')
|
||||||
->label('Teacher Subject')
|
->label('Teacher Subject')
|
||||||
->options(
|
->required()
|
||||||
TeacherSubject::with(['teacher', 'subject', 'class', 'academicYear'])->get()->mapWithKeys(function ($item) {
|
->options(function () {
|
||||||
return [
|
$user = auth()->user();
|
||||||
$item->id => "{$item->teacher->name} - {$item->subject->name} - {$item->class->class_name} - {$item->academicYear->name}"
|
$query = TeacherSubject::with(['teacher', 'subject', 'class', 'academicYear']);
|
||||||
];
|
|
||||||
})->toArray()
|
if ($user->hasRole('teacher')) {
|
||||||
|
$homeRoomClassIds = HomeRoomTeacher::where('teacher_id', $user->id)
|
||||||
|
->pluck('class_room_id')
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$query->where(function($q) use ($user, $homeRoomClassIds) {
|
||||||
|
$q->where('teacher_id', $user->id)
|
||||||
|
->orWhereIn('class_id', $homeRoomClassIds);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query->get()->mapWithKeys(fn ($item) => [
|
||||||
|
$item->id => sprintf('%s - %s - %s - %s',
|
||||||
|
$item->teacher->name,
|
||||||
|
$item->subject->name,
|
||||||
|
$item->class->class_name,
|
||||||
|
$item->academicYear->name
|
||||||
)
|
)
|
||||||
|
]);
|
||||||
|
})
|
||||||
->searchable()
|
->searchable()
|
||||||
->reactive()
|
->live()
|
||||||
->afterStateUpdated(function ($state) {
|
->afterStateUpdated(function ($state) {
|
||||||
$this->teacherSubjectId = $state;
|
$this->teacherSubjectId = $state;
|
||||||
$this->loadStudents();
|
$this->loadStudents();
|
||||||
|
|||||||
@ -6,11 +6,13 @@ use App\Filament\Resources\AttendancesResource\Pages;
|
|||||||
use App\Models\Attendances;
|
use App\Models\Attendances;
|
||||||
use App\Models\ClassRoom;
|
use App\Models\ClassRoom;
|
||||||
use App\Models\ClassStudent;
|
use App\Models\ClassStudent;
|
||||||
|
use App\Models\HomeRoomTeacher;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Models\Subject;
|
use App\Models\Subject;
|
||||||
use App\Models\TeacherSubject;
|
use App\Models\TeacherSubject;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Filament\Forms;
|
use Filament\Forms;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
use Filament\Forms\Form;
|
use Filament\Forms\Form;
|
||||||
use Filament\Resources\Resource;
|
use Filament\Resources\Resource;
|
||||||
use Filament\Tables;
|
use Filament\Tables;
|
||||||
@ -29,14 +31,38 @@ class AttendancesResource extends Resource
|
|||||||
->schema([
|
->schema([
|
||||||
Forms\Components\Section::make('Data Absensi')
|
Forms\Components\Section::make('Data Absensi')
|
||||||
->schema([
|
->schema([
|
||||||
Forms\Components\Select::make('teacher_subject_id')
|
Select::make('teacher_subject_id')
|
||||||
->label('Teacher Subject')
|
->label('Teacher Subject')
|
||||||
->required()
|
->required()
|
||||||
->relationship('teacherSubject', 'id')
|
->options(function () {
|
||||||
->getOptionLabelFromRecordUsing(fn (TeacherSubject $record) =>
|
$user = auth()->user();
|
||||||
$record->teacher->name . ' - ' . $record->subject->name . ' - ' . $record->class->class_name . ' - ' . $record->academicYear->name)
|
$query = TeacherSubject::with(['teacher', 'subject', 'class', 'academicYear']);
|
||||||
|
|
||||||
|
if ($user->hasRole('teacher')) {
|
||||||
|
// Ambil ID kelas dimana user menjadi wali kelas
|
||||||
|
$homeRoomClassIds = HomeRoomTeacher::where('teacher_id', $user->id)
|
||||||
|
->pluck('class_room_id')
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$query->where(function($q) use ($user, $homeRoomClassIds) {
|
||||||
|
// Mata pelajaran yang diajarkan oleh guru ini
|
||||||
|
$q->where('teacher_id', $user->id)
|
||||||
|
// ATAU kelas dimana dia menjadi wali kelas
|
||||||
|
->orWhereIn('class_id', $homeRoomClassIds);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query->get()->mapWithKeys(fn ($item) => [
|
||||||
|
$item->id => sprintf('%s - %s - %s - %s',
|
||||||
|
$item->teacher->name,
|
||||||
|
$item->subject->name,
|
||||||
|
$item->class->class_name,
|
||||||
|
$item->academicYear->name
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
})
|
||||||
->searchable()
|
->searchable()
|
||||||
->preload()
|
->live()
|
||||||
->afterStateUpdated(function (callable $set, $state) {
|
->afterStateUpdated(function (callable $set, $state) {
|
||||||
if ($state) {
|
if ($state) {
|
||||||
$teacherSubject = TeacherSubject::find($state);
|
$teacherSubject = TeacherSubject::find($state);
|
||||||
@ -53,7 +79,7 @@ class AttendancesResource extends Resource
|
|||||||
->default(now())
|
->default(now())
|
||||||
->live(),
|
->live(),
|
||||||
|
|
||||||
Forms\Components\Select::make('student_id')
|
Select::make('student_id')
|
||||||
->label('Student')
|
->label('Student')
|
||||||
->required()
|
->required()
|
||||||
->searchable()
|
->searchable()
|
||||||
@ -77,7 +103,7 @@ class AttendancesResource extends Resource
|
|||||||
return $student ? $student->full_name . ' (' . $student->nis . ')' : null;
|
return $student ? $student->full_name . ' (' . $student->nis . ')' : null;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
Forms\Components\Select::make('semester')
|
Select::make('semester')
|
||||||
->label('Semester')
|
->label('Semester')
|
||||||
->required()
|
->required()
|
||||||
->options([
|
->options([
|
||||||
@ -85,7 +111,7 @@ class AttendancesResource extends Resource
|
|||||||
'second' => 'Second Semester'
|
'second' => 'Second Semester'
|
||||||
]),
|
]),
|
||||||
|
|
||||||
Forms\Components\Select::make('status')
|
Select::make('status')
|
||||||
->label('Status')
|
->label('Status')
|
||||||
->required()
|
->required()
|
||||||
->options([
|
->options([
|
||||||
@ -161,10 +187,6 @@ class AttendancesResource extends Resource
|
|||||||
Tables\Columns\TextColumn::make('recorder.name')
|
Tables\Columns\TextColumn::make('recorder.name')
|
||||||
->label('Record by')
|
->label('Record by')
|
||||||
->toggleable(),
|
->toggleable(),
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('notes')
|
|
||||||
->label('Notes')
|
|
||||||
->toggleable()
|
|
||||||
])
|
])
|
||||||
->filters([
|
->filters([
|
||||||
Tables\Filters\SelectFilter::make('status')
|
Tables\Filters\SelectFilter::make('status')
|
||||||
@ -218,12 +240,9 @@ class AttendancesResource extends Resource
|
|||||||
])
|
])
|
||||||
->bulkActions([
|
->bulkActions([
|
||||||
Tables\Actions\BulkActionGroup::make([
|
Tables\Actions\BulkActionGroup::make([
|
||||||
Tables\Actions\DeleteBulkAction::make(),
|
Tables\Actions\DeleteBulkAction::make()->visible(fn () => auth()->user()->hasRole('admin') || auth()->user()->hasRole('teacher')),
|
||||||
]),
|
]),
|
||||||
])
|
])
|
||||||
->emptyStateActions([
|
|
||||||
Tables\Actions\CreateAction::make(),
|
|
||||||
])
|
|
||||||
->defaultSort('date', 'desc')
|
->defaultSort('date', 'desc')
|
||||||
->groups([
|
->groups([
|
||||||
Tables\Grouping\Group::make('date')
|
Tables\Grouping\Group::make('date')
|
||||||
|
|||||||
@ -3,21 +3,43 @@
|
|||||||
namespace App\Filament\Resources\AttendancesResource\Pages;
|
namespace App\Filament\Resources\AttendancesResource\Pages;
|
||||||
|
|
||||||
use App\Filament\Resources\AttendancesResource;
|
use App\Filament\Resources\AttendancesResource;
|
||||||
|
use App\Models\Attendances;
|
||||||
|
use App\Models\HomeRoomTeacher;
|
||||||
use Filament\Actions;
|
use Filament\Actions;
|
||||||
use Filament\Resources\Pages\ListRecords;
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
class ListAttendances extends ListRecords
|
class ListAttendances extends ListRecords
|
||||||
{
|
{
|
||||||
protected static string $resource = AttendancesResource::class;
|
protected static string $resource = AttendancesResource::class;
|
||||||
|
|
||||||
|
protected function getTableQuery(): ?Builder
|
||||||
|
{
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
if ($user->hasRole('teacher')) {
|
||||||
|
$homeRoomClassIds = HomeRoomTeacher::where('teacher_id', $user->id)
|
||||||
|
->pluck('class_room_id')
|
||||||
|
->toArray();
|
||||||
|
return Attendances::with('teacherSubject', 'student')
|
||||||
|
->whereHas('teacherSubject', function (Builder $query) use ($homeRoomClassIds, $user) {
|
||||||
|
$query->where('teacher_id', $user->id)
|
||||||
|
->orWhereIn('class_id', $homeRoomClassIds);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Attendances::query();
|
||||||
|
}
|
||||||
|
|
||||||
protected function getHeaderActions(): array
|
protected function getHeaderActions(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
Actions\CreateAction::make(),
|
Actions\CreateAction::make()->visible(fn () => auth()->user()->hasRole('admin')),
|
||||||
Actions\Action::make('multiple')
|
Actions\Action::make('multiple')
|
||||||
->label('Multiple Attendance')
|
->label('Multiple Attendance')
|
||||||
->url('attendances/multiple')
|
->url('attendances/multiple')
|
||||||
->icon('heroicon-o-user-group'),
|
->icon('heroicon-o-user-group')
|
||||||
|
->visible(fn () => auth()->user()->hasRole('admin') || auth()->user()->hasRole('teacher')),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ use App\Models\Assessment;
|
|||||||
use App\Models\Attendances;
|
use App\Models\Attendances;
|
||||||
use App\Models\ClassRoom;
|
use App\Models\ClassRoom;
|
||||||
use App\Models\ClassStudent;
|
use App\Models\ClassStudent;
|
||||||
|
use App\Models\HomeRoomTeacher;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Models\TeacherSubject;
|
use App\Models\TeacherSubject;
|
||||||
use Filament\Actions;
|
use Filament\Actions;
|
||||||
@ -48,11 +49,33 @@ class MultipleAttendances extends Page
|
|||||||
Select::make('teacher_subject_id')
|
Select::make('teacher_subject_id')
|
||||||
->label('Teacher Subject')
|
->label('Teacher Subject')
|
||||||
->required()
|
->required()
|
||||||
->options(TeacherSubject::with(['teacher', 'subject', 'class'])
|
->options(function () {
|
||||||
->get()
|
$user = auth()->user();
|
||||||
->mapWithKeys(fn ($item) => [
|
$query = TeacherSubject::with(['teacher', 'subject', 'class', 'academicYear']);
|
||||||
$item->id => $item->teacher->name . ' - ' . $item->subject->name . ' - ' . $item->class->class_name . ' - ' . $item->academicYear->name
|
|
||||||
]))
|
if ($user->hasRole('teacher')) {
|
||||||
|
// Ambil ID kelas dimana user menjadi wali kelas
|
||||||
|
$homeRoomClassIds = HomeRoomTeacher::where('teacher_id', $user->id)
|
||||||
|
->pluck('class_room_id')
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$query->where(function($q) use ($user, $homeRoomClassIds) {
|
||||||
|
// Mata pelajaran yang diajarkan oleh guru ini
|
||||||
|
$q->where('teacher_id', $user->id)
|
||||||
|
// ATAU kelas dimana dia menjadi wali kelas
|
||||||
|
->orWhereIn('class_id', $homeRoomClassIds);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query->get()->mapWithKeys(fn ($item) => [
|
||||||
|
$item->id => sprintf('%s - %s - %s - %s',
|
||||||
|
$item->teacher->name,
|
||||||
|
$item->subject->name,
|
||||||
|
$item->class->class_name,
|
||||||
|
$item->academicYear->name
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
})
|
||||||
->searchable()
|
->searchable()
|
||||||
->live()
|
->live()
|
||||||
->afterStateUpdated(function ($state) {
|
->afterStateUpdated(function ($state) {
|
||||||
@ -135,28 +158,6 @@ class MultipleAttendances extends Page
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->students = $result;
|
$this->students = $result;
|
||||||
|
|
||||||
// $this->students = ClassStudent::where('class_room_id', $this->teacherSubjectId)
|
|
||||||
// ->where('academic_year_id', $this->teacherSubject->academic_year_id)
|
|
||||||
// ->with('student')
|
|
||||||
// ->get()
|
|
||||||
// ->map(function ($student) {
|
|
||||||
// $existingAttendance = Attendances::where('student_id', $student->student_id)
|
|
||||||
// ->where('teacher_subject_id', $this->teacherSubjectId)
|
|
||||||
// ->whereDate('date', $this->attendanceDate)
|
|
||||||
// ->where('semester', $this->semester)
|
|
||||||
// ->first();
|
|
||||||
//
|
|
||||||
// return [
|
|
||||||
// 'id' => $student->student->id,
|
|
||||||
// 'name' => $student->student->full_name,
|
|
||||||
// 'nis' => $student->student->nis,
|
|
||||||
// 'status' => $existingAttendance ? $existingAttendance->status : null,
|
|
||||||
// 'attendance_id' => $existingAttendance ? $existingAttendance->id : null,
|
|
||||||
// ];
|
|
||||||
// })
|
|
||||||
// ->values()
|
|
||||||
// ->toArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function markAll($status): void
|
public function markAll($status): void
|
||||||
|
|||||||
@ -6,6 +6,7 @@ use App\Filament\Resources\CompetencyAchievementResource\Pages;
|
|||||||
use App\Filament\Resources\CompetencyAchievementResource\RelationManagers;
|
use App\Filament\Resources\CompetencyAchievementResource\RelationManagers;
|
||||||
use App\Models\ClassRoom;
|
use App\Models\ClassRoom;
|
||||||
use App\Models\CompetencyAchievement;
|
use App\Models\CompetencyAchievement;
|
||||||
|
use App\Models\HomeRoomTeacher;
|
||||||
use App\Models\Subject;
|
use App\Models\Subject;
|
||||||
use Filament\Forms;
|
use Filament\Forms;
|
||||||
use Filament\Forms\Form;
|
use Filament\Forms\Form;
|
||||||
@ -35,7 +36,20 @@ class CompetencyAchievementResource extends Resource
|
|||||||
Forms\Components\Select::make('class_room_id')
|
Forms\Components\Select::make('class_room_id')
|
||||||
->label('Class')
|
->label('Class')
|
||||||
->required()
|
->required()
|
||||||
->options(ClassRoom::pluck('class_name', 'id')->toArray())
|
->options(function () {
|
||||||
|
$query = ClassRoom::query();
|
||||||
|
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
if ($user->hasAnyRole(['teacher'])) {
|
||||||
|
$homeRoomTeacher = HomeRoomTeacher::where('teacher_id', $user->id)->first();
|
||||||
|
if ($homeRoomTeacher) {
|
||||||
|
$query->where('id', $homeRoomTeacher->class_room_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query->pluck('class_name', 'id')->toArray();
|
||||||
|
})
|
||||||
->searchable()
|
->searchable()
|
||||||
->native(false),
|
->native(false),
|
||||||
|
|
||||||
@ -87,7 +101,7 @@ class CompetencyAchievementResource extends Resource
|
|||||||
])
|
])
|
||||||
->bulkActions([
|
->bulkActions([
|
||||||
Tables\Actions\BulkActionGroup::make([
|
Tables\Actions\BulkActionGroup::make([
|
||||||
Tables\Actions\DeleteBulkAction::make(),
|
Tables\Actions\DeleteBulkAction::make()->visible(fn () => auth()->user()->hasRole('admin') || auth()->user()->hasRole('teacher')),
|
||||||
]),
|
]),
|
||||||
])
|
])
|
||||||
->emptyStateActions([
|
->emptyStateActions([
|
||||||
|
|||||||
@ -3,13 +3,30 @@
|
|||||||
namespace App\Filament\Resources\CompetencyAchievementResource\Pages;
|
namespace App\Filament\Resources\CompetencyAchievementResource\Pages;
|
||||||
|
|
||||||
use App\Filament\Resources\CompetencyAchievementResource;
|
use App\Filament\Resources\CompetencyAchievementResource;
|
||||||
|
use App\Models\CompetencyAchievement;
|
||||||
|
use App\Models\HomeRoomTeacher;
|
||||||
use Filament\Actions;
|
use Filament\Actions;
|
||||||
use Filament\Resources\Pages\ListRecords;
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
class ListCompetencyAchievements extends ListRecords
|
class ListCompetencyAchievements extends ListRecords
|
||||||
{
|
{
|
||||||
protected static string $resource = CompetencyAchievementResource::class;
|
protected static string $resource = CompetencyAchievementResource::class;
|
||||||
|
|
||||||
|
protected function getTableQuery(): Builder
|
||||||
|
{
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
if ($user->hasRole('teacher')) {
|
||||||
|
$homeRoomTeacher = HomeRoomTeacher::where('teacher_id', $user->id)->firstOrFail();
|
||||||
|
if ($homeRoomTeacher) {
|
||||||
|
return CompetencyAchievement::where('class_room_id', $homeRoomTeacher->class_room_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CompetencyAchievement::query();
|
||||||
|
}
|
||||||
|
|
||||||
protected function getHeaderActions(): array
|
protected function getHeaderActions(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|||||||
@ -7,14 +7,12 @@ use App\Filament\Resources\ExtracurricularAssessmentResource\RelationManagers;
|
|||||||
use App\Models\ClassStudent;
|
use App\Models\ClassStudent;
|
||||||
use App\Models\Extracurricular;
|
use App\Models\Extracurricular;
|
||||||
use App\Models\ExtracurricularAssessment;
|
use App\Models\ExtracurricularAssessment;
|
||||||
use App\Models\TeacherSubject;
|
use App\Models\HomeRoomTeacher;
|
||||||
use Filament\Forms;
|
use Filament\Forms;
|
||||||
use Filament\Forms\Form;
|
use Filament\Forms\Form;
|
||||||
use Filament\Resources\Resource;
|
use Filament\Resources\Resource;
|
||||||
use Filament\Tables;
|
use Filament\Tables;
|
||||||
use Filament\Tables\Table;
|
use Filament\Tables\Table;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
|
||||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
|
||||||
|
|
||||||
class ExtracurricularAssessmentResource extends Resource
|
class ExtracurricularAssessmentResource extends Resource
|
||||||
{
|
{
|
||||||
@ -27,14 +25,36 @@ class ExtracurricularAssessmentResource extends Resource
|
|||||||
public static function form(Form $form): Form
|
public static function form(Form $form): Form
|
||||||
{
|
{
|
||||||
return $form
|
return $form
|
||||||
->schema([
|
->schema(components: [
|
||||||
Forms\Components\Select::make('class_student_id')
|
Forms\Components\Select::make('class_student_id')
|
||||||
->relationship('classStudent', 'id') // atau gunakan relasi yang lebih deskriptif jika ada
|
->label('Siswa & Kelas')
|
||||||
->getOptionLabelFromRecordUsing(fn (ClassStudent $record) =>
|
->options(function () {
|
||||||
$record->class->class_name . ' - ' . $record->student->full_name . ' - ' . $record->academicYear->name)
|
$user = auth()->user();
|
||||||
|
$query = ClassStudent::with(['student', 'class']);
|
||||||
|
|
||||||
|
if ($user->hasAnyRole(['admin']))
|
||||||
|
{
|
||||||
|
return $query->get()->mapWithKeys(function ($cs) {
|
||||||
|
return [
|
||||||
|
$cs->id => $cs->student->full_name . ' - ' . $cs->class->class_name . ' - ' . $cs->academicYear->name,
|
||||||
|
];
|
||||||
|
});
|
||||||
|
} else if ($user->hasAnyRole(['teacher'])) {
|
||||||
|
$homeRoomTeacher = HomeRoomTeacher::where('teacher_id', $user->id)->firstOrFail();
|
||||||
|
$query->whereHas('class', function ($query) use ($homeRoomTeacher) {
|
||||||
|
$query->where('id', $homeRoomTeacher->class_room_id);
|
||||||
|
});
|
||||||
|
return $query->get()->mapWithKeys(function ($cs) {
|
||||||
|
return [
|
||||||
|
$cs->id => $cs->student->full_name . ' - ' . $cs->class->class_name . ' - ' . $cs->academicYear->name,
|
||||||
|
];
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
})
|
||||||
->searchable()
|
->searchable()
|
||||||
->preload()
|
->preload(),
|
||||||
->required(),
|
|
||||||
|
|
||||||
Forms\Components\Select::make('extracurricular_id')
|
Forms\Components\Select::make('extracurricular_id')
|
||||||
->relationship('extracurricular', 'name')
|
->relationship('extracurricular', 'name')
|
||||||
@ -50,8 +70,19 @@ class ExtracurricularAssessmentResource extends Resource
|
|||||||
])
|
])
|
||||||
->required(),
|
->required(),
|
||||||
|
|
||||||
Forms\Components\TextInput::make('score')
|
Forms\Components\Select::make('predicate')
|
||||||
->numeric()
|
->label('Predicate')
|
||||||
|
->options([
|
||||||
|
'A' => 'A',
|
||||||
|
'B' => 'B',
|
||||||
|
'C' => 'C',
|
||||||
|
'D' => 'D',
|
||||||
|
'E' => 'E',
|
||||||
|
])
|
||||||
|
->required(),
|
||||||
|
|
||||||
|
Forms\Components\Textarea::make('description')
|
||||||
|
->label('Description')
|
||||||
->required(),
|
->required(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -74,10 +105,17 @@ class ExtracurricularAssessmentResource extends Resource
|
|||||||
Tables\Columns\TextColumn::make('extracurricular.name')
|
Tables\Columns\TextColumn::make('extracurricular.name')
|
||||||
->label('Extracurricular'),
|
->label('Extracurricular'),
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('semester'),
|
Tables\Columns\TextColumn::make('semester')
|
||||||
|
->formatStateUsing(function ($state) {
|
||||||
|
return $state === 'first' ? 'Ganjil' : 'Genap';
|
||||||
|
}),
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('score')
|
Tables\Columns\TextColumn::make('predicate')
|
||||||
|
->label('Predicate')
|
||||||
->sortable(),
|
->sortable(),
|
||||||
|
|
||||||
|
Tables\Columns\TextColumn::make('description')
|
||||||
|
->label('Description'),
|
||||||
])
|
])
|
||||||
->filters([
|
->filters([
|
||||||
//
|
//
|
||||||
@ -87,8 +125,11 @@ class ExtracurricularAssessmentResource extends Resource
|
|||||||
])
|
])
|
||||||
->bulkActions([
|
->bulkActions([
|
||||||
Tables\Actions\BulkActionGroup::make([
|
Tables\Actions\BulkActionGroup::make([
|
||||||
Tables\Actions\DeleteBulkAction::make(),
|
Tables\Actions\DeleteBulkAction::make()->visible(fn () => auth()->user()->hasRole('admin') || auth()->user()->hasRole('teacher')),
|
||||||
]),
|
]),
|
||||||
|
])
|
||||||
|
->emptyStateActions([
|
||||||
|
Tables\Actions\CreateAction::make(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,13 +3,32 @@
|
|||||||
namespace App\Filament\Resources\ExtracurricularAssessmentResource\Pages;
|
namespace App\Filament\Resources\ExtracurricularAssessmentResource\Pages;
|
||||||
|
|
||||||
use App\Filament\Resources\ExtracurricularAssessmentResource;
|
use App\Filament\Resources\ExtracurricularAssessmentResource;
|
||||||
|
use App\Models\ExtracurricularAssessment;
|
||||||
|
use App\Models\HomeRoomTeacher;
|
||||||
use Filament\Actions;
|
use Filament\Actions;
|
||||||
use Filament\Resources\Pages\ListRecords;
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
class ListExtracurricularAssessments extends ListRecords
|
class ListExtracurricularAssessments extends ListRecords
|
||||||
{
|
{
|
||||||
protected static string $resource = ExtracurricularAssessmentResource::class;
|
protected static string $resource = ExtracurricularAssessmentResource::class;
|
||||||
|
|
||||||
|
protected function getTableQuery() : Builder
|
||||||
|
{
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
if ($user->hasRole('teacher')) {
|
||||||
|
$homeRoomTeacher = HomeRoomTeacher::where('teacher_id', $user->id)->firstOrFail();
|
||||||
|
return ExtracurricularAssessment::with('classStudent', 'extracurricular')
|
||||||
|
->whereHas('classStudent', function (Builder $query) use ($homeRoomTeacher) {
|
||||||
|
$query->where('class_room_id', $homeRoomTeacher->class_room_id)
|
||||||
|
->where('academic_year_id', $homeRoomTeacher->academic_year_id);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return ExtracurricularAssessment::query();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected function getHeaderActions(): array
|
protected function getHeaderActions(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|||||||
@ -62,8 +62,9 @@ class StudentResource extends Resource
|
|||||||
->maxLength(15),
|
->maxLength(15),
|
||||||
|
|
||||||
Forms\Components\TextInput::make('email')
|
Forms\Components\TextInput::make('email')
|
||||||
->label('Email')
|
->label("Parent's Email")
|
||||||
->email()
|
->email()
|
||||||
|
->required()
|
||||||
->maxLength(100),
|
->maxLength(100),
|
||||||
|
|
||||||
Forms\Components\TextInput::make('parent_name')
|
Forms\Components\TextInput::make('parent_name')
|
||||||
@ -73,6 +74,7 @@ class StudentResource extends Resource
|
|||||||
|
|
||||||
Forms\Components\TextInput::make('parent_phone')
|
Forms\Components\TextInput::make('parent_phone')
|
||||||
->label("Parent's Phone")
|
->label("Parent's Phone")
|
||||||
|
->required()
|
||||||
->maxLength(15),
|
->maxLength(15),
|
||||||
|
|
||||||
Forms\Components\Select::make('religion')
|
Forms\Components\Select::make('religion')
|
||||||
|
|||||||
@ -3,10 +3,36 @@
|
|||||||
namespace App\Filament\Resources\StudentResource\Pages;
|
namespace App\Filament\Resources\StudentResource\Pages;
|
||||||
|
|
||||||
use App\Filament\Resources\StudentResource;
|
use App\Filament\Resources\StudentResource;
|
||||||
|
use App\Models\Student;
|
||||||
|
use App\Models\User;
|
||||||
|
use Carbon\Carbon;
|
||||||
use Filament\Actions;
|
use Filament\Actions;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
use Filament\Resources\Pages\CreateRecord;
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
use Spatie\Permission\Models\Role;
|
||||||
|
|
||||||
class CreateStudent extends CreateRecord
|
class CreateStudent extends CreateRecord
|
||||||
{
|
{
|
||||||
protected static string $resource = StudentResource::class;
|
protected static string $resource = StudentResource::class;
|
||||||
|
|
||||||
|
protected function mutateFormDataBeforeCreate(array $data): array
|
||||||
|
{
|
||||||
|
$parentRole = Role::where('name', 'parent')->first();
|
||||||
|
|
||||||
|
$birthDate = Carbon::parse($data['birth_date']);
|
||||||
|
$password = $birthDate->format('dmY') . $data['nis'];
|
||||||
|
|
||||||
|
$parentUser = User::updateOrCreate(
|
||||||
|
['email' => $data['email']],
|
||||||
|
[
|
||||||
|
'name' => $data['parent_name'],
|
||||||
|
'password' => bcrypt($password),
|
||||||
|
'phone' => $data['parent_phone'],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$parentUser->assignRole($parentRole);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,17 +3,47 @@
|
|||||||
namespace App\Filament\Resources\StudentResource\Pages;
|
namespace App\Filament\Resources\StudentResource\Pages;
|
||||||
|
|
||||||
use App\Filament\Resources\StudentResource;
|
use App\Filament\Resources\StudentResource;
|
||||||
|
use App\Models\User;
|
||||||
use Filament\Actions;
|
use Filament\Actions;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
use Filament\Resources\Pages\EditRecord;
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
use Spatie\Permission\Models\Role;
|
||||||
|
|
||||||
class EditStudent extends EditRecord
|
class EditStudent extends EditRecord
|
||||||
{
|
{
|
||||||
protected static string $resource = StudentResource::class;
|
protected static string $resource = StudentResource::class;
|
||||||
|
|
||||||
|
protected function mutateFormDataBeforeSave(array $data): array
|
||||||
|
{
|
||||||
|
$parentRole = Role::where('name', 'parent')->first();
|
||||||
|
|
||||||
|
$parentUser = User::updateOrCreate(
|
||||||
|
['email' => $data['email']],
|
||||||
|
[
|
||||||
|
'name' => $data['parent_name'],
|
||||||
|
'phone' => $data['parent_phone'],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Pastikan user memiliki role parent
|
||||||
|
if (!$parentUser->hasRole('parent')) {
|
||||||
|
$parentUser->assignRole($parentRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
protected function getHeaderActions(): array
|
protected function getHeaderActions(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
Actions\DeleteAction::make(),
|
Actions\DeleteAction::make()
|
||||||
|
->before(function (Actions\DeleteAction $action) {
|
||||||
|
$student = $this->record;
|
||||||
|
|
||||||
|
if ($student->email) {
|
||||||
|
User::where('email', $student->email)->delete();
|
||||||
|
}
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Filament\Resources\StudentResource\Pages;
|
namespace App\Filament\Resources\StudentResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Imports\StudentImporter;
|
||||||
use App\Filament\Resources\StudentResource;
|
use App\Filament\Resources\StudentResource;
|
||||||
use Filament\Actions;
|
use Filament\Actions;
|
||||||
use Filament\Resources\Pages\ListRecords;
|
use Filament\Resources\Pages\ListRecords;
|
||||||
@ -14,6 +15,8 @@ class ListStudents extends ListRecords
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
Actions\CreateAction::make(),
|
Actions\CreateAction::make(),
|
||||||
|
Actions\ImportAction::make('importBrands')
|
||||||
|
->importer(StudentImporter::class),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,21 +29,43 @@ class UserResource extends Resource
|
|||||||
Forms\Components\TextInput::make('name')
|
Forms\Components\TextInput::make('name')
|
||||||
->required()
|
->required()
|
||||||
->maxLength(255),
|
->maxLength(255),
|
||||||
|
|
||||||
Forms\Components\TextInput::make('email')
|
Forms\Components\TextInput::make('email')
|
||||||
->email()
|
->email()
|
||||||
->required()
|
->required()
|
||||||
->maxLength(255),
|
->maxLength(255),
|
||||||
|
|
||||||
Forms\Components\TextInput::make('password')
|
Forms\Components\TextInput::make('password')
|
||||||
->password()
|
->password()
|
||||||
->required(fn (string $context): bool => $context === 'create')
|
->required(fn (string $context): bool => $context === 'create')
|
||||||
->dehydrateStateUsing(fn ($state) => Hash::make($state))
|
->dehydrateStateUsing(fn ($state) => Hash::make($state))
|
||||||
->dehydrated(fn ($state) => filled($state))
|
->dehydrated(fn ($state) => filled($state))
|
||||||
->maxLength(255),
|
->maxLength(255),
|
||||||
|
|
||||||
Forms\Components\Select::make('role')
|
Forms\Components\Select::make('role')
|
||||||
->relationship('roles', 'name')
|
->relationship('roles', 'name')
|
||||||
->preload()
|
->preload()
|
||||||
->searchable()
|
->searchable()
|
||||||
->required(),
|
->required(),
|
||||||
|
|
||||||
|
Forms\Components\TextInput::make('nip')
|
||||||
|
->label('NIP')
|
||||||
|
->maxLength(255),
|
||||||
|
|
||||||
|
Forms\Components\Select::make('gender')
|
||||||
|
->options([
|
||||||
|
'L' => 'L',
|
||||||
|
'P' => 'P',
|
||||||
|
]),
|
||||||
|
|
||||||
|
Forms\Components\DatePicker::make('birth_date'),
|
||||||
|
|
||||||
|
Forms\Components\TextInput::make('phone')
|
||||||
|
->tel()
|
||||||
|
->maxLength(255),
|
||||||
|
|
||||||
|
Forms\Components\Textarea::make('address')
|
||||||
|
->columnSpanFull(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,6 +77,18 @@ class UserResource extends Resource
|
|||||||
->searchable(),
|
->searchable(),
|
||||||
Tables\Columns\TextColumn::make('email')
|
Tables\Columns\TextColumn::make('email')
|
||||||
->searchable(),
|
->searchable(),
|
||||||
|
Tables\Columns\TextColumn::make('nip')
|
||||||
|
->label('NIP')
|
||||||
|
->searchable(),
|
||||||
|
Tables\Columns\TextColumn::make('gender')
|
||||||
|
->formatStateUsing(fn (string $state): string => ucfirst($state)),
|
||||||
|
Tables\Columns\TextColumn::make('birth_date')
|
||||||
|
->date(),
|
||||||
|
Tables\Columns\TextColumn::make('phone')
|
||||||
|
->searchable(),
|
||||||
|
Tables\Columns\TextColumn::make('roles.name')
|
||||||
|
->searchable()
|
||||||
|
->sortable(),
|
||||||
Tables\Columns\TextColumn::make('created_at')
|
Tables\Columns\TextColumn::make('created_at')
|
||||||
->dateTime()
|
->dateTime()
|
||||||
->sortable()
|
->sortable()
|
||||||
@ -63,17 +97,16 @@ class UserResource extends Resource
|
|||||||
->dateTime()
|
->dateTime()
|
||||||
->sortable()
|
->sortable()
|
||||||
->toggleable(isToggledHiddenByDefault: true),
|
->toggleable(isToggledHiddenByDefault: true),
|
||||||
Tables\Columns\TextColumn::make('roles.name')->searchable(),
|
|
||||||
])
|
])
|
||||||
->filters([
|
->filters([
|
||||||
//
|
//
|
||||||
])
|
])
|
||||||
->actions([
|
->actions([
|
||||||
Tables\Actions\EditAction::make(),
|
Tables\Actions\EditAction::make()->visible(fn () => auth()->user()->hasRole('admin')),
|
||||||
])
|
])
|
||||||
->bulkActions([
|
->bulkActions([
|
||||||
Tables\Actions\BulkActionGroup::make([
|
Tables\Actions\BulkActionGroup::make([
|
||||||
// Tables\Actions\DeleteBulkAction::make(),
|
// Tables\Actions\DeleteBulkAction::make()->visible(fn () => auth()->user()->hasRole('admin')),
|
||||||
]),
|
]),
|
||||||
])
|
])
|
||||||
->emptyStateActions([
|
->emptyStateActions([
|
||||||
|
|||||||
229
app/Http/Controllers/ReportPDFController.php
Normal file
229
app/Http/Controllers/ReportPDFController.php
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\AcademicYear;
|
||||||
|
use App\Models\Assessment;
|
||||||
|
use App\Models\ClassRoom;
|
||||||
|
use App\Models\CompetencyAchievement;
|
||||||
|
use App\Models\ExtracurricularAssessment;
|
||||||
|
use App\Models\HomeRoomTeacher;
|
||||||
|
use App\Models\SchoolInformation;
|
||||||
|
use App\Models\Student;
|
||||||
|
use Barryvdh\DomPDF\Facade\Pdf;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
|
class ReportPDFController extends Controller
|
||||||
|
{
|
||||||
|
public $student;
|
||||||
|
public $class;
|
||||||
|
public $class_name;
|
||||||
|
public $academic_year;
|
||||||
|
public $semester;
|
||||||
|
|
||||||
|
public $school_information;
|
||||||
|
|
||||||
|
public $table = [];
|
||||||
|
|
||||||
|
public $home_room_teacher;
|
||||||
|
|
||||||
|
public function reportPDF(Request $request)
|
||||||
|
{
|
||||||
|
$params = $request->query();
|
||||||
|
$defaultParams = ["studentId", "classId", "yearId", "semester", "sakit", "izin", "tanpa_keterangan"];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->validateParameters($params, $defaultParams);
|
||||||
|
} catch (\Illuminate\Validation\ValidationException $e) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Parameter tidak valid: ' . $e->getMessage())
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
return back();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$this->student = Student::findOrFail($params["studentId"]);
|
||||||
|
$this->class = ClassRoom::findOrFail($params["classId"]);
|
||||||
|
$this->academic_year = AcademicYear::findOrFail($params["yearId"]);
|
||||||
|
$this->semester = $params["semester"];
|
||||||
|
|
||||||
|
$this->school_information = SchoolInformation::firstOrFail();
|
||||||
|
|
||||||
|
$this->class_name = $this->toRoman($this->class->class_level) . ' ' . $this->extractClassLetter($this->class->class_name);
|
||||||
|
|
||||||
|
$this->loadAssessment();
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'student' => $this->student,
|
||||||
|
'school_information' => $this->school_information,
|
||||||
|
'table' => $this->table,
|
||||||
|
'sakit' => $params['sakit'],
|
||||||
|
'izin' => $params['izin'],
|
||||||
|
'tanpa_keterangan' => $params['tanpa_keterangan'],
|
||||||
|
'class_name' => $this->class_name,
|
||||||
|
'semester' => $params['semester'],
|
||||||
|
'academic_year' => $this->academic_year,
|
||||||
|
'home_room_teacher' => $this->home_room_teacher,
|
||||||
|
];
|
||||||
|
|
||||||
|
$pdf = Pdf::loadView('print.report', $data)
|
||||||
|
->setPaper('a4', 'portrait')
|
||||||
|
->setOption('isRemoteEnabled', true)
|
||||||
|
->setOption('isHtml5ParserEnabled', true);
|
||||||
|
|
||||||
|
return response()->streamDownload(
|
||||||
|
function () use ($pdf) {
|
||||||
|
echo $pdf->stream();
|
||||||
|
},
|
||||||
|
'Rapor_' . $this->student->full_name . '.pdf'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function loadAssessment(): void
|
||||||
|
{
|
||||||
|
$student_id = $this->student->id;
|
||||||
|
$class_id = $this->class->id;
|
||||||
|
$semester = $this->semester;
|
||||||
|
$year_id = $this->academic_year->id;
|
||||||
|
|
||||||
|
// Assessment Mapping
|
||||||
|
$assessments = Assessment::where('semester', $this->semester)
|
||||||
|
->whereHas('teacherSubject', function($query) use ($class_id, $year_id) {
|
||||||
|
$query->where('academic_year_id', $year_id)
|
||||||
|
->where('class_id', $class_id);
|
||||||
|
})
|
||||||
|
->where('student_id', $this->student->id)
|
||||||
|
->with('teacherSubject.subject', 'student')
|
||||||
|
->get()
|
||||||
|
->map(function ($as) use ($class_id) {
|
||||||
|
$subject = $as->teacherSubject->subject ?? null;
|
||||||
|
|
||||||
|
if (!$subject) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$competencyAchievements = CompetencyAchievement::where('class_room_id', $class_id)
|
||||||
|
->where('subject_id', $subject->id)
|
||||||
|
->where('min_score', '<=', $as->score)
|
||||||
|
->where('max_score', '>=', $as->score)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
return [
|
||||||
|
"score" => $as->score,
|
||||||
|
"subject" => $subject->name,
|
||||||
|
"category" => $subject->category,
|
||||||
|
"competency_achievement" => $competencyAchievements ? $this->student->full_name . ' ' . $competencyAchievements->description : '-',
|
||||||
|
];
|
||||||
|
})
|
||||||
|
->filter() // Hapus null jika ada
|
||||||
|
->sortByDesc('subject')
|
||||||
|
->sortBy(function ($item) {
|
||||||
|
return $item['category'] === 'umum' ? 0 : 1;
|
||||||
|
})
|
||||||
|
->values()
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$this->table["assessments"]['umum'] = array_filter($assessments, function ($item) {
|
||||||
|
return $item["category"] === "umum";
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->table["assessments"]['muatan lokal'] = array_filter($assessments, function ($item) {
|
||||||
|
return $item["category"] === "muatan lokal";
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->table["assessments"]['seni'] = array_filter($assessments, function ($item) {
|
||||||
|
return $item["category"] === "seni";
|
||||||
|
});
|
||||||
|
|
||||||
|
$extracurricular = ExtracurricularAssessment::with('classStudent','extracurricular')
|
||||||
|
->where('semester', $this->semester)
|
||||||
|
->whereHas('classStudent', function($query) use ($class_id, $year_id) {
|
||||||
|
$query->where('academic_year_id', $year_id)
|
||||||
|
->where('class_room_id', $class_id)
|
||||||
|
->where('student_id', $this->student->id);
|
||||||
|
})
|
||||||
|
->get()
|
||||||
|
->map(function ($as) {
|
||||||
|
return [
|
||||||
|
"name" => $as->extracurricular->name,
|
||||||
|
"predicate" => $as->predicate,
|
||||||
|
"description" => $as->description,
|
||||||
|
];
|
||||||
|
})
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$this->table["extracurricular"] = $extracurricular;
|
||||||
|
|
||||||
|
$homeRoom = HomeRoomTeacher::with(['teacher'])
|
||||||
|
->where('class_room_id', $this->class->id)
|
||||||
|
->where('academic_year_id', $this->academic_year->id)
|
||||||
|
->firstOrFail()
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$this->home_room_teacher = $homeRoom ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function validateParameters(array $params, array $allowedParams): void
|
||||||
|
{
|
||||||
|
$validator = Validator::make($params, [
|
||||||
|
'studentId' => 'required|integer',
|
||||||
|
'classId' => 'required|integer',
|
||||||
|
'yearId' => 'required|integer',
|
||||||
|
'semester' => 'required|in:first,second',
|
||||||
|
'sakit' => 'nullable|integer|min:0',
|
||||||
|
'izin' => 'nullable|integer|min:0',
|
||||||
|
'tanpa_keterangan' => 'nullable|integer|min:0',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
throw new \Illuminate\Validation\ValidationException($validator);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($params as $key => $value) {
|
||||||
|
if (!in_array($key, $allowedParams)) {
|
||||||
|
throw new \InvalidArgumentException("Parameter {$key} tidak valid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function extractClassLetter($className): string
|
||||||
|
{
|
||||||
|
preg_match('/[A-Z]+$/i', trim($className), $matches);
|
||||||
|
return $matches[0] ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toRoman($number): string
|
||||||
|
{
|
||||||
|
$map = [
|
||||||
|
'M' => 1000,
|
||||||
|
'CM' => 900,
|
||||||
|
'D' => 500,
|
||||||
|
'CD' => 400,
|
||||||
|
'C' => 100,
|
||||||
|
'XC' => 90,
|
||||||
|
'L' => 50,
|
||||||
|
'XL' => 40,
|
||||||
|
'X' => 10,
|
||||||
|
'IX' => 9,
|
||||||
|
'V' => 5,
|
||||||
|
'IV' => 4,
|
||||||
|
'I' => 1,
|
||||||
|
];
|
||||||
|
|
||||||
|
$returnValue = '';
|
||||||
|
while ($number > 0) {
|
||||||
|
foreach ($map as $roman => $int) {
|
||||||
|
if ($number >= $int) {
|
||||||
|
$number -= $int;
|
||||||
|
$returnValue .= $roman;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,7 +9,8 @@ class ExtracurricularAssessment extends Model
|
|||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'class_student_id',
|
'class_student_id',
|
||||||
'extracurricular_id',
|
'extracurricular_id',
|
||||||
'score',
|
'predicate',
|
||||||
|
'description',
|
||||||
'semester',
|
'semester',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
66
app/Policies/AcademicYearPolicy.php
Normal file
66
app/Policies/AcademicYearPolicy.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Policies;
|
||||||
|
|
||||||
|
use App\Models\AcademicYear;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Auth\Access\Response;
|
||||||
|
|
||||||
|
class AcademicYearPolicy
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view any models.
|
||||||
|
*/
|
||||||
|
public function viewAny(User $user): bool
|
||||||
|
{
|
||||||
|
return $user->can('view_any_academic::year');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view the model.
|
||||||
|
*/
|
||||||
|
public function view(User $user, AcademicYear $academicYear): bool
|
||||||
|
{
|
||||||
|
return $user->can('view_academic::year');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can create models.
|
||||||
|
*/
|
||||||
|
public function create(User $user): bool
|
||||||
|
{
|
||||||
|
return $user->can('create_academic::year');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can update the model.
|
||||||
|
*/
|
||||||
|
public function update(User $user, AcademicYear $academicYear): bool
|
||||||
|
{
|
||||||
|
return $user->can('update_academic::year');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can delete the model.
|
||||||
|
*/
|
||||||
|
public function delete(User $user, AcademicYear $academicYear): bool
|
||||||
|
{
|
||||||
|
return $user->can('delete_academic::year');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can restore the model.
|
||||||
|
*/
|
||||||
|
public function restore(User $user, AcademicYear $academicYear): bool
|
||||||
|
{
|
||||||
|
return $user->can('restore_academic::year');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can permanently delete the model.
|
||||||
|
*/
|
||||||
|
public function forceDelete(User $user, AcademicYear $academicYear): bool
|
||||||
|
{
|
||||||
|
return $user->can('force_delete_academic::year');
|
||||||
|
}
|
||||||
|
}
|
||||||
66
app/Policies/ClassStudentPolicy.php
Normal file
66
app/Policies/ClassStudentPolicy.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Policies;
|
||||||
|
|
||||||
|
use App\Models\ClassStudent;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Auth\Access\Response;
|
||||||
|
|
||||||
|
class ClassStudentPolicy
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view any models.
|
||||||
|
*/
|
||||||
|
public function viewAny(User $user): bool
|
||||||
|
{
|
||||||
|
return $user->can('view_any_class::student');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view the model.
|
||||||
|
*/
|
||||||
|
public function view(User $user, ClassStudent $classStudent): bool
|
||||||
|
{
|
||||||
|
return $user->can('view_class::student');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can create models.
|
||||||
|
*/
|
||||||
|
public function create(User $user): bool
|
||||||
|
{
|
||||||
|
return $user->can('create_class::student');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can update the model.
|
||||||
|
*/
|
||||||
|
public function update(User $user, ClassStudent $classStudent): bool
|
||||||
|
{
|
||||||
|
return $user->can('update_class::student');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can delete the model.
|
||||||
|
*/
|
||||||
|
public function delete(User $user, ClassStudent $classStudent): bool
|
||||||
|
{
|
||||||
|
return $user->can('delete_class::student');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can restore the model.
|
||||||
|
*/
|
||||||
|
public function restore(User $user, ClassStudent $classStudent): bool
|
||||||
|
{
|
||||||
|
return $user->can('restore_class::student');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can permanently delete the model.
|
||||||
|
*/
|
||||||
|
public function forceDelete(User $user, ClassStudent $classStudent): bool
|
||||||
|
{
|
||||||
|
return $user->can('force_delete_class::student');
|
||||||
|
}
|
||||||
|
}
|
||||||
66
app/Policies/ClassSubjectPolicy.php
Normal file
66
app/Policies/ClassSubjectPolicy.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Policies;
|
||||||
|
|
||||||
|
use App\Models\ClassSubject;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Auth\Access\Response;
|
||||||
|
|
||||||
|
class ClassSubjectPolicy
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view any models.
|
||||||
|
*/
|
||||||
|
public function viewAny(User $user): bool
|
||||||
|
{
|
||||||
|
return $user->can('view_any_class::subject');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view the model.
|
||||||
|
*/
|
||||||
|
public function view(User $user, ClassSubject $classSubject): bool
|
||||||
|
{
|
||||||
|
return $user->can('view_class::subject');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can create models.
|
||||||
|
*/
|
||||||
|
public function create(User $user): bool
|
||||||
|
{
|
||||||
|
return $user->can('create_class::subject');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can update the model.
|
||||||
|
*/
|
||||||
|
public function update(User $user, ClassSubject $classSubject): bool
|
||||||
|
{
|
||||||
|
return $user->can('update_class::subject');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can delete the model.
|
||||||
|
*/
|
||||||
|
public function delete(User $user, ClassSubject $classSubject): bool
|
||||||
|
{
|
||||||
|
return $user->can('delete_class::subject');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can restore the model.
|
||||||
|
*/
|
||||||
|
public function restore(User $user, ClassSubject $classSubject): bool
|
||||||
|
{
|
||||||
|
return $user->can('restore_class::subject');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can permanently delete the model.
|
||||||
|
*/
|
||||||
|
public function forceDelete(User $user, ClassSubject $classSubject): bool
|
||||||
|
{
|
||||||
|
return $user->can('force_delete_class::subject');
|
||||||
|
}
|
||||||
|
}
|
||||||
66
app/Policies/CompetencyAchievementPolicy.php
Normal file
66
app/Policies/CompetencyAchievementPolicy.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Policies;
|
||||||
|
|
||||||
|
use App\Models\CompetencyAchievement;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Auth\Access\Response;
|
||||||
|
|
||||||
|
class CompetencyAchievementPolicy
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view any models.
|
||||||
|
*/
|
||||||
|
public function viewAny(User $user): bool
|
||||||
|
{
|
||||||
|
return $user->can('view_any_competency::achievement');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view the model.
|
||||||
|
*/
|
||||||
|
public function view(User $user, CompetencyAchievement $competencyAchievement): bool
|
||||||
|
{
|
||||||
|
return $user->can('view_competency::achievement');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can create models.
|
||||||
|
*/
|
||||||
|
public function create(User $user): bool
|
||||||
|
{
|
||||||
|
return $user->can('create_competency::achievement');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can update the model.
|
||||||
|
*/
|
||||||
|
public function update(User $user, CompetencyAchievement $competencyAchievement): bool
|
||||||
|
{
|
||||||
|
return $user->can('update_competency::achievement');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can delete the model.
|
||||||
|
*/
|
||||||
|
public function delete(User $user, CompetencyAchievement $competencyAchievement): bool
|
||||||
|
{
|
||||||
|
return $user->can('delete_competency::achievement');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can restore the model.
|
||||||
|
*/
|
||||||
|
public function restore(User $user, CompetencyAchievement $competencyAchievement): bool
|
||||||
|
{
|
||||||
|
return $user->can('restore_competency::achievement');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can permanently delete the model.
|
||||||
|
*/
|
||||||
|
public function forceDelete(User $user, CompetencyAchievement $competencyAchievement): bool
|
||||||
|
{
|
||||||
|
return $user->can('force_delete_competency::achievement');
|
||||||
|
}
|
||||||
|
}
|
||||||
66
app/Policies/ExtracurricularAssessmentPolicy.php
Normal file
66
app/Policies/ExtracurricularAssessmentPolicy.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Policies;
|
||||||
|
|
||||||
|
use App\Models\ExtracurricularAssessment;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Auth\Access\Response;
|
||||||
|
|
||||||
|
class ExtracurricularAssessmentPolicy
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view any models.
|
||||||
|
*/
|
||||||
|
public function viewAny(User $user): bool
|
||||||
|
{
|
||||||
|
return $user->can('view_any_extracurricular::assessment');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view the model.
|
||||||
|
*/
|
||||||
|
public function view(User $user, ExtracurricularAssessment $extracurricularAssessment): bool
|
||||||
|
{
|
||||||
|
return $user->can('view_extracurricular::assessment');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can create models.
|
||||||
|
*/
|
||||||
|
public function create(User $user): bool
|
||||||
|
{
|
||||||
|
return $user->can('create_extracurricular::assessment');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can update the model.
|
||||||
|
*/
|
||||||
|
public function update(User $user, ExtracurricularAssessment $extracurricularAssessment): bool
|
||||||
|
{
|
||||||
|
return $user->can('update_extracurricular::assessment');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can delete the model.
|
||||||
|
*/
|
||||||
|
public function delete(User $user, ExtracurricularAssessment $extracurricularAssessment): bool
|
||||||
|
{
|
||||||
|
return $user->can('delete_extracurricular::assessment');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can restore the model.
|
||||||
|
*/
|
||||||
|
public function restore(User $user, ExtracurricularAssessment $extracurricularAssessment): bool
|
||||||
|
{
|
||||||
|
return $user->can('restore_extracurricular::assessment');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can permanently delete the model.
|
||||||
|
*/
|
||||||
|
public function forceDelete(User $user, ExtracurricularAssessment $extracurricularAssessment): bool
|
||||||
|
{
|
||||||
|
return $user->can('force_delete_extracurricular::assessment');
|
||||||
|
}
|
||||||
|
}
|
||||||
66
app/Policies/HomeRoomTeacherPolicy.php
Normal file
66
app/Policies/HomeRoomTeacherPolicy.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Policies;
|
||||||
|
|
||||||
|
use App\Models\HomeRoomTeacher;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Auth\Access\Response;
|
||||||
|
|
||||||
|
class HomeRoomTeacherPolicy
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view any models.
|
||||||
|
*/
|
||||||
|
public function viewAny(User $user): bool
|
||||||
|
{
|
||||||
|
return $user->can('view_any_home::room::teacher');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view the model.
|
||||||
|
*/
|
||||||
|
public function view(User $user, HomeRoomTeacher $homeRomeTeacher): bool
|
||||||
|
{
|
||||||
|
return $user->can('view_home::room::teacher');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can create models.
|
||||||
|
*/
|
||||||
|
public function create(User $user): bool
|
||||||
|
{
|
||||||
|
return $user->can('create_home::room::teacher');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can update the model.
|
||||||
|
*/
|
||||||
|
public function update(User $user, HomeRoomTeacher $homeRomeTeacher): bool
|
||||||
|
{
|
||||||
|
return $user->can('update_home::room::teacher');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can delete the model.
|
||||||
|
*/
|
||||||
|
public function delete(User $user, HomeRoomTeacher $homeRomeTeacher): bool
|
||||||
|
{
|
||||||
|
return $user->can('delete_home::room::teacher');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can restore the model.
|
||||||
|
*/
|
||||||
|
public function restore(User $user, HomeRoomTeacher $homeRomeTeacher): bool
|
||||||
|
{
|
||||||
|
return $user->can('restore_home::room::teacher');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can permanently delete the model.
|
||||||
|
*/
|
||||||
|
public function forceDelete(User $user, HomeRoomTeacher $homeRomeTeacher): bool
|
||||||
|
{
|
||||||
|
return $user->can('force_delete_home::room::teacher');
|
||||||
|
}
|
||||||
|
}
|
||||||
66
app/Policies/SchoolInformationPolicy.php
Normal file
66
app/Policies/SchoolInformationPolicy.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Policies;
|
||||||
|
|
||||||
|
use App\Models\SchoolInformation;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Auth\Access\Response;
|
||||||
|
|
||||||
|
class SchoolInformationPolicy
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view any models.
|
||||||
|
*/
|
||||||
|
public function viewAny(User $user): bool
|
||||||
|
{
|
||||||
|
return $user->can('page_SchoolInformation');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view the model.
|
||||||
|
*/
|
||||||
|
public function view(User $user, SchoolInformation $schoolInformation): bool
|
||||||
|
{
|
||||||
|
return $user->can('page_SchoolInformation');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can create models.
|
||||||
|
*/
|
||||||
|
public function create(User $user): bool
|
||||||
|
{
|
||||||
|
return $user->can('page_SchoolInformation');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can update the model.
|
||||||
|
*/
|
||||||
|
public function update(User $user, SchoolInformation $schoolInformation): bool
|
||||||
|
{
|
||||||
|
return $user->can('page_SchoolInformation');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can delete the model.
|
||||||
|
*/
|
||||||
|
public function delete(User $user, SchoolInformation $schoolInformation): bool
|
||||||
|
{
|
||||||
|
return $user->can('page_SchoolInformation');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can restore the model.
|
||||||
|
*/
|
||||||
|
public function restore(User $user, SchoolInformation $schoolInformation): bool
|
||||||
|
{
|
||||||
|
return $user->can('page_SchoolInformation');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can permanently delete the model.
|
||||||
|
*/
|
||||||
|
public function forceDelete(User $user, SchoolInformation $schoolInformation): bool
|
||||||
|
{
|
||||||
|
return $user->can('page_SchoolInformation');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,65 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Policies;
|
|
||||||
|
|
||||||
use App\Models\SubjectScope;
|
|
||||||
use App\Models\User;
|
|
||||||
|
|
||||||
class SubjectScopePolicy
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Determine whether the user can view any models.
|
|
||||||
*/
|
|
||||||
public function viewAny(User $user): bool
|
|
||||||
{
|
|
||||||
return $user->can('view_any_subject::scope');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine whether the user can view the model.
|
|
||||||
*/
|
|
||||||
public function view(User $user, SubjectScope $subjectScope): bool
|
|
||||||
{
|
|
||||||
return $user->can('view_subject::scope');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine whether the user can create models.
|
|
||||||
*/
|
|
||||||
public function create(User $user): bool
|
|
||||||
{
|
|
||||||
return $user->can('create_subject::scope');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine whether the user can update the model.
|
|
||||||
*/
|
|
||||||
public function update(User $user, SubjectScope $subjectScope): bool
|
|
||||||
{
|
|
||||||
return $user->can('update_subject::scope');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine whether the user can delete the model.
|
|
||||||
*/
|
|
||||||
public function delete(User $user, SubjectScope $subjectScope): bool
|
|
||||||
{
|
|
||||||
return $user->can('delete_subject::scope');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine whether the user can restore the model.
|
|
||||||
*/
|
|
||||||
public function restore(User $user, SubjectScope $subjectScope): bool
|
|
||||||
{
|
|
||||||
return $user->can('restore_subject::scope');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine whether the user can permanently delete the model.
|
|
||||||
*/
|
|
||||||
public function forceDelete(User $user, SubjectScope $subjectScope): bool
|
|
||||||
{
|
|
||||||
return $user->can('force_delete_subject::scope');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -56,6 +56,7 @@ class AdminPanelProvider extends PanelProvider
|
|||||||
])
|
])
|
||||||
->plugins([
|
->plugins([
|
||||||
\BezhanSalleh\FilamentShield\FilamentShieldPlugin::make(),
|
\BezhanSalleh\FilamentShield\FilamentShieldPlugin::make(),
|
||||||
]);
|
])
|
||||||
|
->brandName('Sistem Akademik Sekolah');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.2",
|
"php": "^8.2",
|
||||||
|
"barryvdh/laravel-dompdf": "^3.1",
|
||||||
"bezhansalleh/filament-shield": "^3.3",
|
"bezhansalleh/filament-shield": "^3.3",
|
||||||
"laravel/framework": "^11.31",
|
"laravel/framework": "^11.31",
|
||||||
"laravel/tinker": "^2.9"
|
"laravel/tinker": "^2.9"
|
||||||
|
|||||||
299
composer.lock
generated
299
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "6ab55b3e872edca1f0857b78d520564b",
|
"content-hash": "c3a721ae1c529499b996247d90300571",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "anourvalar/eloquent-serialize",
|
"name": "anourvalar/eloquent-serialize",
|
||||||
@ -72,6 +72,83 @@
|
|||||||
},
|
},
|
||||||
"time": "2025-04-06T06:54:34+00:00"
|
"time": "2025-04-06T06:54:34+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "barryvdh/laravel-dompdf",
|
||||||
|
"version": "v3.1.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/barryvdh/laravel-dompdf.git",
|
||||||
|
"reference": "8e71b99fc53bb8eb77f316c3c452dd74ab7cb25d"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/barryvdh/laravel-dompdf/zipball/8e71b99fc53bb8eb77f316c3c452dd74ab7cb25d",
|
||||||
|
"reference": "8e71b99fc53bb8eb77f316c3c452dd74ab7cb25d",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"dompdf/dompdf": "^3.0",
|
||||||
|
"illuminate/support": "^9|^10|^11|^12",
|
||||||
|
"php": "^8.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"larastan/larastan": "^2.7|^3.0",
|
||||||
|
"orchestra/testbench": "^7|^8|^9|^10",
|
||||||
|
"phpro/grumphp": "^2.5",
|
||||||
|
"squizlabs/php_codesniffer": "^3.5"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"aliases": {
|
||||||
|
"PDF": "Barryvdh\\DomPDF\\Facade\\Pdf",
|
||||||
|
"Pdf": "Barryvdh\\DomPDF\\Facade\\Pdf"
|
||||||
|
},
|
||||||
|
"providers": [
|
||||||
|
"Barryvdh\\DomPDF\\ServiceProvider"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "3.0-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Barryvdh\\DomPDF\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Barry vd. Heuvel",
|
||||||
|
"email": "barryvdh@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A DOMPDF Wrapper for Laravel",
|
||||||
|
"keywords": [
|
||||||
|
"dompdf",
|
||||||
|
"laravel",
|
||||||
|
"pdf"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/barryvdh/laravel-dompdf/issues",
|
||||||
|
"source": "https://github.com/barryvdh/laravel-dompdf/tree/v3.1.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://fruitcake.nl",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/barryvdh",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-02-13T15:07:54+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "bezhansalleh/filament-shield",
|
"name": "bezhansalleh/filament-shield",
|
||||||
"version": "3.3.5",
|
"version": "3.3.5",
|
||||||
@ -940,6 +1017,161 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-02-05T11:56:58+00:00"
|
"time": "2024-02-05T11:56:58+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "dompdf/dompdf",
|
||||||
|
"version": "v3.1.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/dompdf/dompdf.git",
|
||||||
|
"reference": "a51bd7a063a65499446919286fb18b518177155a"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/a51bd7a063a65499446919286fb18b518177155a",
|
||||||
|
"reference": "a51bd7a063a65499446919286fb18b518177155a",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"dompdf/php-font-lib": "^1.0.0",
|
||||||
|
"dompdf/php-svg-lib": "^1.0.0",
|
||||||
|
"ext-dom": "*",
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"masterminds/html5": "^2.0",
|
||||||
|
"php": "^7.1 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ext-gd": "*",
|
||||||
|
"ext-json": "*",
|
||||||
|
"ext-zip": "*",
|
||||||
|
"mockery/mockery": "^1.3",
|
||||||
|
"phpunit/phpunit": "^7.5 || ^8 || ^9 || ^10 || ^11",
|
||||||
|
"squizlabs/php_codesniffer": "^3.5",
|
||||||
|
"symfony/process": "^4.4 || ^5.4 || ^6.2 || ^7.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-gd": "Needed to process images",
|
||||||
|
"ext-gmagick": "Improves image processing performance",
|
||||||
|
"ext-imagick": "Improves image processing performance",
|
||||||
|
"ext-zlib": "Needed for pdf stream compression"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Dompdf\\": "src/"
|
||||||
|
},
|
||||||
|
"classmap": [
|
||||||
|
"lib/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"LGPL-2.1"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "The Dompdf Community",
|
||||||
|
"homepage": "https://github.com/dompdf/dompdf/blob/master/AUTHORS.md"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter",
|
||||||
|
"homepage": "https://github.com/dompdf/dompdf",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/dompdf/dompdf/issues",
|
||||||
|
"source": "https://github.com/dompdf/dompdf/tree/v3.1.0"
|
||||||
|
},
|
||||||
|
"time": "2025-01-15T14:09:04+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dompdf/php-font-lib",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/dompdf/php-font-lib.git",
|
||||||
|
"reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d",
|
||||||
|
"reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"php": "^7.1 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/phpunit-bridge": "^3 || ^4 || ^5 || ^6"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"FontLib\\": "src/FontLib"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"LGPL-2.1-or-later"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "The FontLib Community",
|
||||||
|
"homepage": "https://github.com/dompdf/php-font-lib/blob/master/AUTHORS.md"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A library to read, parse, export and make subsets of different types of font files.",
|
||||||
|
"homepage": "https://github.com/dompdf/php-font-lib",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/dompdf/php-font-lib/issues",
|
||||||
|
"source": "https://github.com/dompdf/php-font-lib/tree/1.0.1"
|
||||||
|
},
|
||||||
|
"time": "2024-12-02T14:37:59+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dompdf/php-svg-lib",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/dompdf/php-svg-lib.git",
|
||||||
|
"reference": "eb045e518185298eb6ff8d80d0d0c6b17aecd9af"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/eb045e518185298eb6ff8d80d0d0c6b17aecd9af",
|
||||||
|
"reference": "eb045e518185298eb6ff8d80d0d0c6b17aecd9af",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"php": "^7.1 || ^8.0",
|
||||||
|
"sabberworm/php-css-parser": "^8.4"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Svg\\": "src/Svg"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"LGPL-3.0-or-later"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "The SvgLib Community",
|
||||||
|
"homepage": "https://github.com/dompdf/php-svg-lib/blob/master/AUTHORS.md"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A library to read, parse and export to PDF SVG files.",
|
||||||
|
"homepage": "https://github.com/dompdf/php-svg-lib",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/dompdf/php-svg-lib/issues",
|
||||||
|
"source": "https://github.com/dompdf/php-svg-lib/tree/1.0.0"
|
||||||
|
},
|
||||||
|
"time": "2024-04-29T13:26:35+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "dragonmantank/cron-expression",
|
"name": "dragonmantank/cron-expression",
|
||||||
"version": "v3.4.0",
|
"version": "v3.4.0",
|
||||||
@ -4797,6 +5029,71 @@
|
|||||||
],
|
],
|
||||||
"time": "2025-02-25T09:09:36+00:00"
|
"time": "2025-02-25T09:09:36+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "sabberworm/php-css-parser",
|
||||||
|
"version": "v8.8.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/MyIntervals/PHP-CSS-Parser.git",
|
||||||
|
"reference": "3de493bdddfd1f051249af725c7e0d2c38fed740"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/3de493bdddfd1f051249af725c7e0d2c38fed740",
|
||||||
|
"reference": "3de493bdddfd1f051249af725c7e0d2c38fed740",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-iconv": "*",
|
||||||
|
"php": "^5.6.20 || ^7.0.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "5.7.27 || 6.5.14 || 7.5.20 || 8.5.41"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-mbstring": "for parsing UTF-8 CSS"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "9.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Sabberworm\\CSS\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Raphael Schweikert"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Oliver Klee",
|
||||||
|
"email": "github@oliverklee.de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jake Hotson",
|
||||||
|
"email": "jake.github@qzdesign.co.uk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Parser for CSS Files written in PHP",
|
||||||
|
"homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser",
|
||||||
|
"keywords": [
|
||||||
|
"css",
|
||||||
|
"parser",
|
||||||
|
"stylesheet"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues",
|
||||||
|
"source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v8.8.0"
|
||||||
|
},
|
||||||
|
"time": "2025-03-23T17:59:05+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "spatie/color",
|
"name": "spatie/color",
|
||||||
"version": "1.8.0",
|
"version": "1.8.0",
|
||||||
|
|||||||
@ -21,7 +21,7 @@ return [
|
|||||||
|
|
||||||
'super_admin' => [
|
'super_admin' => [
|
||||||
'enabled' => true,
|
'enabled' => true,
|
||||||
'name' => 'super_admin',
|
'name' => 'admin',
|
||||||
'define_via_gate' => false,
|
'define_via_gate' => false,
|
||||||
'intercept_gate' => 'before', // after
|
'intercept_gate' => 'before', // after
|
||||||
],
|
],
|
||||||
|
|||||||
@ -15,7 +15,8 @@ return new class extends Migration
|
|||||||
$table->id();
|
$table->id();
|
||||||
$table->foreignId('class_student_id')->constrained('class_students');
|
$table->foreignId('class_student_id')->constrained('class_students');
|
||||||
$table->foreignId('extracurricular_id')->constrained('extracurriculars');
|
$table->foreignId('extracurricular_id')->constrained('extracurriculars');
|
||||||
$table->float('score');
|
$table->string('predicate');
|
||||||
|
$table->text('description');
|
||||||
$table->string('semester');
|
$table->string('semester');
|
||||||
|
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('notifications', function (Blueprint $table) {
|
||||||
|
$table->uuid('id')->primary();
|
||||||
|
$table->string('type');
|
||||||
|
$table->morphs('notifiable');
|
||||||
|
$table->text('data');
|
||||||
|
$table->timestamp('read_at')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('notifications');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('imports', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->timestamp('completed_at')->nullable();
|
||||||
|
$table->string('file_name');
|
||||||
|
$table->string('file_path');
|
||||||
|
$table->string('importer');
|
||||||
|
$table->unsignedInteger('processed_rows')->default(0);
|
||||||
|
$table->unsignedInteger('total_rows');
|
||||||
|
$table->unsignedInteger('successful_rows')->default(0);
|
||||||
|
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('imports');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('exports', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->timestamp('completed_at')->nullable();
|
||||||
|
$table->string('file_disk');
|
||||||
|
$table->string('file_name')->nullable();
|
||||||
|
$table->string('exporter');
|
||||||
|
$table->unsignedInteger('processed_rows')->default(0);
|
||||||
|
$table->unsignedInteger('total_rows');
|
||||||
|
$table->unsignedInteger('successful_rows')->default(0);
|
||||||
|
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('exports');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('failed_import_rows', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->json('data');
|
||||||
|
$table->foreignId('import_id')->constrained()->cascadeOnDelete();
|
||||||
|
$table->text('validation_error')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('failed_import_rows');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -6,34 +6,45 @@ use App\Models\AcademicYear;
|
|||||||
use App\Models\ClassRoom;
|
use App\Models\ClassRoom;
|
||||||
use App\Models\ClassStudent;
|
use App\Models\ClassStudent;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
class ClassStudentSeeder extends Seeder
|
class ClassStudentSeeder extends Seeder
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Run the database seeds.
|
|
||||||
*/
|
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
// Pastikan data ClassRoom, Student, dan AcademicYear sudah ada
|
$academicYears = AcademicYear::all();
|
||||||
$classRooms = ClassRoom::all();
|
$classRooms = ClassRoom::all();
|
||||||
$students = Student::all();
|
$students = Student::all();
|
||||||
$academicYears = AcademicYear::all();
|
|
||||||
|
|
||||||
// Hanya melanjutkan jika data tersedia
|
// Pastikan ada data yang tersedia
|
||||||
if ($classRooms->isNotEmpty() && $students->isNotEmpty() && $academicYears->isNotEmpty()) {
|
if ($academicYears->isEmpty() || $classRooms->isEmpty() || $students->isEmpty()) {
|
||||||
foreach ($classRooms as $classRoom) {
|
return;
|
||||||
foreach ($students as $student) {
|
}
|
||||||
|
|
||||||
|
// Distribusikan siswa ke kelas secara merata
|
||||||
|
$studentsPerClass = ceil($students->count() / $classRooms->count());
|
||||||
|
$studentChunks = $students->chunk($studentsPerClass);
|
||||||
|
|
||||||
foreach ($academicYears as $academicYear) {
|
foreach ($academicYears as $academicYear) {
|
||||||
// Buat ClassStudent baru untuk setiap kombinasi
|
$classIndex = 0;
|
||||||
ClassStudent::create([
|
|
||||||
|
foreach ($studentChunks as $studentGroup) {
|
||||||
|
// Pastikan kita tidak melebihi jumlah kelas yang tersedia
|
||||||
|
if ($classIndex >= $classRooms->count()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$classRoom = $classRooms[$classIndex];
|
||||||
|
|
||||||
|
foreach ($studentGroup as $student) {
|
||||||
|
ClassStudent::firstOrCreate([
|
||||||
'class_room_id' => $classRoom->id,
|
'class_room_id' => $classRoom->id,
|
||||||
'student_id' => $student->id,
|
'student_id' => $student->id,
|
||||||
'academic_year_id' => $academicYear->id,
|
'academic_year_id' => $academicYear->id,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
$classIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,38 +2,55 @@
|
|||||||
|
|
||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use App\Models\ClassRoom;
|
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
|
use App\Models\User;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
|
use Spatie\Permission\Models\Role;
|
||||||
|
|
||||||
class StudentSeeder extends Seeder
|
class StudentSeeder extends Seeder
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Run the database seeds.
|
|
||||||
*/
|
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
$religions = ['islam', 'kristen', 'katolik', 'hindu', 'buddha'];
|
$religions = ['islam', 'kristen', 'katolik', 'hindu', 'buddha'];
|
||||||
|
$parentRole = Role::where('name', 'parent')->firstOrFail();
|
||||||
|
|
||||||
for ($i = 1; $i <= 20; $i++) {
|
for ($i = 1; $i <= 20; $i++) {
|
||||||
$gender = $i % 2 == 0 ? 'L' : 'P';
|
$gender = $i % 2 == 0 ? 'L' : 'P';
|
||||||
$religion = $religions[array_rand($religions)];
|
$religion = $religions[array_rand($religions)];
|
||||||
$nis = '24' . str_pad($i, 4, '0', STR_PAD_LEFT); // NIS unik, misal 240001
|
$nis = '24' . str_pad($i, 4, '0', STR_PAD_LEFT);
|
||||||
|
$birthDate = Carbon::now()->subYears(rand(15, 18))->subMonths(rand(1, 12));
|
||||||
|
$parentName = 'Orang Tua Siswa ' . $i;
|
||||||
|
$parentEmail = 'parent' . $i . '@example.com';
|
||||||
|
$parentPhone = '0813' . rand(1000000, 9999999);
|
||||||
|
|
||||||
|
$birthDateParse = Carbon::parse($birthDate);
|
||||||
|
$password = $birthDateParse->format('dmY') . $nis;
|
||||||
|
|
||||||
|
$parentUser = User::firstOrCreate(
|
||||||
|
['email' => $parentEmail],
|
||||||
|
[
|
||||||
|
'name' => $parentName,
|
||||||
|
'password' => bcrypt($password),
|
||||||
|
'phone' => $parentPhone,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$parentUser->assignRole($parentRole);
|
||||||
|
|
||||||
Student::firstOrCreate(
|
Student::firstOrCreate(
|
||||||
['nis' => $nis], // Cek berdasarkan NIS
|
['nis' => $nis],
|
||||||
[
|
[
|
||||||
'full_name' => 'Siswa ' . $i,
|
'full_name' => 'Siswa ' . $i,
|
||||||
'gender' => $gender,
|
'gender' => $gender,
|
||||||
'birth_date' => Carbon::now()->subYears(rand(15, 18))->subMonths(rand(1, 12)),
|
'birth_date' => $birthDate,
|
||||||
'birth_place' => 'Kota ' . chr(65 + rand(0, 25)),
|
'birth_place' => 'Kota ' . chr(65 + rand(0, 25)),
|
||||||
'address' => 'Jl. Contoh No.' . $i,
|
'address' => 'Jl. Contoh No.' . $i,
|
||||||
'phone' => '0812' . rand(1000000, 9999999),
|
'phone' => '0812' . rand(1000000, 9999999),
|
||||||
'parent_name' => 'Orang Tua Siswa ' . $i,
|
'parent_name' => $parentName,
|
||||||
'religion' => $religion,
|
'religion' => $religion,
|
||||||
'parent_phone' => '0813' . rand(1000000, 9999999),
|
'parent_phone' => $parentPhone,
|
||||||
|
'email' => $parentEmail,
|
||||||
'created_at' => now(),
|
'created_at' => now(),
|
||||||
'updated_at' => now(),
|
'updated_at' => now(),
|
||||||
]
|
]
|
||||||
|
|||||||
@ -51,7 +51,7 @@ class UserSeeder extends Seeder
|
|||||||
|
|
||||||
// 4. Buat role super_admin jika belum ada
|
// 4. Buat role super_admin jika belum ada
|
||||||
$role = Role::firstOrCreate([
|
$role = Role::firstOrCreate([
|
||||||
'name' => 'super_admin',
|
'name' => 'admin',
|
||||||
'guard_name' => 'web',
|
'guard_name' => 'web',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -60,6 +60,16 @@ class UserSeeder extends Seeder
|
|||||||
'guard_name' => 'web',
|
'guard_name' => 'web',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$headmaster = Role::firstOrCreate([
|
||||||
|
'name' => 'headmaster',
|
||||||
|
'guard_name' => 'web',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$parent = Role::firstOrCreate([
|
||||||
|
'name' => 'parent',
|
||||||
|
'guard_name' => 'web',
|
||||||
|
]);
|
||||||
|
|
||||||
$teacher->syncPermissions($rolePermissions);
|
$teacher->syncPermissions($rolePermissions);
|
||||||
|
|
||||||
$role->syncPermissions($rolePermissions);
|
$role->syncPermissions($rolePermissions);
|
||||||
|
|||||||
3007
package-lock.json
generated
Normal file
3007
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,6 @@
|
|||||||
"laravel-vite-plugin": "^1.2.0",
|
"laravel-vite-plugin": "^1.2.0",
|
||||||
"postcss": "^8.4.47",
|
"postcss": "^8.4.47",
|
||||||
"tailwindcss": "^3.4.13",
|
"tailwindcss": "^3.4.13",
|
||||||
"vite": "^6.0.11"
|
"vite": "^6.3.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<x-filament-panels::page >
|
<x-filament-panels::page >
|
||||||
<div class="w-full flex gap-8">
|
<div class="w-full flex gap-8">
|
||||||
{{-- Report Preview --}}
|
{{-- Report Preview --}}
|
||||||
<div class="w-full" style="font-family: 'Times New Roman', Times, serif;">
|
<div class="w-full" style="font-family: 'Times New Roman', Times, serif;" id="print">
|
||||||
<div class="text-center mb-6">
|
<div class="text-center mb-6">
|
||||||
<h2 class="text-lg font-bold uppercase">Laporan Hasil Belajar</h2>
|
<h2 class="text-lg font-bold uppercase">Laporan Hasil Belajar</h2>
|
||||||
<h3 class="text-sm font-bold uppercase">(RAPOR)</h3>
|
<h3 class="text-sm font-bold uppercase">(RAPOR)</h3>
|
||||||
@ -44,30 +44,30 @@
|
|||||||
$i = 1;
|
$i = 1;
|
||||||
@endphp
|
@endphp
|
||||||
<tbody>
|
<tbody>
|
||||||
@if(!empty($this->table['subjects']['umum']))
|
@if(!empty($this->table['assessments']['umum']))
|
||||||
@foreach($this->table['subjects']['umum'] as $subjectId => $subjectName)
|
@foreach($this->table['assessments']['umum'] as $subjects => $subject)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="border border-black text-center">{{ $i }}</td>
|
<td class="border border-black text-center">{{ $i }}</td>
|
||||||
<td class="border border-black">{{ $subjectName }}</td>
|
<td class="border border-black">{{ $subject["subject"] }}</td>
|
||||||
<td class="border border-black text-center">90</td>
|
<td class="border border-black text-center">{{ $subject["score"] }}</td>
|
||||||
<td class="border border-black">Ananda sangat memahami materi ajaran dan menunjukkan perilaku religius dalam keseharian.</td>
|
<td class="border border-black">{{ $subject["competency_achievement"] }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@php
|
@php
|
||||||
$i++;
|
$i++;
|
||||||
@endphp
|
@endphp
|
||||||
@endforeach
|
@endforeach
|
||||||
@endif
|
@endif
|
||||||
@if(!empty($this->table['subjects']['seni']))
|
@if(!empty($this->table['assessments']['seni']))
|
||||||
<tr>
|
<tr>
|
||||||
<td class="border border-black text-center">{{ $i }}</td>
|
<td class="border border-black text-center">{{ $i }}</td>
|
||||||
<td class="border border-black" colspan="3">Seni</td>
|
<td class="border border-black" colspan="3">Seni</td>
|
||||||
</tr>
|
</tr>
|
||||||
@foreach($this->table['subjects']['seni'] as $subjectId => $subjectName)
|
@foreach($this->table['assessments']['seni'] as $subjects => $subject)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="border border-black text-center">a</td>
|
<td class="border border-black text-center">a</td>
|
||||||
<td class="border border-black">{{ $subjectName }}</td>
|
<td class="border border-black">{{ $subject["subject"] }}</td>
|
||||||
<td class="border border-black text-center">90</td>
|
<td class="border border-black text-center">{{ $subject["score"] }}</td>
|
||||||
<td class="border border-black">Ananda sangat memahami materi ajaran dan menunjukkan perilaku religius dalam keseharian.</td>
|
<td class="border border-black">{{ $subject["competency_achievement"] }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@php
|
@php
|
||||||
$i++;
|
$i++;
|
||||||
@ -90,13 +90,13 @@
|
|||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
@if(!empty($this->table['subjects']['muatan lokal']))
|
@if(!empty($this->table['assessments']['muatan lokal']))
|
||||||
@foreach($this->table['subjects']['muatan lokal'] as $subjectId => $subjectName)
|
@foreach($this->table['assessments']['muatan lokal'] as $subjects => $subject)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="border border-black text-center">{{ $i }}</td>
|
<td class="border border-black text-center">{{ $i }}</td>
|
||||||
<td class="border border-black">{{ $subjectName }}</td>
|
<td class="border border-black">{{ $subject["subject"] }}</td>
|
||||||
<td class="border border-black text-center">90</td>
|
<td class="border border-black text-center">{{ $subject["score"] }}</td>
|
||||||
<td class="border border-black">Ananda sangat memahami materi ajaran dan menunjukkan perilaku religius dalam keseharian.</td>
|
<td class="border border-black">{{ $subject["competency_achievement"] }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@php
|
@php
|
||||||
$i++;
|
$i++;
|
||||||
@ -116,28 +116,47 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
|
@php
|
||||||
|
$i = 1;
|
||||||
|
@endphp
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@if(!empty($this->table["extracurricular"]))
|
||||||
|
|
||||||
|
@foreach($this->table['extracurricular'] as $subjects => $subject)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="border border-black">1</td>
|
<td class="border border-black text-center">{{ $i }}</td>
|
||||||
<td class="border border-black">Pramuka</td>
|
<td class="border border-black">{{ $subject["name"] }}</td>
|
||||||
<td class="border border-black text-center">A</td>
|
<td class="border border-black text-center">{{ $subject["predicate"] }}</td>
|
||||||
<td class="border border-black">Sangat Berkembang</td>
|
<td class="border border-black">{{ $subject["description"] }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@php
|
||||||
|
$i++;
|
||||||
|
@endphp
|
||||||
|
@endforeach
|
||||||
|
@else
|
||||||
|
<tr>
|
||||||
|
<td class="border border-black"></td>
|
||||||
|
<td class="border border-black"></td>
|
||||||
|
<td class="border border-black text-center"></td>
|
||||||
|
<td class="border border-black"></td>
|
||||||
|
</tr>
|
||||||
|
@endif
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
{{-- Table Ketidakhadiran --}}
|
||||||
<table class="border text-sm mt-6">
|
<table class="border text-sm mt-6">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="border text-center" colspan="2">Ketidakhadiran</td>
|
<td class="border text-center" colspan="2">Ketidakhadiran</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Sakit</td><td>: 2 hari</td>
|
<td>Sakit</td><td>: {{ $sakit }} hari</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Izin</td><td>: 1 hari</td>
|
<td>Izin</td><td>: {{ $izin }} hari</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Tanpa Keterangan</td><td>: 0 hari</td>
|
<td>Tanpa Keterangan</td><td>: {{ $tanpa_keterangan }} hari</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
@ -154,8 +173,8 @@
|
|||||||
|
|
||||||
Depok, {{ \Carbon\Carbon::now()->translatedFormat('d F Y') }} <br>
|
Depok, {{ \Carbon\Carbon::now()->translatedFormat('d F Y') }} <br>
|
||||||
Wali Kelas {{ $this->class_name ?? "-" }} <br><br><br>
|
Wali Kelas {{ $this->class_name ?? "-" }} <br><br><br>
|
||||||
<strong>Siti Mawarni, S.Pd</strong><br>
|
<strong>{{ $home_room_teacher["teacher"]["name"] ?? '-' }}</strong><br>
|
||||||
NIP. 197502021990121001
|
NIP. {{ $home_room_teacher["teacher"]["nip"] ?? '-' }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -173,21 +192,51 @@
|
|||||||
<div>
|
<div>
|
||||||
<h4 class="font-semibold mb-1">Input Absensi</h4>
|
<h4 class="font-semibold mb-1">Input Absensi</h4>
|
||||||
<label class="block text-sm">Sakit:</label>
|
<label class="block text-sm">Sakit:</label>
|
||||||
<input type="number" class="w-full rounded border-gray-300" placeholder="0">
|
<input
|
||||||
|
type="number"
|
||||||
|
wire:model="sakit"
|
||||||
|
class="w-full rounded border-gray-300"
|
||||||
|
placeholder="0"
|
||||||
|
min="0">
|
||||||
|
|
||||||
<label class="block text-sm mt-2">Izin:</label>
|
<label class="block text-sm mt-2">Izin:</label>
|
||||||
<input type="number" class="w-full rounded border-gray-300" placeholder="0">
|
<input
|
||||||
|
type="number"
|
||||||
|
wire:model="izin"
|
||||||
|
class="w-full rounded border-gray-300"
|
||||||
|
placeholder="0"
|
||||||
|
min="0">
|
||||||
|
|
||||||
<label class="block text-sm mt-2">Tanpa Keterangan:</label>
|
<label class="block text-sm mt-2">Tanpa Keterangan:</label>
|
||||||
<input type="number" class="w-full rounded border-gray-300" placeholder="0">
|
<input
|
||||||
|
type="number"
|
||||||
|
wire:model="tanpa_keterangan"
|
||||||
|
class="w-full rounded border-gray-300"
|
||||||
|
placeholder="0"
|
||||||
|
min="0">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<x-filament::button
|
||||||
<h4 class="font-semibold mb-1">Catatan Wali Kelas</h4>
|
wire:click="saveAttendance"
|
||||||
<textarea class="w-full rounded border-gray-300" rows="4" placeholder="Tulis catatan di sini..."></textarea>
|
class="w-full">
|
||||||
</div>
|
Simpan
|
||||||
|
</x-filament::button>
|
||||||
|
|
||||||
<x-filament::button class="w-full">Simpan</x-filament::button>
|
<x-filament::button
|
||||||
|
tag="a"
|
||||||
|
href="{{ route('report.pdf', [
|
||||||
|
'studentId' => $this->student->id,
|
||||||
|
'classId' => $this->class->id,
|
||||||
|
'yearId' => $this->academic_year->id,
|
||||||
|
'semester' => $this->semester,
|
||||||
|
'sakit' => $this->sakit,
|
||||||
|
'izin' => $this->izin,
|
||||||
|
'tanpa_keterangan' => $this->tanpa_keterangan,
|
||||||
|
]) }}"
|
||||||
|
target="_blank"
|
||||||
|
class="w-full">
|
||||||
|
Download PDF
|
||||||
|
</x-filament::button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
254
resources/views/print/report.blade.php
Normal file
254
resources/views/print/report.blade.php
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="id">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Laporan Hasil Belajar</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Times New Roman', Times, serif;
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uppercase {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-full {
|
||||||
|
width: 256px;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table, th, td {
|
||||||
|
border: 1px solid #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
td, th {
|
||||||
|
padding: 6px;
|
||||||
|
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-border {
|
||||||
|
border: none !important;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-section {
|
||||||
|
margin-top: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-50 {
|
||||||
|
width: 48%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt-20 {
|
||||||
|
margin-top: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-4 {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.underline {
|
||||||
|
display: inline-block;
|
||||||
|
border-bottom: 1px solid #000;
|
||||||
|
width: 200px;
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="text-center mb-4">
|
||||||
|
<h2 class="uppercase">Laporan Hasil Belajar</h2>
|
||||||
|
<h3 class="uppercase">(RAPOR)</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="no-border">
|
||||||
|
<tr class="no-border">
|
||||||
|
<td class="no-border">Nama Peserta Didik</td>
|
||||||
|
<td class="no-border">: {{ $student->full_name }}</td>
|
||||||
|
<td class="no-border">Kelas</td>
|
||||||
|
<td class="no-border">: {{ $class_name }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="no-border">
|
||||||
|
<td class="no-border">NISN/NIS</td>
|
||||||
|
<td class="no-border">: {{ $student->nisn }} / {{ $student->nis }}</td>
|
||||||
|
<td class="no-border">Fase</td>
|
||||||
|
<td class="no-border">: -</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="no-border">
|
||||||
|
<td class="no-border">Sekolah</td>
|
||||||
|
<td class="no-border">: {{ $school_information->school_name }}</td>
|
||||||
|
<td class="no-border">Semester</td>
|
||||||
|
<td class="no-border">: {{ $semester === 'first' ? "I" : "II"}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="no-border">
|
||||||
|
<td class="no-border">Alamat</td>
|
||||||
|
<td class="no-border">: {{ $school_information->address }}</td>
|
||||||
|
<td class="no-border">Tahun Ajaran</td>
|
||||||
|
<td class="no-border">: {{ $academic_year->name }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
@php
|
||||||
|
$i = 1;
|
||||||
|
@endphp
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 2rem">No</th>
|
||||||
|
<th style="width: 185px">Muatan Pelajaran</th>
|
||||||
|
<th style="width: 100px" class="text-center">Nilai Akhir</th>
|
||||||
|
<th>Capaian Kompetensi</th>
|
||||||
|
</tr>
|
||||||
|
@if(!empty($table['assessments']['umum']))
|
||||||
|
@foreach($table['assessments']['umum'] as $subjects => $subject)
|
||||||
|
<tr>
|
||||||
|
<td>{{ $i }}</td>
|
||||||
|
<td>{{ $subject["subject"] }}</td>
|
||||||
|
<td class="text-center">{{ $subject["score"] }}</td>
|
||||||
|
<td>{{ $subject["competency_achievement"] }}</td>
|
||||||
|
</tr>
|
||||||
|
@php
|
||||||
|
$i++;
|
||||||
|
@endphp
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if(!empty($table['assessments']['seni']))
|
||||||
|
<tr>
|
||||||
|
<td>{{ $i }}</td>
|
||||||
|
<td colspan="3">Seni</td>
|
||||||
|
</tr>
|
||||||
|
@php $charIndex = 0; @endphp
|
||||||
|
@foreach($table['assessments']['seni'] as $subjects => $subject)
|
||||||
|
<tr>
|
||||||
|
<td>{{ chr(97 + $charIndex) }}</td>
|
||||||
|
<td>{{ $subject["subject"] }}</td>
|
||||||
|
<td class="text-center">{{ $subject["score"] }}</td>
|
||||||
|
<td>{{ $subject["competency_achievement"] }}</td>
|
||||||
|
</tr>
|
||||||
|
@php
|
||||||
|
$i++;
|
||||||
|
@endphp
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<br><strong>Muatan Lokal</strong>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 2rem">No</th>
|
||||||
|
<th style="width: 185px">Muatan Pelajaran</th>
|
||||||
|
<th style="width: 100px">Nilai Akhir</th>
|
||||||
|
<th>Capaian Kompetensi</th>
|
||||||
|
</tr>
|
||||||
|
@if(!empty($table['assessments']['muatan lokal']))
|
||||||
|
@foreach($table['assessments']['muatan lokal'] as $subjects => $subject)
|
||||||
|
<tr>
|
||||||
|
<td>{{ $i }}</td>
|
||||||
|
<td>{{ $subject["subject"] }}</td>
|
||||||
|
<td class="text-center">{{ $subject["score"] }}</td>
|
||||||
|
<td>{{ $subject["competency_achievement"] }}</td>
|
||||||
|
</tr>
|
||||||
|
@php
|
||||||
|
$i++;
|
||||||
|
@endphp
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 2rem">No</th>
|
||||||
|
<th style="width: 185px">Ekstrakurikuler</th>
|
||||||
|
<th style="width: 100px">Predikat</th>
|
||||||
|
<th>Keterangan</th>
|
||||||
|
</tr>
|
||||||
|
@php
|
||||||
|
$i = 1;
|
||||||
|
@endphp
|
||||||
|
@if(!empty($table["extracurricular"]))
|
||||||
|
|
||||||
|
@foreach($table['extracurricular'] as $subjects => $subject)
|
||||||
|
<tr>
|
||||||
|
<td class=>{{ $i }}</td>
|
||||||
|
<td class=>{{ $subject["name"] }}</td>
|
||||||
|
<td class='text-center'>{{ $subject["predicate"] }}</td>
|
||||||
|
<td class=>{{ $subject["description"] }}</td>
|
||||||
|
</tr>
|
||||||
|
@php
|
||||||
|
$i++;
|
||||||
|
@endphp
|
||||||
|
@endforeach
|
||||||
|
@else
|
||||||
|
<tr>
|
||||||
|
<td class=></td>
|
||||||
|
<td class=></td>
|
||||||
|
<td class=></td>
|
||||||
|
<td class=></td>
|
||||||
|
</tr>
|
||||||
|
@endif
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<table class="no-full">
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" style="text-align: center">
|
||||||
|
Ketidakhadiran
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr><td>Sakit</td><td>: {{ $sakit ?? 0 }} hari</td></tr>
|
||||||
|
<tr><td>Izin</td><td>: {{ $izin ?? 0 }} hari</td></tr>
|
||||||
|
<tr><td>Tanpa Keterangan</td><td>: {{ $tanpa_keterangan ?? 0 }} hari</td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<table class="no-border" style="margin-top: 60px;">
|
||||||
|
<tr class="no-border">
|
||||||
|
<td class="no-border" style="text-align: center;">
|
||||||
|
Orang Tua / Wali<br><br><br><br>
|
||||||
|
<span class="underline"></span>
|
||||||
|
</td>
|
||||||
|
<td class="no-border" style="text-align: center;">
|
||||||
|
@php
|
||||||
|
\Carbon\Carbon::setLocale('id');
|
||||||
|
@endphp
|
||||||
|
Depok, {{ \Carbon\Carbon::now()->translatedFormat('d F Y') }}<br>
|
||||||
|
Wali Kelas {{ $class_name }}<br><br><br>
|
||||||
|
<strong>{{ $home_room_teacher["teacher"]["name"] ?? '-' }}</strong><br>
|
||||||
|
NIP. {{ $home_room_teacher["teacher"]["nip"] ?? '-' }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="text-center mt-20">
|
||||||
|
Mengetahui,<br>
|
||||||
|
Kepala Sekolah<br><br><br>
|
||||||
|
<strong>{{ $school_information->headmaster_name }}</strong><br>
|
||||||
|
NIP: {{ $school_information->headmaster_nip }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -1,7 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
use App\Http\Controllers\ReportPDFController;
|
||||||
|
|
||||||
Route::get('/', function () {
|
Route::get('/', function () {
|
||||||
return view('welcome');
|
return view('welcome');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Route::get('/report-pdf', [ReportPDFController::class, 'reportPDF'])->name('report.pdf');
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user