MIF_E31211891/app/Http/Controllers/SidangController.php

552 lines
26 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Exports\SidangExport;
use App\Models\Pengajuan;
use App\Models\SeminarJadwal;
use App\Models\SettingSidang;
use App\Models\Sidang;
use App\Models\SidangJadwal;
use App\Models\SidangTempat;
use App\Models\SidangWaktu;
use App\Models\User;
use Carbon\Carbon;
use DateTime;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Maatwebsite\Excel\Facades\Excel;
use Barryvdh\DomPDF\Facade\Pdf as PDF;
class SidangController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
if (Auth::User()->role == 'Admin') {
// Filter Tahun
$tahuns = SidangJadwal::selectRaw('YEAR(tanggal_sidang) as year')->groupBy('year')->pluck('year');
$tahun = $request->tahun;
// Filter Jadwal
$filter = $request->jadwal;
$today = Carbon::today();
// Tangani filter tahun
$sidangJadwals = SidangJadwal::whereIn(SidangJadwal::raw('YEAR(tanggal_sidang)'), $tahuns)->when($tahun, function ($query, $tahun) {
return $query->whereYear('tanggal_sidang', $tahun);
});
// Tangani filter dropdown
if ($filter == 'hari') {
$sidangJadwals->whereDate('tanggal_sidang', $today);
} elseif ($filter == 'minggu') {
$startOfWeek = $today->startOfWeek();
$endOfWeek = $today->endOfWeek();
$sidangJadwals->whereBetween('tanggal_sidang', [$startOfWeek, $endOfWeek]);
} elseif ($filter == 'bulan') {
$sidangJadwals->whereYear('tanggal_sidang', $today->year)
->whereMonth('tanggal_sidang', $today->month);
}
// Dapatkan data sidang jadwal
$sidangJadwals = $sidangJadwals->get();
$pengajuans = Pengajuan::all();
$mahasiswas = User::where('role', 'mahasiswa')->get();
$dosenPembimbings = User::where('role', 'Dosen')->get();
$sidangs = Sidang::all();
$sidangTempats = SidangTempat::all();
$sidangWaktus = SidangWaktu::all();
$showResetButton = $sidangJadwals->isNotEmpty();
return view('sidang', compact('tahun', 'tahuns', 'sidangJadwals', 'pengajuans', 'mahasiswas', 'dosenPembimbings', 'sidangs', 'sidangTempats', 'sidangWaktus', 'showResetButton'));
} elseif (Auth::user()->role == 'Dosen') {
$user_id = Auth::user()->id;
// Filter Tahun
$tahuns = SidangJadwal::selectRaw('YEAR(tanggal_sidang) as year')->groupBy('year')->pluck('year');
$tahun = $request->tahun;
// Filter Jadwal
$filter = $request->jadwal;
$today = Carbon::today();
// Tangani filter tahun
$sidangJadwals = SidangJadwal::where(function ($query) use ($user_id) {
$query->where('id_dosen_pembimbing', $user_id)
->orWhere('id_dosen_panelis_1', $user_id)
->orWhere('id_dosen_panelis_2', $user_id);
})
->whereIn(SidangJadwal::raw('YEAR(tanggal_sidang)'), $tahuns)
->when($tahun, function ($query, $tahun) {
return $query->whereYear('tanggal_sidang', $tahun);
});
// Tangani filter dropdown
if ($filter == 'hari') {
$sidangJadwals->whereDate('tanggal_sidang', $today);
} elseif ($filter == 'minggu') {
$startOfWeek = $today->startOfWeek();
$endOfWeek = $today->endOfWeek();
$sidangJadwals->whereBetween('tanggal_sidang', [$startOfWeek, $endOfWeek]);
} elseif ($filter == 'bulan') {
$sidangJadwals->whereYear('tanggal_sidang', $today->year)
->whereMonth('tanggal_sidang', $today->month);
}
// Dapatkan data sidang jadwal
$sidangJadwals = $sidangJadwals->get();
return view('sidang', compact('tahun', 'tahuns', 'sidangJadwals'));
} elseif (Auth::user()->role == 'Mahasiswa') {
$user_id = Auth::user()->id;
$sidangJadwals = SidangJadwal::where('id_mahasiswa', $user_id)
->get();
return view('sidang', compact('sidangJadwals'));
}
return view('sidang');
}
function generateJadwal(Request $request, $sidang = null, $tglMulaiSidang = null, $waktuSidang = null, $tempatSidang = null)
{
// Ambil pengaturan seminar proposal
$settingSidang = SettingSidang::first();
// Ambil waktu mulai sidang
$tglMulaiSidang = ($tglMulaiSidang == null) ? $settingSidang->tgl_mulai_sidang : $tglMulaiSidang;
// Ambil tanggal akhir sidang
$tglAkhirSidang = $settingSidang->tgl_akhir_sidang;
// Ambil data seminar proposal yang belum terjadwal
$sidangBelumTerjadwal = Sidang::whereDoesntHave('sidangJadwal')->get();
// Lakukan looping untuk setiap seminar proposal yang belum terjadwal
foreach ($sidangBelumTerjadwal as $sidang) {
// Ambil data mahasiswa, pengajuan, dan dosen pembimbing
$mahasiswa = $sidang->mahasiswa;
$pengajuan = $sidang->pengajuan;
$dosenPembimbing = $pengajuan->dosenPembimbing;
// Lakukan looping untuk menentukan waktu, tempat, dan tanggal yang tersedia
do {
// Ambil data waktu seminar proposal
$waktuSidang = ($waktuSidang == null) ? SidangWaktu::orderBy('waktu_mulai')->first() : $waktuSidang;
// Ambil data tempat seminar proposal
$tempatSidang = ($tempatSidang == null) ? SidangTempat::inRandomOrder()->first() : $tempatSidang;
// Cek apakah dosen panelis 1 atau dosen pembimbing sudah memiliki jadwal pada waktu dan tempat yang sama
$dosenTerpakai = SidangJadwal::where('tanggal_sidang', $tglMulaiSidang)
->where('id_sidang_waktu', $waktuSidang->id)
->where(function ($query) use ($dosenPembimbing) {
$query->where('id_dosen_panelis_1', $dosenPembimbing->id)
->orWhere('id_dosen_pembimbing', $dosenPembimbing->id);
})
->exists();
// Cek apakah waktu, tempat, dan tanggal yang sama sudah digunakan untuk sidang yang berbeda
$waktuTempatTerpakai = SidangJadwal::where('tanggal_sidang', $tglMulaiSidang)
->where('id_sidang_waktu', $waktuSidang->id)
->where('id_sidang_tempat', $tempatSidang->id)
->exists();
// Jika dosen atau waktu-tempat sudah terpakai, pindah ke tempat atau waktu berikutnya
if ($dosenTerpakai || $waktuTempatTerpakai) {
// Cek apakah masih ada tempat yang tersedia pada waktu yang sama
$nextTempatSidang = SidangTempat::where('id', '>', $tempatSidang->id)
->inRandomOrder()
->first();
if (!$nextTempatSidang) {
// Jika tidak ada tempat tersedia, pindah ke waktu berikutnya
$nextWaktuSidang = SidangWaktu::where('waktu_mulai', '>', $waktuSidang->waktu_mulai)
->whereNotExists(function ($query) use ($tglMulaiSidang, $tempatSidang) {
$query->select(DB::raw(1))
->from('sidang_jadwal')
->whereRaw('sidang_jadwal.tanggal_sidang = ?', [$tglMulaiSidang])
->whereRaw('sidang_jadwal.id_sidang_tempat = ?', [$tempatSidang->id])
->whereRaw('sidang_jadwal.id_sidang_waktu = sidang_waktu.id');
})
->first();
if (!$nextWaktuSidang) {
// Jika tidak ada waktu berikutnya, lanjutkan ke hari berikutnya
$tglMulaiSidangObj = new DateTime($tglMulaiSidang); // Konversi string menjadi objek DateTime
$tglMulaiSidangObj->modify('+1 day'); // Tambah 1 hari
// $tglMulaiSidang = $tglMulaiSidangObj;
$tglMulaiSidang = $tglMulaiSidangObj->format('Y-m-d');
// Konversi tanggal menjadi objek Carbon
$tglMulaiSidang = Carbon::parse($tglMulaiSidang);
// Jika tanggal tersebut adalah hari Sabtu atau Minggu, geser ke hari Senin
if ($tglMulaiSidang->isWeekend()) {
$tglMulaiSidang->next(Carbon::MONDAY);
}
// Periksa apakah tanggal mulai sidang melewati tanggal akhir sidang
if (Carbon::parse($tglMulaiSidang)->gt(Carbon::parse($tglAkhirSidang))) {
// Jika tanggal mulai sidang melewati tanggal akhir sidang, generate gagal
return redirect()
->back()
->with(
'toast_error',
'Generate Jadwal Melewati Batas Akhir. Tambahkan Tempat/Waktu Seminar Proposal.'
);
}
$waktuSidang = null;
$tempatSidang = null;
} else {
// Jika masih ada waktu berikutnya, lanjutkan ke waktu tersebut
$waktuSidang = $nextWaktuSidang;
$tempatSidang = null;
}
} else {
// Jika masih ada tempat berikutnya, lanjutkan ke tempat tersebut
$tempatSidang = $nextTempatSidang;
}
}
} while ($dosenTerpakai || $waktuTempatTerpakai);
// Buat data seminar jadwal
$id_dosen_panelis_1 = SeminarJadwal::where('id_seminar_proposal', $sidang->seminarProposal->id)
->value('id_dosen_panelis_1');
$sidangJadwal = new SidangJadwal();
$sidangJadwal->id_pengajuan = $pengajuan->id;
$sidangJadwal->id_mahasiswa = $mahasiswa->id;
$sidangJadwal->id_dosen_pembimbing = $dosenPembimbing->id;
$sidangJadwal->id_dosen_panelis_1 = $id_dosen_panelis_1;
$sidangJadwal->id_seminar_proposal = $sidang->seminarProposal->id;
$sidangJadwal->id_sidang = $sidang->id;
$sidangJadwal->id_sidang_waktu = $waktuSidang->id;
$sidangJadwal->id_sidang_tempat = $tempatSidang->id;
$sidangJadwal->tanggal_sidang = $tglMulaiSidang;
$sidangJadwal->save();
}
$sidangJadwalBelumLengkap = SidangJadwal::whereNull('id_dosen_panelis_2')->get();
foreach ($sidangJadwalBelumLengkap as $jadwal) {
// Cari id (dosen) dari users where role Dosen
$dosen = User::where('role', 'Dosen')->where('prodi', $request->input('prodi'))->pluck('id')->toArray();
// Acak urutan elemen dalam array $dosen
shuffle($dosen);
$dosenPanelis2 = null;
// Iterasi semua dosen pastikan memenuhi kondisi 1 dan 2
foreach ($dosen as $idDosen) {
// Kondisi 1: pastikan belum menjadi id_dosen_pembimbing pada id_sidang_waktu dan seminar_tanggal yang sama
$belumJadiDosenPembimbing = SidangJadwal::where('id_sidang_waktu', $jadwal->id_sidang_waktu)
->where('tanggal_sidang', $jadwal->tanggal_sidang)
->where('id_dosen_pembimbing', $idDosen)
->doesntExist();
// Kondisi 2: pastikan belum menjadi id_dosen_panelis_2 pada id_sidang_waktu dan seminar_tanggal yang sama
$belumJadiDosenPanelis1 = SidangJadwal::where('id_sidang_waktu', $jadwal->id_sidang_waktu)
->where('tanggal_sidang', $jadwal->tanggal_sidang)
->where('id_dosen_panelis_1', $idDosen)
->doesntExist();
// Kondisi 3: pastikan belum menjadi id_dosen_panelis_2 pada id_sidang_waktu dan seminar_tanggal yang sama
$belumJadiDosenPanelis2 = SidangJadwal::where('id_sidang_waktu', $jadwal->id_sidang_waktu)
->where('tanggal_sidang', $jadwal->tanggal_sidang)
->where('id_dosen_panelis_2', $idDosen)
->doesntExist();
// Sesuai prodi dosen
$sesuaiProdi = User::where('role', 'Dosen')->where('prodi', $request->input('prodi'))->exists();
// Menghitung jumlah panelis yang sudah ada
$jumlahPanelis = SidangJadwal::where('id_dosen_panelis_2', $idDosen)->count();
// Batasan maksimal panelis
$batasanPanelis = $request->input('limit');
// Jika dosen memenuhi semua kondisi, kita jadikan sebagai dosen panelis 2
if ($belumJadiDosenPembimbing && $belumJadiDosenPanelis1 && $belumJadiDosenPanelis2 && $sesuaiProdi && $jumlahPanelis < $batasanPanelis) {
$dosenPanelis2 = $idDosen;
break; // Keluar dari perulangan jika sudah ditemukan dosen
}
}
if (is_null($dosenPanelis2)) {
// Ambil dosen dari tabel User untuk dijadikan panelis 2 jika belum ditemukan dosen yang memenuhi kondisi
$prodi = $request->input('prodi');
$dosenPanelis2 = User::where('role', 'Dosen')
->whereIn('prodi', $prodi)
->whereNotIn('id', $dosen)
->inRandomOrder()
->first();
if ($dosenPanelis2) {
$dosenPanelis2 = $dosenPanelis2->id;
// Menghitung jumlah panelis yang sudah ada setelah memilih dosen secara acak
$jumlahPanelis = SidangJadwal::where('id_dosen_panelis_2', $dosenPanelis2)->count();
// Jika jumlah panelis melebihi batasan setelah memilih dosen secara acak, kembalikan pesan error
if ($jumlahPanelis > $batasanPanelis) {
return redirect()->back()->with('toast_error', 'Dosen Telah Mencapai Batas Maksimal Sebagai Anggota Penguji');
}
} else {
return redirect()->back()->with('toast_error', 'Seluruh Dosen Telah Mencapai Batas Maksimal Sebagai Anggota Penguji');
}
}
// Simpan id dosen panelis 2 ke dalam jadwal sidang
$jadwal->id_dosen_panelis_2 = $dosenPanelis2;
$jadwal->save();
}
return redirect('sidang')->with('toast_success', 'Generate Jadwal Sidang Berhasil.');
}
function generateJadwalV2($sidang = null, $tglMulaiSidang = null, $waktuSidang = null, $tempatSidang = null)
{
// Ambil pengaturan seminar proposal
$settingSidang = SettingSidang::first();
// Ambil waktu mulai sidang
$tglMulaiSidang = ($tglMulaiSidang == null) ? $settingSidang->tgl_mulai_sidang : $tglMulaiSidang;
// Ambil data seminar proposal yang belum terjadwal
$sidangBelumTerjadwal = Sidang::whereDoesntHave('sidangJadwal')->get();
// Lakukan looping untuk setiap seminar proposal
foreach ($sidangBelumTerjadwal as $sidang) {
// Ambil data mahasiswa, pengajuan, dan dosen pembimbing
$mahasiswa = $sidang->mahasiswa;
$pengajuan = $sidang->pengajuan;
$dosenPembimbing = $pengajuan->dosenPembimbing;
// Ambil data waktu seminar proposal
$waktuSidang = ($waktuSidang == null) ? SidangWaktu::orderBy('waktu_mulai')->first() : $waktuSidang;
// Ambil data tempat seminar proposal
$tempatSidang = ($tempatSidang == null) ? SidangTempat::first() : $tempatSidang;
// Ambil data jadwal seminar yang sudah ada pada tanggal dan waktu yang sama
$jadwalSeminarTersedia = SidangJadwal::where('tanggal_sidang', $tglMulaiSidang)
->where('id_sidang_waktu', $waktuSidang->id)
->where('id_sidang_tempat', $tempatSidang->id)
->get();
// Hitung jumlah dosen pembimbing yang sudah terjadwal pada tanggal dan waktu yang sama
$jumlahDosenPembimbingTerjadwal = 0;
foreach ($jadwalSeminarTersedia as $jadwal) {
if ($jadwal->id_dosen_pembimbing != $dosenPembimbing->id) {
$jumlahDosenPembimbingTerjadwal++;
}
}
// Jika masih ada kuota dosen pembimbing, jadwalkan seminar proposal
if ($jumlahDosenPembimbingTerjadwal < 2) {
// Buat data seminar jadwal
$id_dosen_panelis_1 = SeminarJadwal::where('id_seminar_proposal', $sidang->seminarProposal->id)
->value('id_dosen_panelis_1');
$sidangJadwal = new SidangJadwal();
$sidangJadwal->id_pengajuan = $pengajuan->id;
$sidangJadwal->id_mahasiswa = $mahasiswa->id;
$sidangJadwal->id_dosen_pembimbing = $dosenPembimbing->id;
$sidangJadwal->id_dosen_panelis_1 = $id_dosen_panelis_1;
$sidangJadwal->id_seminar_proposal = $sidang->seminarProposal->id;
$sidangJadwal->id_sidang = $sidang->id;
$sidangJadwal->id_sidang_waktu = $waktuSidang->id;
$sidangJadwal->id_sidang_tempat = $tempatSidang->id;
$sidangJadwal->tanggal_sidang = $tglMulaiSidang;
$sidangJadwal->save();
} else {
// If dosen pembimbing quota is full, check for empty slots in the current waktuSeminarProposal
$tempatSidangBerikutnya = SidangTempat::where('id', '>', $tempatSidang->id)->first();
$emptySlotsInCurrentWaktu = SidangJadwal::where('tanggal_sidang', $tglMulaiSidang)
->where('id_sidang_waktu', $waktuSidang->id)
->where('id_sidang_tempat', $tempatSidangBerikutnya->id)
->whereHas('dosenPembimbing', function ($query) {
$query->havingRaw('COUNT(*) < 5');
})
->count();
if ($emptySlotsInCurrentWaktu < 1) {
// If empty slots are found, schedule the seminar proposal in one of those slots
// ... (logic to schedule in an empty slot within the current waktuSeminarProposal)
// echo "Passing 0 ({$emptySlotsInCurrentWaktu}) - {$tglMulaiSidang} - {$waktuSidang} - {$tempatSidangBerikutnya}";
// exit();
$this->generateJadwal($sidang, $tglMulaiSidang, $waktuSidang, $tempatSidangBerikutnya);
} else {
// Jika kuota dosen pembimbing penuh, pindahkan ke sesi berikutnya
$waktuSidangBerikutnya = SidangWaktu::where('waktu_mulai', '>', $waktuSidang->waktu_mulai)->first();
if ($waktuSidangBerikutnya) {
// Ulangi proses penjadwalan dengan waktu seminar proposal berikutnya
// echo "Passing 1 ({$emptySlotsInCurrentWaktu}) - {$tglMulaiSidang} - {$waktuSidangBerikutnya} - {$tempatSidang}";
// exit();
$this->generateJadwal($sidang, $tglMulaiSidang, $waktuSidangBerikutnya, $tempatSidang);
// $this->generateJadwal($sidang, $tglMulaiSidang, $waktuSidangBerikutnya, $tempatSidang);
} else {
// Jika tidak ada waktu seminar proposal berikutnya, pindahkan ke hari berikutnya
$tglMulaiSidang = $tglMulaiSidang->addDays(1);
// Ulangi proses penjadwalan dengan tanggal seminar dan waktu seminar proposal yang sama
// echo "Passing 2";
// exit();
$this->generateJadwal($sidang, $tglMulaiSidang, $waktuSidang, $tempatSidang);
}
}
}
}
// Ambil semua entri yang belum memiliki dosenPanelis1
$entriesToUpdate = SidangJadwal::whereNull('id_dosen_panelis_2')->get();
// Iterasi melalui setiap entri yang belum memiliki id_dosen_panelis_2
foreach ($entriesToUpdate as $entry) {
// Ambil id_dosen_pembimbing dari entri yang sedang diiterasi
$currentDosenId = $entry->id_dosen_pembimbing;
// Ambil dosen dengan kriteria yang sama dengan id_sidang_waktu dan id_sidang_tempat pada entri yang sedang diiterasi
$otherDosen = SidangJadwal::where('id_sidang_waktu', $entry->id_sidang_waktu)
->where('id_sidang_tempat', $entry->id_sidang_tempat)
->where('id_dosen_pembimbing', '!=', $currentDosenId) // Memastikan beda dengan dosen pada entri yang sedang diiterasi
->where('id_dosen_panelis_1', '!=', $entry->id_dosen_panelis_1)
->pluck('id_dosen_pembimbing') // Ambil hanya id_dosen_pembimbing
->toArray(); // Ubah menjadi array
// Cek apakah ditemukan dosen lain yang memenuhi kriteria
if (!empty($otherDosen)) {
// Lakukan pembaruan dengan menetapkan id_dosen_panelis_1 pada entri yang sedang diiterasi
$entry->update([
'id_dosen_panelis_2' => $otherDosen[0] // Ambil dosen pertama yang memenuhi kriteria
]);
}
}
// echo "Finish";
// exit;
return redirect('sidang')->with('toast_success', 'Generate Jadwal Sidang Berhasil.');
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
// Validasi data yang diterima dari request
$request->validate([
'id_sidang_tempat' => 'required',
'id_sidang_waktu' => 'required',
'tanggal_sidang' => 'required|date',
'id_dosen_panelis_2' => 'required',
]);
// Cari data SidangJadwal berdasarkan ID
$sidangJadwal = SidangJadwal::findOrFail($id);
if($request->id_dosen_panelis_2 == $sidangJadwal->id_dosen_pembimbing)
{
return redirect()->back()->with('toast_error', 'Anggota Penguji Sama Dengan Sekretaris Pembimbing.');
} elseif($request->id_dosen_panelis_2 == $sidangJadwal->id_dosen_panelis_1)
{
return redirect()->back()->with('toast_error', 'Anggota Penguji Sama Dengan Ketua Penguji.');
} else {
// Pengecekan bentrok jadwal
$jadwalBentrok = SidangJadwal::where('tanggal_sidang', $request->tanggal_sidang)
->where('id_sidang_waktu', $request->id_sidang_waktu)
->where('id_dosen_panelis_2', $request->id_dosen_panelis_2)
->where('id', '!=', $id)
->exists();
if ($jadwalBentrok)
{
return redirect()->back()->with('toast_error', 'Anggota Penguji Sudah Memiliki Jadwal yang Sama.');
} else {
// Update data SidangJadwal dengan data baru dari request
$sidangJadwal->update([
'id_sidang_tempat' => $request->input('id_sidang_tempat'),
'id_sidang_waktu' => $request->input('id_sidang_waktu'),
'tanggal_sidang' => $request->input('tanggal_sidang'),
'id_dosen_panelis_2' => $request->input('id_dosen_panelis_2'),
]);
// Redirect ke halaman atau route yang sesuai setelah berhasil mengupdate data
return redirect()->back()->with('toast_success', 'Jadwal Sidang Berhasil Diperbarui.');
}
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
// Cari data SidangJadwal berdasarkan ID
$sidangJadwal = SidangJadwal::findOrFail($id);
// Hapus data SidangJadwal dari database
$sidangJadwal->delete();
// Redirect ke halaman atau route yang sesuai setelah berhasil menghapus data
return redirect()->back()->with('toast_success', 'Jadwal Sidang Berhasil Dihapus.');
}
public function reset()
{
// Menghapus semua jadwal
SidangJadwal::truncate();
return redirect()->back()->with('toast_success', 'Jadwal Sidang Berhasil Diatur Ulang.');
}
public function exportExcel()
{
return Excel::download(new SidangExport, 'sidang.xlsx');
}
public function exportPDF()
{
$sidangJadwal = SidangJadwal::with([
'pengajuan',
'mahasiswa',
'dosenPembimbing',
'dosenPanelis1',
'dosenPanelis2',
'seminarProposal',
'sidang',
'sidangWaktu',
'sidangTempat'
])->get();
$pdf = PDF::loadView('export.sidang', compact('sidangJadwal'))->setPaper('a4', 'landscape');
return $pdf->stream();
}
}