310 lines
10 KiB
PHP
310 lines
10 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;
|
|
});
|
|
|
|
$groupInfoByHal = [];
|
|
foreach ($detailSoal as $detail) {
|
|
$halValue = (int) ($detail->hal ?? $daftarHal->first());
|
|
if (!array_key_exists($halValue, $groupInfoByHal)) {
|
|
$groupInfoByHal[$halValue] = [
|
|
'nama' => $detail->group_nama,
|
|
'keterangan' => $detail->group_keterangan,
|
|
];
|
|
continue;
|
|
}
|
|
|
|
if (empty($groupInfoByHal[$halValue]['nama']) && !empty($detail->group_nama)) {
|
|
$groupInfoByHal[$halValue]['nama'] = $detail->group_nama;
|
|
}
|
|
|
|
if (empty($groupInfoByHal[$halValue]['keterangan']) && !empty($detail->group_keterangan)) {
|
|
$groupInfoByHal[$halValue]['keterangan'] = $detail->group_keterangan;
|
|
}
|
|
}
|
|
$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 = [];
|
|
return view('soal.index', [
|
|
'soal' => $soal,
|
|
'hal' => $hal,
|
|
'halPertama' => $halPertama,
|
|
'daftarHal' => $daftarHal,
|
|
'totalHal' => $daftarHal->count(),
|
|
'soalId' => $soal->id,
|
|
'pegawai' => [],
|
|
'prefillJawaban' => $prefillJawaban,
|
|
'existingJawaban' => $existingJawaban,
|
|
'formLocked' => $formLocked,
|
|
'groupInfoByHal' => $groupInfoByHal,
|
|
]);
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$validator = Validator::make($request->all(), [
|
|
'lms_mutu_soal_id' => 'required|integer',
|
|
'hal' => 'nullable|integer|min:1',
|
|
'jawaban' => 'nullable|array',
|
|
'jawaban.*' => 'nullable',
|
|
'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();
|
|
$soalId = $validated['lms_mutu_soal_id'];
|
|
|
|
$allDetails = SoalDetail::where('lms_mutu_soal_id', $soalId)
|
|
->get(['id', 'soal'])
|
|
->keyBy('id');
|
|
|
|
$jawabanUtama = $validated['jawaban'] ?? [];
|
|
$jawabanLainnya = $validated['jawaban_lainnya'] ?? [];
|
|
$namaResponden = null;
|
|
$jawabanBaru = null;
|
|
$unitKerja = null;
|
|
$pegawai = session('pegawai') ?? [];
|
|
$pegawaiId = is_array($pegawai) ? ($pegawai['id'] ?? null) : 1;
|
|
DB::connection('dbLmsMutu')->transaction(function () use (&$jawabanBaru, $validated, $jawabanUtama, $jawabanLainnya, $allDetails, &$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 ($allDetails as $detailId => $detail) {
|
|
$answer = $jawabanUtama[$detailId] ?? null;
|
|
|
|
if (is_array($answer)) {
|
|
$answer = json_encode($answer);
|
|
}
|
|
|
|
if ($answer === 'Lainnya' && !empty($jawabanLainnya[$detailId])) {
|
|
$answer = $jawabanLainnya[$detailId];
|
|
}
|
|
|
|
$pertanyaan = null;
|
|
$decoded = json_decode($detail->soal, true);
|
|
$pertanyaan = Str::lower(trim($decoded['soal'] ?? ''));
|
|
|
|
|
|
if ($pertanyaan && $answer) {
|
|
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' => (int) $detailId,
|
|
'jawaban' => $answer,
|
|
]);
|
|
}
|
|
|
|
$updatePayload = [];
|
|
|
|
if (!empty($namaResponden)) {
|
|
$updatePayload['nama'] = $namaResponden;
|
|
}
|
|
|
|
if (!empty($unitKerja)) {
|
|
$updatePayload['unit'] = $unitKerja;
|
|
}
|
|
|
|
if (!empty($updatePayload)) {
|
|
$jawabanBaru->update($updatePayload);
|
|
}
|
|
});
|
|
|
|
|
|
|
|
return redirect()->route('soal.thankyou')
|
|
->with('success', 'Jawaban berhasil disimpan.');
|
|
}
|
|
|
|
public function thankYou()
|
|
{
|
|
return view('soal.thank-you');
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|