310 lines
12 KiB
PHP

<?php
namespace App\Filament\Resources\AssessmentResource\Pages;
use App\Filament\Resources\AssessmentResource;
use App\Models\Assessment;
use App\Models\AssessmentLearningObjective;
use App\Models\Attendances;
use App\Models\ClassStudent;
use App\Models\HomeRoomTeacher;
use App\Models\LearningObjective;
use Filament\Actions;
use Filament\Forms\Components\Select;
use Filament\Resources\Pages\page;
use App\Models\TeacherSubject;
use Filament\Forms;
use Filament\Notifications\Notification;
use Illuminate\Contracts\Support\Htmlable;
class MultipleAssessments extends page
{
protected static string $resource = AssessmentResource::class;
protected static string $view = 'filament.resources.assessment-resource.pages.multiple-assessment';
public function getTitle(): string | Htmlable
{
return __('Tambah Penilaian');
}
use Forms\Concerns\InteractsWithForms;
public ?array $data = [];
public ?int $teacherSubjectId = null;
public $teacherSubject;
public array $students = [];
public $semester = 'first';
public $learningObjectivesList = [];
public function mount(): void
{
$this->form->fill();
}
public function loadData($subject, $class): void
{
$this->learningObjectivesList = LearningObjective::with(["subject", "class"])
->where('subject_id', $subject)
->where('class_room_id', $class)
->get()
->pluck("description", "id")
->toArray();
}
protected function getFormSchema(): array
{
return [
Forms\Components\Grid::make(2)
->schema([
Select::make('teacherSubjectId')
->label('Guru per-Mapel')
->required()
->options(function () {
$user = auth()->user();
$query = TeacherSubject::with(['teacher', 'subject', 'class', 'academicYear']);
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()
->live()
->afterStateUpdated(function ($state) {
$this->teacherSubjectId = $state;
$this->loadStudents();
}),
Forms\Components\Select::make('semester')
->label('Semester')
->required()
->default('first')
->options([
'first' => 'Ganjil',
'second' => 'Genap'
])
->live()
->afterStateUpdated(function ($state) {
$this->semester = $state;
$this->loadStudents();
}),
]),
];
}
public function loadStudents(): void
{
if (!$this->teacherSubjectId) {
$this->students = [];
return;
}
$this->teacherSubject = TeacherSubject::with(['subject','class','academicYear','teacher'])
->where('id', $this->teacherSubjectId)
->firstOrFail();
$this->loadData($this->teacherSubject->subject->id, $this->teacherSubject->class->id);
$classStudents = ClassStudent::where('class_room_id', $this->teacherSubject->class_id)
->where('academic_year_id', $this->teacherSubject->academic_year_id)
->with('student')
->get();
$isSubjectReligion = $this->teacherSubject->subject->is_religious;
$subjectName = strtolower($this->teacherSubject->subject->name);
$result = [];
foreach ($classStudents as $classStudent) {
$student = $classStudent->student;
if (!$student) continue; // Jaga-jaga kalau relasi student-nya null
$existingAssessment = Assessment::where('student_id', $student->id)
->where('teacher_subject_id', $this->teacherSubjectId)
->where('semester', $this->semester)
->first();
if ($isSubjectReligion) {
$studentReligion = strtolower($student->religion);
if (!str_contains($subjectName, $studentReligion)) {
continue; // Skip kalau agama tidak cocok
}
}
// Ambil tujuan pembelajaran tertinggi dari tabel assessment_learning_objectives
$highestObjectives = AssessmentLearningObjective::where('student_id', $student->id)
->where('teacher_subject_id', $this->teacherSubjectId)
->where('type', 'highest')
->pluck('learning_objective_id')
->toArray();
// Ambil tujuan pembelajaran lebih rendah dari tabel assessment_learning_objectives
$lowerObjectives = AssessmentLearningObjective::where('student_id', $student->id)
->where('teacher_subject_id', $this->teacherSubjectId)
->where('type', 'lower')
->pluck('learning_objective_id')
->toArray();
$result[] = [
'id' => $student->id,
'name' => $student->full_name,
'nis' => $student->nis,
'nisn' => $student->nisn,
'gender' => $student->gender,
'birth_date' => $student->birth_date,
'score' => $existingAssessment ? $existingAssessment->score : 0,
// 'learning_objectives' => $existingAssessment && is_array($existingAssessment->learning_objectives)
// ? $existingAssessment->learning_objectives
// : [],
// 'learning_objectives_lower' => $existingAssessment && is_array($existingAssessment->learning_objectives_lower)
// ? $existingAssessment->learning_objectives_lower
// : [],
'learning_objectives' => $highestObjectives,
'learning_objectives_lower' => $lowerObjectives,
];
}
$this->students = $result;
}
public function addLearningObjective(int $studentIndex, string $type = "highest"): void
{
if($type === "lower") {
if (!isset($this->students[$studentIndex]['learning_objectives_lower'])) {
$this->students[$studentIndex]['learning_objectives_lower'] = [];
}
$this->students[$studentIndex]['learning_objectives_lower'][] = null;
} else {
if (!isset($this->students[$studentIndex]['learning_objectives'])) {
$this->students[$studentIndex]['learning_objectives'] = [];
}
$this->students[$studentIndex]['learning_objectives'][] = null;
}
}
public function removeLearningObjective(int $studentIndex, int $objectiveIndex, string $type = "highest"): void
{
if ($type === "lower") {
if (isset($this->students[$studentIndex]['learning_objectives_lower']) && is_array($this->students[$studentIndex]['learning_objectives_lower'])) {
// Check if the specific objectiveIndex exists within the array
// This will be true for null values too, which is what we want for removal
if (array_key_exists($objectiveIndex, $this->students[$studentIndex]['learning_objectives_lower'])) {
unset($this->students[$studentIndex]['learning_objectives_lower'][$objectiveIndex]);
// Reindex the array to prevent gaps in keys, which can cause issues with Livewire
$this->students[$studentIndex]['learning_objectives_lower'] = array_values($this->students[$studentIndex]['learning_objectives_lower']);
}
}
} else {
if (isset($this->students[$studentIndex]['learning_objectives']) && is_array($this->students[$studentIndex]['learning_objectives'])) {
// Check if the specific objectiveIndex exists within the array
// This will be true for null values too, which is what we want for removal
if (array_key_exists($objectiveIndex, $this->students[$studentIndex]['learning_objectives'])) {
unset($this->students[$studentIndex]['learning_objectives'][$objectiveIndex]);
// Reindex the array to prevent gaps in keys, which can cause issues with Livewire
$this->students[$studentIndex]['learning_objectives'] = array_values($this->students[$studentIndex]['learning_objectives']);
}
}
}
}
public function submit(): void
{
if (!$this->teacherSubjectId || empty($this->students)) {
Notification::make()
->title('Error')
->body('Pilih guru per-mapel dan masukkan nilai siswa.')
->danger()
->send();
return;
}
foreach ($this->students as $student) {
if (isset($student['score']) || !empty(array_filter($student['learning_objectives'] ?? [])) || !empty(array_filter($student['learning_objectives_lower'] ?? []))) {
Assessment::updateOrCreate(
[
'student_id' => $student['id'],
'teacher_subject_id' => $this->teacherSubjectId,
'semester' => $this->semester,
],
[
'score' => $student['score'] ?? 0,
]
);
}
AssessmentLearningObjective::where('student_id', $student['id'])
->where('teacher_subject_id', $this->teacherSubjectId)
->where('type', 'highest')
->delete();
if (!empty($student['learning_objectives'])) {
foreach (array_filter($student['learning_objectives']) as $loId) {
AssessmentLearningObjective::create([
'student_id' => $student['id'],
'teacher_subject_id' => $this->teacherSubjectId,
'learning_objective_id' => $loId,
'type' => 'highest',
]);
}
}
AssessmentLearningObjective::where('student_id', $student['id'])
->where('teacher_subject_id', $this->teacherSubjectId)
->where('type', 'lower')
->delete();
if (!empty($student['learning_objectives_lower'])) {
foreach (array_filter($student['learning_objectives_lower']) as $loId) { // Filter nulls
AssessmentLearningObjective::create([
'student_id' => $student['id'],
'teacher_subject_id' => $this->teacherSubjectId,
'learning_objective_id' => $loId,
'type' => 'lower',
]);
}
}
}
Notification::make()
->title('Berhasil')
->body('Penilaian dan Tujuan Pembelajaran berhasil disimpan.')
->success()
->send();
}
protected function getHeaderActions(): array
{
return [
Actions\Action::make('back')
->label('Kembali ke halaman assessment')
->url(static::getResource()::getUrl('index')),
];
}
}