230 lines
7.5 KiB
PHP
230 lines
7.5 KiB
PHP
<?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;
|
|
}
|
|
}
|