119 lines
4.4 KiB
PHP
119 lines
4.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Leaderboard;
|
|
use App\Models\Kelas;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class LeaderboardController extends Controller
|
|
{
|
|
private function hitungExpSiswa(\App\Models\Siswa $s, Carbon $now): int
|
|
{
|
|
// ── 1. EXP dari challenge ─────────────────────────────────────────
|
|
$expChallenge = 0;
|
|
$pesertaList = DB::table('peserta_challenges')
|
|
->where('id_siswa', $s->id_siswa)
|
|
->get();
|
|
|
|
foreach ($pesertaList as $peserta) {
|
|
$jawaban = json_decode($peserta->jawaban, true) ?? [];
|
|
$soalList = DB::table('soal_challenge')
|
|
->where('id_challenge', $peserta->id_challenge)
|
|
->get();
|
|
|
|
foreach ($soalList as $soal) {
|
|
$jwb = $jawaban[$soal->id_soal] ?? null;
|
|
if ($jwb && strtoupper($jwb) === strtoupper($soal->jawaban_benar)) {
|
|
$expChallenge += 1; // +1 per soal benar
|
|
}
|
|
}
|
|
}
|
|
|
|
// ── 2. EXP dari tugas ─────────────────────────────────────────────
|
|
$semuaTugasIdKelas = DB::table('tugas')
|
|
->join('mengajars', 'tugas.id_mengajar', '=', 'mengajars.id_mengajar')
|
|
->where('mengajars.id_kelas', $s->id_kelas)
|
|
->select('tugas.id_tugas', 'tugas.deadline')
|
|
->get();
|
|
|
|
$expTugas = 0;
|
|
foreach ($semuaTugasIdKelas as $tugas) {
|
|
$deadline = Carbon::parse($tugas->deadline);
|
|
$pengumpulan = DB::table('pengumpulan_tugas')
|
|
->where('id_tugas', $tugas->id_tugas)
|
|
->where('id_siswa', $s->id_siswa)
|
|
->first();
|
|
|
|
if ($pengumpulan && $pengumpulan->lampiran_tugas !== null) {
|
|
$tanggalSubmit = Carbon::parse($pengumpulan->tanggal_submit);
|
|
|
|
if ($tanggalSubmit->lessThanOrEqualTo($deadline)) {
|
|
$expTugas += 10; // Tepat waktu → +10
|
|
} else {
|
|
$hariTerlambat = $deadline->diffInDays($tanggalSubmit); // ← dibalik
|
|
|
|
if ($hariTerlambat <= 1) {
|
|
$expTugas += 5; // Terlambat ≤ 1 hari → +5
|
|
} elseif ($hariTerlambat <= 3) {
|
|
$expTugas += 1; // Terlambat 2-3 hari → +3
|
|
} else {
|
|
$expTugas -= 5; // Lewat grace period > 3 hari → dianggap tidak kumpul
|
|
}
|
|
}
|
|
} elseif ($now->greaterThan($deadline)) {
|
|
// Tidak kumpul sama sekali & deadline lewat → -5
|
|
$expTugas -= 5;
|
|
}
|
|
}
|
|
|
|
return max(0, $expChallenge + $expTugas);
|
|
}
|
|
|
|
public function index(Request $request)
|
|
{
|
|
$now = Carbon::now();
|
|
$semester = $request->input('semester', $now->month >= 7 ? '1' : '2');
|
|
$tahunAjaran = $request->input('tahun_ajaran', $now->month >= 7
|
|
? $now->year . '/' . ($now->year + 1)
|
|
: ($now->year - 1) . '/' . $now->year);
|
|
$idKelas = $request->input('id_kelas');
|
|
|
|
$kelasList = Kelas::orderBy('tingkat')->orderBy('nama_kelas')->get();
|
|
|
|
$tahunList = [];
|
|
for ($y = $now->year; $y >= $now->year - 4; $y--) {
|
|
$tahunList[] = $y . '/' . ($y + 1);
|
|
}
|
|
|
|
$query = \App\Models\Siswa::with('kelas');
|
|
if ($idKelas) {
|
|
$query->where('id_kelas', $idKelas);
|
|
}
|
|
$semuaSiswa = $query->get();
|
|
|
|
$leaderboard = $semuaSiswa->map(function ($s) use ($now) {
|
|
return [
|
|
'id_siswa' => $s->id_siswa,
|
|
'nama' => $s->nama,
|
|
'nisn' => $s->nisn,
|
|
'foto_profil' => $s->foto_profil,
|
|
'nama_kelas' => $s->kelas->nama_kelas ?? '-',
|
|
'exp' => $this->hitungExpSiswa($s, $now),
|
|
];
|
|
})
|
|
->sortByDesc('exp')
|
|
->values()
|
|
->map(function ($item, $i) {
|
|
$item['ranking'] = $i + 1;
|
|
return $item;
|
|
});
|
|
|
|
return view('admin.leaderboard.index', compact(
|
|
'leaderboard', 'kelasList', 'semester', 'tahunAjaran', 'idKelas', 'tahunList'
|
|
));
|
|
}
|
|
} |