mutu-rsab/app/Http/Controllers/SoalController.php

287 lines
9.4 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\Jawaban;
use App\Models\JawabanDetail;
use App\Models\Soal;
use App\Models\SoalDetail;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
class SoalController extends Controller
{
public function index(Request $request)
{
$daftarSoal = Soal::orderBy('judul_soal')->get();
if ($daftarSoal->isEmpty()) {
abort(404, 'Data soal tidak ditemukan.');
}
$selectedSoalId = (int) $request->query('soal_id', $daftarSoal->first()->id);
$pegawai = session('pegawai') ?? [];
$pegawaiId = is_array($pegawai) ? ($pegawai['id'] ?? null) : null;
if (!$request->boolean('start')) {
$completedSoalIds = [];
if ($pegawaiId) {
$completedSoalIds = Jawaban::where('pegawai_id', $pegawaiId)
->pluck('lms_mutu_soal_id')
->toArray();
}
return view('soal.list', [
'daftarSoal' => $daftarSoal,
'completedSoalIds' => $completedSoalIds,
]);
}
$soal = Soal::with('soalDetail')->find($selectedSoalId);
if (!$soal) {
abort(404, 'Data soal tidak ditemukan.');
}
$detailSoal = $soal->soalDetail()
->orderBy('hal')
->orderBy('id')
->get();
$daftarHal = $detailSoal->pluck('hal')
->map(function ($value) {
return is_null($value) ? null : (int) $value;
})
->filter(function ($value) {
return !is_null($value);
})
->unique()
->sort()
->values();
if ($daftarHal->isEmpty()) {
$daftarHal = collect([1]);
}
$hal = (int) $request->query('hal', $daftarHal->first());
if (!$daftarHal->contains($hal)) {
$hal = $daftarHal->first();
}
$detailSoal = $detailSoal->map(function ($detail) use ($daftarHal) {
$detail->hal = $detail->hal ?? $daftarHal->first();
return $detail;
});
$soal->setRelation('soalDetail', $detailSoal);
$halPertama = $daftarHal->first() ?? $hal;
$existingJawaban = [];
$formLocked = false;
if ($pegawaiId) {
$jawabanTersimpan = Jawaban::where('pegawai_id', $pegawaiId)
->where('lms_mutu_soal_id', $soal->id)
->latest('tanggal_isi')
->first();
if ($jawabanTersimpan) {
$existingJawaban = $jawabanTersimpan->jawabanDetail
->pluck('jawaban', 'lms_mutu_soal_detail_id')
->toArray();
$formLocked = true;
}
}
$prefillJawaban = $this->generatePrefillJawaban($detailSoal, $pegawai);
return view('soal.index', [
'soal' => $soal,
'hal' => $hal,
'halPertama' => $halPertama,
'daftarHal' => $daftarHal,
'totalHal' => $daftarHal->count(),
'soalId' => $soal->id,
'pegawai' => $pegawai,
'prefillJawaban' => $prefillJawaban,
'existingJawaban' => $existingJawaban,
'formLocked' => $formLocked,
]);
}
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'lms_mutu_soal_id' => 'required|integer',
'hal' => 'nullable|integer|min:1',
'jawaban' => 'required|array',
'jawaban.*' => 'required',
'jawaban_lainnya' => 'nullable|array',
'jawaban_lainnya.*' => 'nullable|string',
]);
$validator->after(function ($validator) use ($request) {
$jawabanUtama = $request->input('jawaban', []);
$jawabanLainnya = $request->input('jawaban_lainnya', []);
foreach ($jawabanUtama as $detailId => $answer) {
if ($answer === 'Lainnya') {
$jawabanIsian = $jawabanLainnya[$detailId] ?? null;
if (!$jawabanIsian) {
$validator->errors()->add("jawaban_lainnya.$detailId", 'Jawaban lainnya wajib diisi.');
}
}
}
});
$validated = $validator->validate();
$detailIds = array_map('intval', array_keys($validated['jawaban']));
$detailMeta = SoalDetail::whereIn('id', $detailIds)
->get(['id', 'soal'])
->keyBy('id');
$jawabanBaru = null;
$jawabanLainnya = $validated['jawaban_lainnya'] ?? [];
$namaResponden = null;
$unitKerja = null;
$pegawai = session('pegawai') ?? [];
$pegawaiId = is_array($pegawai) ? ($pegawai['id'] ?? null) : null;
DB::connection('dbLmsMutu')->transaction(function () use (&$jawabanBaru, $validated, $jawabanLainnya, $detailMeta, &$namaResponden, &$unitKerja, $pegawaiId) {
$jawabanBaru = Jawaban::create([
'lms_mutu_soal_id' => $validated['lms_mutu_soal_id'],
'pegawai_id' => $pegawaiId,
'tanggal_isi' => Carbon::now()->addHour(7),
]);
foreach ($validated['jawaban'] as $detailId => $answer) {
if (is_array($answer)) {
$answer = json_encode($answer);
}
if ($answer === 'Lainnya' && !empty($jawabanLainnya[$detailId])) {
$answer = $jawabanLainnya[$detailId];
}
if ($answer === null || $answer === '') {
continue;
}
$detailIdInt = (int) $detailId;
$pertanyaan = null;
if ($detailMeta->has($detailIdInt)) {
$decoded = json_decode($detailMeta[$detailIdInt]->soal, true);
$pertanyaan = Str::lower(trim($decoded['soal'] ?? ''));
}
if ($pertanyaan) {
if (Str::contains($pertanyaan, 'nama/inisial responden')) {
$namaResponden = $answer;
}
if (Str::contains($pertanyaan, 'unit/area kerja anda saat ini')) {
$unitKerja = $answer;
}
}
JawabanDetail::create([
'lms_mutu_jawaban_id' => $jawabanBaru->id,
'lms_mutu_soal_detail_id' => $detailIdInt,
'jawaban' => $answer,
]);
}
$updatePayload = [];
if (!empty($namaResponden)) {
$updatePayload['nama'] = $namaResponden;
}
if (!empty($unitKerja)) {
$updatePayload['unit'] = $unitKerja;
}
if (!empty($updatePayload)) {
$jawabanBaru->update($updatePayload);
}
});
return redirect('/')
->with('success', 'Jawaban berhasil disimpan.');
}
public function redirectSmart()
{
$data = request()->input('data');
$json = base64_decode($data);
$array = json_decode($json, true);
session(['pegawai' => $array]);
return redirect('/');
}
protected function generatePrefillJawaban($detailSoal, $pegawai): array
{
if (!is_iterable($detailSoal) || !is_array($pegawai) || empty($pegawai)) {
return [];
}
$prefill = [];
foreach ($detailSoal as $detail) {
$decoded = json_decode($detail->soal, true) ?? [];
$question = $decoded['soal'] ?? '';
$value = $this->mapPegawaiValueToQuestion($question, $pegawai);
if ($value !== null && $value !== '') {
$prefill[$detail->id] = $value;
}
}
return $prefill;
}
protected function mapPegawaiValueToQuestion(?string $question, array $pegawai): ?string
{
if (!$question) {
return null;
}
$normalized = Str::lower($question);
if (Str::contains($normalized, 'nama/inisial responden')) {
return $pegawai['namaLengkap'] ?? $pegawai['nama'] ?? null;
}
if (Str::contains($normalized, 'nomor telepon') || Str::contains($normalized, 'hp')) {
return $pegawai['noHandphone'] ?? null;
}
if (Str::contains($normalized, 'jenis kelamin')) {
return $pegawai['jenisKelamin']['jenisKelamin'] ?? $pegawai['jenisKelamin']['namaExternal'] ?? null;
}
if (Str::contains($normalized, 'unit/area kerja')) {
return $pegawai['ruangan']['namaRuangan'] ?? $pegawai['ruangan']['namaExternal'] ?? null;
}
if (Str::contains($normalized, 'posisi kerja')) {
return $pegawai['jabatanInternal']['namaJabatan']
?? $pegawai['jabatanFungsional']['namaJabatan']
?? $pegawai['jenisPegawai']['jenisPegawai']
?? null;
}
if (Str::contains($normalized, 'email')) {
return $pegawai['email'] ?? null;
}
if (Str::contains($normalized, 'nip') || Str::contains($normalized, 'nomor identitas')) {
return $pegawai['nipPns'] ?? $pegawai['noIdentitas'] ?? null;
}
if (Str::contains($normalized, 'nama faskes')) {
return $pegawai['ruangan']['namaExternal'] ?? 'RSAB HARAPAN KITA';
}
return null;
}
}