210 lines
7.9 KiB
PHP
210 lines
7.9 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Kriteria;
|
|
use App\Models\PeriodeSeleksi;
|
|
use Illuminate\Http\Request;
|
|
|
|
class KriteriaController extends Controller
|
|
{
|
|
/**
|
|
* Tampilkan daftar kriteria
|
|
*/
|
|
public function index()
|
|
{
|
|
$kriteria = Kriteria::orderBy('kode')->get();
|
|
$totalBobot = $kriteria->sum('bobot');
|
|
$isLocked = PeriodeSeleksi::where('status', 'aktif')->exists();
|
|
|
|
return view('admin.kriteria.index', compact('kriteria', 'totalBobot', 'isLocked'));
|
|
}
|
|
|
|
/**
|
|
* Form tambah kriteria baru
|
|
*/
|
|
public function create()
|
|
{
|
|
if (PeriodeSeleksi::where('status', 'aktif')->exists()) {
|
|
return redirect()->route('admin.kriteria.index')
|
|
->with('error', 'Aksi ditolak: Struktur kriteria dikunci karena terdapat periode seleksi yang sedang AKTIF.');
|
|
}
|
|
|
|
$kriteria = Kriteria::orderBy('kode')->get();
|
|
|
|
$lastKriteria = Kriteria::orderBy('id', 'desc')->first();
|
|
$nextCode = 'C1';
|
|
if ($lastKriteria) {
|
|
$num = (int) filter_var($lastKriteria->kode, FILTER_SANITIZE_NUMBER_INT);
|
|
$nextCode = 'C' . ($num + 1);
|
|
}
|
|
|
|
return view('admin.kriteria.create', compact('kriteria', 'nextCode'));
|
|
}
|
|
|
|
/**
|
|
* Simpan kriteria baru
|
|
*/
|
|
public function store(Request $request)
|
|
{
|
|
if (PeriodeSeleksi::where('status', 'aktif')->exists()) {
|
|
return redirect()->route('admin.kriteria.index')
|
|
->with('error', 'Aksi ditolak: Struktur kriteria dikunci karena terdapat periode seleksi yang sedang AKTIF.');
|
|
}
|
|
|
|
$validated = $request->validate([
|
|
'kode' => 'required|string|max:50|unique:kriteria,kode',
|
|
'nama' => 'required|string|max:255',
|
|
'jenis' => 'required|in:benefit,cost',
|
|
'bobot' => 'required|numeric|min:0|max:1',
|
|
'existing_bobot' => 'nullable|array',
|
|
'existing_bobot.*' => 'required|numeric|min:0|max:1',
|
|
'sub_keterangan' => 'required|array|size:5',
|
|
'sub_keterangan.*' => 'required|string|max:255',
|
|
], [
|
|
'kode.required' => 'Kode kriteria harus diisi',
|
|
'kode.unique' => 'Kode kriteria sudah digunakan',
|
|
'nama.required' => 'Nama kriteria harus diisi',
|
|
'jenis.required' => 'Jenis kriteria harus dipilih',
|
|
'bobot.required' => 'Bobot harus diisi',
|
|
'bobot.min' => 'Bobot minimal 0',
|
|
'bobot.max' => 'Bobot maksimal 1',
|
|
'sub_keterangan.*.required' => 'Keterangan sub-kriteria harus diisi',
|
|
]);
|
|
|
|
$newBobot = (float)$validated['bobot'];
|
|
$existingBobotSum = 0;
|
|
if (isset($validated['existing_bobot'])) {
|
|
foreach ($validated['existing_bobot'] as $id => $val) {
|
|
$existingBobotSum += (float)$val;
|
|
}
|
|
}
|
|
$totalBobot = $newBobot + $existingBobotSum;
|
|
|
|
if (abs($totalBobot - 1.00) > 0.001) {
|
|
return back()
|
|
->withInput()
|
|
->with('error', 'Tidak dapat menyimpan kriteria karena total bobot tidak boleh kurang/lebih dari 1.00 (100%). Total saat ini adalah ' . number_format($totalBobot, 2) . '.');
|
|
}
|
|
|
|
\Illuminate\Support\Facades\DB::transaction(function() use ($validated) {
|
|
if (isset($validated['existing_bobot'])) {
|
|
foreach ($validated['existing_bobot'] as $id => $val) {
|
|
Kriteria::where('id', $id)->update(['bobot' => $val]);
|
|
}
|
|
}
|
|
|
|
$k = Kriteria::create([
|
|
'kode' => strtoupper($validated['kode']),
|
|
'nama' => $validated['nama'],
|
|
'jenis' => $validated['jenis'],
|
|
'bobot' => $validated['bobot'],
|
|
]);
|
|
|
|
foreach ($validated['sub_keterangan'] as $nilai => $keterangan) {
|
|
\App\Models\SubKriteria::create([
|
|
'kriteria_id' => $k->id,
|
|
'nilai' => $nilai,
|
|
'keterangan' => $keterangan,
|
|
]);
|
|
}
|
|
});
|
|
|
|
return redirect()->route('admin.kriteria.index')
|
|
->with('success', 'Kriteria baru berhasil ditambahkan dan bobot disesuaikan!');
|
|
}
|
|
|
|
/**
|
|
* Form edit kriteria
|
|
*/
|
|
public function edit(Kriteria $kriterium)
|
|
{
|
|
if (PeriodeSeleksi::where('status', 'aktif')->exists()) {
|
|
return redirect()->route('admin.kriteria.index')
|
|
->with('error', 'Aksi ditolak: Struktur kriteria dikunci karena terdapat periode seleksi yang sedang AKTIF.');
|
|
}
|
|
|
|
return view('admin.kriteria.edit', ['kriteria' => $kriterium]);
|
|
}
|
|
|
|
/**
|
|
* Update kriteria
|
|
*/
|
|
public function update(Request $request, Kriteria $kriterium)
|
|
{
|
|
if (PeriodeSeleksi::where('status', 'aktif')->exists()) {
|
|
return redirect()->route('admin.kriteria.index')
|
|
->with('error', 'Aksi ditolak: Struktur kriteria dikunci karena terdapat periode seleksi yang sedang AKTIF.');
|
|
}
|
|
|
|
$validated = $request->validate([
|
|
'nama' => 'required|string|max:255',
|
|
'jenis' => 'required|in:benefit,cost',
|
|
'bobot' => 'required|numeric|min:0|max:1',
|
|
'sub_keterangan' => 'required|array|size:5',
|
|
'sub_keterangan.*' => 'required|string|max:255',
|
|
], [
|
|
'nama.required' => 'Nama kriteria harus diisi',
|
|
'jenis.required' => 'Jenis atribut harus dipilih',
|
|
'bobot.required' => 'Bobot harus diisi',
|
|
'bobot.min' => 'Bobot minimal 0',
|
|
'bobot.max' => 'Bobot maksimal 1',
|
|
'sub_keterangan.*.required' => 'Keterangan sub-kriteria harus diisi',
|
|
]);
|
|
|
|
\Illuminate\Support\Facades\DB::transaction(function() use ($kriterium, $validated) {
|
|
$kriterium->update([
|
|
'nama' => $validated['nama'],
|
|
'jenis' => $validated['jenis'],
|
|
'bobot' => $validated['bobot'],
|
|
]);
|
|
|
|
foreach ($validated['sub_keterangan'] as $nilai => $keterangan) {
|
|
\App\Models\SubKriteria::updateOrCreate(
|
|
[
|
|
'kriteria_id' => $kriterium->id,
|
|
'nilai' => $nilai,
|
|
],
|
|
[
|
|
'keterangan' => $keterangan,
|
|
]
|
|
);
|
|
}
|
|
});
|
|
|
|
$totalBobot = Kriteria::sum('bobot');
|
|
if (abs($totalBobot - 1.00) > 0.001) {
|
|
return redirect()->route('admin.kriteria.index')
|
|
->with('success', 'Kriteria berhasil diperbarui!')
|
|
->with('warning', 'Perhatian: Total bobot kriteria saat ini adalah ' . number_format($totalBobot, 2) . '. Silakan sesuaikan bobot seluruh kriteria agar bernilai tepat 1.00 sebelum menghitung SAW.');
|
|
}
|
|
|
|
return redirect()->route('admin.kriteria.index')
|
|
->with('success', 'Kriteria berhasil diperbarui!');
|
|
}
|
|
|
|
/**
|
|
* Hapus kriteria
|
|
*/
|
|
public function destroy(Kriteria $kriterium)
|
|
{
|
|
if (PeriodeSeleksi::where('status', 'aktif')->exists()) {
|
|
return redirect()->route('admin.kriteria.index')
|
|
->with('error', 'Aksi ditolak: Struktur kriteria dikunci karena terdapat periode seleksi yang sedang AKTIF.');
|
|
}
|
|
|
|
$kriterium->delete();
|
|
|
|
$totalBobot = Kriteria::sum('bobot');
|
|
if (abs($totalBobot - 1.00) > 0.001) {
|
|
return redirect()->route('admin.kriteria.index')
|
|
->with('success', 'Kriteria berhasil dihapus!')
|
|
->with('warning', 'Perhatian: Total bobot kriteria saat ini adalah ' . number_format($totalBobot, 2) . '. Silakan sesuaikan bobot kriteria yang tersisa agar bernilai tepat 1.00 sebelum menghitung SAW.');
|
|
}
|
|
|
|
return redirect()->route('admin.kriteria.index')
|
|
->with('success', 'Kriteria berhasil dihapus!');
|
|
}
|
|
}
|