diff --git a/htdocs/app/Http/Controllers/BiorepositoryController.php b/htdocs/app/Http/Controllers/BiorepositoryController.php index 24a69bdf..41335a29 100644 --- a/htdocs/app/Http/Controllers/BiorepositoryController.php +++ b/htdocs/app/Http/Controllers/BiorepositoryController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers; use App\BioCabinet; use App\BioRack; use App\BioSpecimen; +use App\Periksa; use Carbon\Carbon; use Illuminate\Http\Request; use Session; @@ -28,15 +29,6 @@ class BiorepositoryController extends Controller ->orderBy('id', 'DESC') ->get(); - $data['cabinets'] = BioCabinet::with([ - 'racks' => function ($query) { - $query->orderBy('rack_number', 'ASC')->orderBy('code', 'ASC'); - }, - 'racks.specimens' => function ($query) { - $query->orderBy('stored_at', 'ASC'); - }, - ])->orderBy('name', 'ASC')->get(); - $data['oldestSpecimen'] = BioSpecimen::with(['cabinet', 'rack']) ->whereNotNull('stored_at') ->orderBy('stored_at', 'ASC') @@ -79,7 +71,9 @@ class BiorepositoryController extends Controller 'cabinet_id' => 'required|exists:bio_cabinets,id', 'code' => 'required|max:50', 'name' => 'required|max:150', + 'slot_count' => 'required|integer|min:1|max:20', 'level' => 'required|integer|min:4|max:6', + 'box_number' => 'required|integer|min:1|max:20', 'capacity' => 'required|integer|min:16|max:100', 'notes' => 'nullable', ]); @@ -102,9 +96,10 @@ class BiorepositoryController extends Controller 'cabinet_id' => $request->input('cabinet_id'), 'code' => $request->input('code'), 'name' => $request->input('name'), + 'slot_count' => $request->input('slot_count'), 'level' => $request->input('level'), 'rack_number' => $nextRackNumber, - 'box_number' => 1, + 'box_number' => $request->input('box_number'), 'capacity' => $request->input('capacity'), 'notes' => $request->input('notes'), ]); @@ -136,15 +131,23 @@ class BiorepositoryController extends Controller $rack = BioRack::find($request->input('rack_id')); $expectedRackNo = $rack->rack_number ?: $rack->id; - $expectedBoxNo = $rack->box_number ?: 1; + $slotCount = (int) ($rack->slot_count ?: 1); + $boxCount = (int) ($rack->box_number ?: 1); - if ((int) $request->input('raknomor') !== (int) $expectedRackNo || - (int) $request->input('boxnomor') !== (int) $expectedBoxNo) { + if ((int) $request->input('raknomor') !== (int) $expectedRackNo) { return back()->withErrors(['slotnomor' => 'Posisi slot tidak sesuai dengan konfigurasi rack.'])->withInput(); } + if ((int) $request->input('slotnomor') < 1 || (int) $request->input('slotnomor') > $slotCount) { + return back()->withErrors(['slotnomor' => 'Slot melebihi konfigurasi rack.'])->withInput(); + } + if ((int) $request->input('shelfnomor') < 1 || (int) $request->input('shelfnomor') > (int) $rack->level) { - return back()->withErrors(['shelfnomor' => 'Shelf melebihi konfigurasi rack.'])->withInput(); + return back()->withErrors(['shelfnomor' => 'Shelf melebihi konfigurasi slot.'])->withInput(); + } + + if ((int) $request->input('boxnomor') < 1 || (int) $request->input('boxnomor') > $boxCount) { + return back()->withErrors(['boxnomor' => 'Box melebihi konfigurasi shelf.'])->withInput(); } if ((int) $request->input('tubenomor') < 1 || (int) $request->input('tubenomor') > (int) $rack->capacity) { @@ -152,7 +155,9 @@ class BiorepositoryController extends Controller } $slotTaken = BioSpecimen::where('rack_id', $rack->id) + ->where('slot_number', $request->input('slotnomor')) ->where('shelf_number', $request->input('shelfnomor')) + ->where('box_number', $request->input('boxnomor')) ->where('tube_number', $request->input('tubenomor')) ->first(); @@ -209,7 +214,7 @@ class BiorepositoryController extends Controller $sampleid = $request->input('sampleid'); if ($sampleid) { $cekdata = Periksa::where('nofoto', $sampleid)->first(); - if (!$cekdata) { + if ($cekdata) { $sampleid = $cekdata->id; } else { $sampleid = null; @@ -226,7 +231,7 @@ class BiorepositoryController extends Controller 'category_storage' => $request->input('kategorisimpan'), 'shelf_number' => $request->input('shelfnomor'), 'rack_number' => $request->input('raknomor'), - 'slot_number' => $request->input('shelfnomor'), + 'slot_number' => $request->input('slotnomor'), 'box_number' => $request->input('boxnomor'), 'tube_number' => $request->input('tubenomor'), 'bacteria_name' => $request->input('nmbakteri'), diff --git a/htdocs/app/Http/Controllers/DokterController.php b/htdocs/app/Http/Controllers/DokterController.php index 74f8adca..77f02d58 100644 --- a/htdocs/app/Http/Controllers/DokterController.php +++ b/htdocs/app/Http/Controllers/DokterController.php @@ -463,304 +463,298 @@ class DokterController extends Controller if ($kerja == 'Draft'){ $iddokter = Session('id'); } - if ($iddokter == 'Pilih' OR $iddokter == '' OR $iddokter == '0'){ - return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Error..!!', 'message' => 'Please Select Doctor Names']); - return back(); - } else { - $today = date('Y-m-d H:i:s'); - $periksa = Periksa::with(['getPasien', 'getPoli'])->find($idperiksa); - $nm_spesimen = $periksa->nm_spesimen ?? ''; - $noregister = $periksa->noregister ?? ''; - $nmadendum = $periksa->nmadendum ?? ''; - $tglverifikasi = $periksa->verifikasi ?? $today; - - $cekganda = Periksa::where('noregister', $noregister)->where('nmadendum', $nmadendum)->where('nm_spesimen', 'SPUTUM')->where('id', '!=', $idperiksa)->get(); - $statusdraft = 'Proses Analisis Sampel'; - KomponenJawaban::where('accnumber', $nofoto)->where('template', $dlp)->delete(); - $data = $request->except(['_token', 'periksa_id', 'val01', 'val10', 'acc_number']); - foreach ($data as $key => $value) { - if ($value === "" || is_null($value) || $value === "Pilih Salah Satu") continue; - if (is_array($value)) { - KomponenJawaban::updateOrCreate( - [ - 'accnumber' => $nofoto, - 'komponen' => $key, - ], - [ - 'isidata' => json_encode($value), - 'template' => $dlp, - 'created_by' => session('nama'), - ] - ); + $today = date('Y-m-d H:i:s'); + $periksa = Periksa::with(['getPasien', 'getPoli'])->find($idperiksa); + $nm_spesimen = $periksa->nm_spesimen ?? ''; + $noregister = $periksa->noregister ?? ''; + $nmadendum = $periksa->nmadendum ?? ''; + $tglverifikasi = $periksa->verifikasi ?? $today; + + $cekganda = Periksa::where('noregister', $noregister)->where('nmadendum', $nmadendum)->where('nm_spesimen', 'SPUTUM')->where('id', '!=', $idperiksa)->get(); + $statusdraft = 'Proses Analisis Sampel'; + KomponenJawaban::where('accnumber', $nofoto)->where('template', $dlp)->delete(); + $data = $request->except(['_token', 'periksa_id', 'val01', 'val10', 'acc_number']); + foreach ($data as $key => $value) { + if ($value === "" || is_null($value) || $value === "Pilih Salah Satu") continue; + if (is_array($value)) { + KomponenJawaban::updateOrCreate( + [ + 'accnumber' => $nofoto, + 'komponen' => $key, + ], + [ + 'isidata' => json_encode($value), + 'template' => $dlp, + 'created_by' => session('nama'), + ] + ); + } else { + if ($key == 'id_statusmediatamlainnya' AND $value != ''){ + $statusdraft = $value; + } else if ($key == 'id_statusmediasellainnya' AND $value != ''){ + $statusdraft = $value; + } else if ($key == 'id_statusmediasda' AND $value != ''){ + $statusdraft = $value; + } else if ($key == 'id_statusmediamcconkey' AND $value != ''){ + $statusdraft = $value; + } else if ($key == 'id_statusmediacap' AND $value != ''){ + $statusdraft = $value; + } else if ($key == 'id_statusmediabap' AND $value != ''){ + $statusdraft = $value; } else { - if ($key == 'id_statusmediatamlainnya' AND $value != ''){ - $statusdraft = $value; - } else if ($key == 'id_statusmediasellainnya' AND $value != ''){ - $statusdraft = $value; - } else if ($key == 'id_statusmediasda' AND $value != ''){ - $statusdraft = $value; - } else if ($key == 'id_statusmediamcconkey' AND $value != ''){ - $statusdraft = $value; - } else if ($key == 'id_statusmediacap' AND $value != ''){ - $statusdraft = $value; - } else if ($key == 'id_statusmediabap' AND $value != ''){ - $statusdraft = $value; + } + KomponenJawaban::updateOrCreate( + [ + 'accnumber' => $nofoto, + 'komponen' => $key, + ], + [ + 'isidata' => $value, + 'template' => $dlp, + 'created_by' => session('nama'), + ] + ); + } + $yangperludicloning = ''; + if ($dlp == 'Kultur'){ + if ($key == 'id_selepitel'){ $yangperludicloning = 'lsg_selepitel'; } + if ($key == 'id_selradang'){ $yangperludicloning = 'lsg_selradang'; } + if ($key == 'id_mikroorganisme'){ $yangperludicloning = 'lsg_mikroorganisme'; } + if ($key == 'id_mikroorganismeoptional'){ $yangperludicloning = 'lsg_mikroorganismeoptional'; } + if ($key == 'id_pewarnaanziehlnielsen'){ $yangperludicloning = 'lsg_pewarnaanziehlnielsen'; } + if ($key == 'id_pewarnaanziehlnielsensewaktu'){ $yangperludicloning = 'lsg_pewarnaanziehlnielsensewaktu'; } + if ($key == 'id_pewarnaankoh'){ $yangperludicloning = 'lsg_pewarnaankoh'; } + if ($key == 'id_pewarnaankohoptional'){ $yangperludicloning = 'lsg_pewarnaankohoptional'; } + if ($key == 'id_pewarnaanneisser'){ $yangperludicloning = 'lsg_pewarnaanneisser'; } + if ($key == 'id_pewarnaannegatif'){ $yangperludicloning = 'lsg_pewarnaannegatif'; } + if ($key == 'id_pewarnaanspora'){ $yangperludicloning = 'lsg_pewarnaanspora'; } + if ($key == 'id_pewarnaangiesma'){ $yangperludicloning = 'lsg_pewarnaangiesma'; } + if ($key == 'id_pewarnaangiesmaoptional'){ $yangperludicloning = 'lsg_pewarnaangiesmaoptional'; } + } else { + if ($key == 'lsg_selepitel'){ $yangperludicloning = 'id_selepitel'; } + if ($key == 'lsg_selradang'){ $yangperludicloning = 'id_selradang'; } + if ($key == 'lsg_mikroorganisme'){ $yangperludicloning = 'id_mikroorganisme'; } + if ($key == 'lsg_mikroorganismeoptional'){ $yangperludicloning = 'id_mikroorganismeoptional'; } + if ($key == 'lsg_pewarnaanziehlnielsen'){ $yangperludicloning = 'id_pewarnaanziehlnielsen'; } + if ($key == 'lsg_pewarnaanziehlnielsensewaktu'){ $yangperludicloning = 'id_pewarnaanziehlnielsensewaktu'; } + if ($key == 'lsg_pewarnaankoh'){ $yangperludicloning = 'id_pewarnaankoh'; } + if ($key == 'lsg_pewarnaankohoptional'){ $yangperludicloning = 'id_pewarnaankohoptional'; } + if ($key == 'lsg_pewarnaanneisser'){ $yangperludicloning = 'id_pewarnaanneisser'; } + if ($key == 'lsg_pewarnaannegatif'){ $yangperludicloning = 'id_pewarnaannegatif'; } + if ($key == 'lsg_pewarnaanspora'){ $yangperludicloning = 'id_pewarnaanspora'; } + if ($key == 'lsg_pewarnaangiesma'){ $yangperludicloning = 'id_pewarnaangiesma'; } + if ($key == 'lsg_pewarnaangiesmaoptional'){ $yangperludicloning = 'id_pewarnaangiesmaoptional'; } + } + if ($nm_spesimen == 'SPUTUM' AND !empty($cekganda) AND $yangperludicloning != ''){ + foreach($cekganda as $rcloning){ + $nofotocloning = $rcloning->nofoto; + $dlpcloning = $rcloning->dlp ?? 'Kultur'; + if (is_array($value)) { + KomponenJawaban::updateOrCreate( + [ + 'accnumber' => $nofotocloning, + 'komponen' => $yangperludicloning, + ], + [ + 'isidata' => json_encode($value), + 'template' => $dlpcloning, + 'created_by' => session('nama'), + ] + ); } else { - } - KomponenJawaban::updateOrCreate( - [ - 'accnumber' => $nofoto, - 'komponen' => $key, - ], - [ - 'isidata' => $value, - 'template' => $dlp, - 'created_by' => session('nama'), - ] - ); - } - $yangperludicloning = ''; - if ($dlp == 'Kultur'){ - if ($key == 'id_selepitel'){ $yangperludicloning = 'lsg_selepitel'; } - if ($key == 'id_selradang'){ $yangperludicloning = 'lsg_selradang'; } - if ($key == 'id_mikroorganisme'){ $yangperludicloning = 'lsg_mikroorganisme'; } - if ($key == 'id_mikroorganismeoptional'){ $yangperludicloning = 'lsg_mikroorganismeoptional'; } - if ($key == 'id_pewarnaanziehlnielsen'){ $yangperludicloning = 'lsg_pewarnaanziehlnielsen'; } - if ($key == 'id_pewarnaanziehlnielsensewaktu'){ $yangperludicloning = 'lsg_pewarnaanziehlnielsensewaktu'; } - if ($key == 'id_pewarnaankoh'){ $yangperludicloning = 'lsg_pewarnaankoh'; } - if ($key == 'id_pewarnaankohoptional'){ $yangperludicloning = 'lsg_pewarnaankohoptional'; } - if ($key == 'id_pewarnaanneisser'){ $yangperludicloning = 'lsg_pewarnaanneisser'; } - if ($key == 'id_pewarnaannegatif'){ $yangperludicloning = 'lsg_pewarnaannegatif'; } - if ($key == 'id_pewarnaanspora'){ $yangperludicloning = 'lsg_pewarnaanspora'; } - if ($key == 'id_pewarnaangiesma'){ $yangperludicloning = 'lsg_pewarnaangiesma'; } - if ($key == 'id_pewarnaangiesmaoptional'){ $yangperludicloning = 'lsg_pewarnaangiesmaoptional'; } - } else { - if ($key == 'lsg_selepitel'){ $yangperludicloning = 'id_selepitel'; } - if ($key == 'lsg_selradang'){ $yangperludicloning = 'id_selradang'; } - if ($key == 'lsg_mikroorganisme'){ $yangperludicloning = 'id_mikroorganisme'; } - if ($key == 'lsg_mikroorganismeoptional'){ $yangperludicloning = 'id_mikroorganismeoptional'; } - if ($key == 'lsg_pewarnaanziehlnielsen'){ $yangperludicloning = 'id_pewarnaanziehlnielsen'; } - if ($key == 'lsg_pewarnaanziehlnielsensewaktu'){ $yangperludicloning = 'id_pewarnaanziehlnielsensewaktu'; } - if ($key == 'lsg_pewarnaankoh'){ $yangperludicloning = 'id_pewarnaankoh'; } - if ($key == 'lsg_pewarnaankohoptional'){ $yangperludicloning = 'id_pewarnaankohoptional'; } - if ($key == 'lsg_pewarnaanneisser'){ $yangperludicloning = 'id_pewarnaanneisser'; } - if ($key == 'lsg_pewarnaannegatif'){ $yangperludicloning = 'id_pewarnaannegatif'; } - if ($key == 'lsg_pewarnaanspora'){ $yangperludicloning = 'id_pewarnaanspora'; } - if ($key == 'lsg_pewarnaangiesma'){ $yangperludicloning = 'id_pewarnaangiesma'; } - if ($key == 'lsg_pewarnaangiesmaoptional'){ $yangperludicloning = 'id_pewarnaangiesmaoptional'; } - } - if ($nm_spesimen == 'SPUTUM' AND !empty($cekganda) AND $yangperludicloning != ''){ - foreach($cekganda as $rcloning){ - $nofotocloning = $rcloning->nofoto; - $dlpcloning = $rcloning->dlp ?? 'Kultur'; - if (is_array($value)) { - KomponenJawaban::updateOrCreate( - [ - 'accnumber' => $nofotocloning, - 'komponen' => $yangperludicloning, - ], - [ - 'isidata' => json_encode($value), - 'template' => $dlpcloning, - 'created_by' => session('nama'), - ] - ); - } else { - KomponenJawaban::updateOrCreate( - [ - 'accnumber' => $nofotocloning, - 'komponen' => $yangperludicloning, - ], - [ - 'isidata' => $value, - 'template' => $dlpcloning, - 'created_by' => session('nama'), - ] - ); - } + KomponenJawaban::updateOrCreate( + [ + 'accnumber' => $nofotocloning, + 'komponen' => $yangperludicloning, + ], + [ + 'isidata' => $value, + 'template' => $dlpcloning, + 'created_by' => session('nama'), + ] + ); } } } - $analis = $request->input('analis'); - $ppds3 = $request->input('ppds3'); - $cekdokter = optional(User::find($iddokter)); - $cekanalis = optional(User::find($analis)); - $cekppds3 = optional(User::find($ppds3)); - switch ($kerja) { - case 'verifikasi': - if ($periksa->status != 'Selesai'){ - $tglverifikasi = date('Y-m-d H:i:s'); - } - $updateData = [ - 'keterangan' => $keterangan, - 'dlp' => $dlp, - 'analis' => $analis, - 'nmanalis' => $cekanalis->nama ?? null, - 'dokter_id' => Session('id'), - 'nmdokter' => Session('nama'), - 'ppdssenior' => $ppds3, - 'nmppdssenior' => $cekppds3->nama ?? null, - 'tandatangan' => '', - 'verifikasi' => $tglverifikasi, - 'akhir' => $tglverifikasi, - 'nmexcutor' => Session('nama'), - 'excutor' => Session('id'), - 'status' => 'Selesai', - ]; - $periksa->update($updateData); - if ($this->shouldMarkAsCritical($request)) { - $this->upsertCriticalValueSample($periksa); - } - $surat = self::genSurat($periksa->id, 'dengan kop'); + } + $analis = $request->input('analis'); + $ppds3 = $request->input('ppds3'); + $cekdokter = optional(User::find($iddokter)); + $cekanalis = optional(User::find($analis)); + $cekppds3 = optional(User::find($ppds3)); + switch ($kerja) { + case 'verifikasi': + if ($periksa->status != 'Selesai'){ + $tglverifikasi = date('Y-m-d H:i:s'); + } + $updateData = [ + 'keterangan' => $keterangan, + 'dlp' => $dlp, + 'analis' => $analis, + 'nmanalis' => $cekanalis->nama ?? null, + 'dokter_id' => Session('id'), + 'nmdokter' => Session('nama'), + 'ppdssenior' => $ppds3, + 'nmppdssenior' => $cekppds3->nama ?? null, + 'tandatangan' => '', + 'verifikasi' => $tglverifikasi, + 'akhir' => $tglverifikasi, + 'nmexcutor' => Session('nama'), + 'excutor' => Session('id'), + 'status' => 'Selesai', + ]; + $periksa->update($updateData); + if ($this->shouldMarkAsCritical($request)) { + $this->upsertCriticalValueSample($periksa); + } + $surat = self::genSurat($periksa->id, 'dengan kop'); + Riwayat::create([ + 'nofoto' => $nofoto, + 'jawaban' => $surat, + 'inputor' => Session('nama'), + 'verifikasi' => 'Accepted', + 'keterangan' => 'Expertise', + ]); + if (isset($addendumketerangan) AND $addendumketerangan != ''){ Riwayat::create([ 'nofoto' => $nofoto, - 'jawaban' => $surat, + 'jawaban' => $addendumketerangan, 'inputor' => Session('nama'), 'verifikasi' => 'Accepted', - 'keterangan' => 'Expertise', + 'keterangan' => 'Addendum', ]); - if (isset($addendumketerangan) AND $addendumketerangan != ''){ - Riwayat::create([ - 'nofoto' => $nofoto, - 'jawaban' => $addendumketerangan, - 'inputor' => Session('nama'), - 'verifikasi' => 'Accepted', - 'keterangan' => 'Addendum', - ]); - } - if (is_null($nofoto)){ - return response()->json(['icon' => 'success', 'warna' => '#5ba035', 'status' => 'Sukses', 'message' => 'Expertise Verified']); - } else { - $pesan = 'Expertise Saved'; - return response()->json(['icon' => 'success', 'warna' => '#5ba035', 'status' => 'Sukses', 'message' => $pesan]); - } - case 'statuspewarnaanlsg': - $periksa->update([ - 'keterangan' => $keterangan, - 'dlp' => $dlp, - 'analis' => $analis, - 'nmanalis' => $cekanalis->nama ?? null, - 'nmdrafter' => Session('nama'), - 'nmexcutor' => Session('nama'), - 'excutor' => Session('id'), - 'status' => 'Pewarnaan Langsung' - ]); - return response()->json(['icon' => 'success', 'status' => 'Success', 'message' => 'Set Status Pewarnaan Langsung']); - case 'preliminary': - $updateData = [ - 'keterangan' => $keterangan, - 'dlp' => $dlp, - 'analis' => $analis, - 'nmanalis' => $cekanalis->nama ?? null, - 'dokter_id' => Session('id'), - 'nmdokter' => Session('nama'), - 'ppdssenior' => $ppds3, - 'nmppdssenior' => $cekppds3->nama ?? null, - 'tandatangan' => '', - 'verifikasi' => $tglverifikasi, - 'nmexcutor' => Session('nama'), - 'excutor' => Session('id'), - 'status' => 'Preliminary Results', - ]; - $periksa->update($updateData); - if ($this->shouldMarkAsCritical($request)) { - $this->upsertCriticalValueSample($periksa); - } - $surat = self::genSurat($periksa->id, 'dengan kop'); - Riwayat::create([ - 'nofoto' => $nofoto, - 'jawaban' => $surat, - 'inputor' => Session('nama'), - 'verifikasi' => 'Accepted', - 'keterangan' => 'Preliminary Results', - ]); - $pesan = 'Preliminary Results Saved'; + } + if (is_null($nofoto)){ + return response()->json(['icon' => 'success', 'warna' => '#5ba035', 'status' => 'Sukses', 'message' => 'Expertise Verified']); + } else { + $pesan = 'Expertise Saved'; return response()->json(['icon' => 'success', 'warna' => '#5ba035', 'status' => 'Sukses', 'message' => $pesan]); - case 'Permohonan Verifikasi': - $updateData = [ - 'keterangan' => $keterangan, - 'dlp' => $dlp, - 'analis' => $analis, - 'nmanalis' => $cekanalis->nama ?? null, - 'dokter_id' => $iddokter, - 'nmdokter' => $cekdokter->nama ?? null, - 'ppdssenior' => $ppds3, - 'nmppdssenior' => $cekppds3->nama ?? null, - 'tandatangan' => '', - 'baca' => $today, - 'nmexcutor' => Session('nama'), - 'excutor' => Session('id'), - 'nmpembaca' => Session('nama'), - 'status' => 'Expertise Saved (Un Verified)', - ]; - $periksa->update($updateData); - $surat = self::genSurat($periksa->id, 'dengan kop'); - Riwayat::create([ - 'nofoto' => $nofoto, - 'jawaban' => $surat, - 'inputor' => Session('nama'), + } + case 'statuspewarnaanlsg': + $periksa->update([ + 'keterangan' => $keterangan, + 'dlp' => $dlp, + 'analis' => $analis, + 'nmanalis' => $cekanalis->nama ?? null, + 'nmdrafter' => Session('nama'), + 'nmexcutor' => Session('nama'), + 'excutor' => Session('id'), + ]); + return response()->json(['icon' => 'success', 'status' => 'Success', 'message' => 'Set Status Pewarnaan Langsung']); + case 'preliminary': + $updateData = [ + 'keterangan' => $keterangan, + 'dlp' => $dlp, + 'analis' => $analis, + 'nmanalis' => $cekanalis->nama ?? null, + 'dokter_id' => Session('id'), + 'nmdokter' => Session('nama'), + 'ppdssenior' => $ppds3, + 'nmppdssenior' => $cekppds3->nama ?? null, + 'tandatangan' => '', + 'verifikasi' => $tglverifikasi, + 'nmexcutor' => Session('nama'), + 'excutor' => Session('id'), + 'status' => 'Preliminary Results', + ]; + $periksa->update($updateData); + if ($this->shouldMarkAsCritical($request)) { + $this->upsertCriticalValueSample($periksa); + } + $surat = self::genSurat($periksa->id, 'dengan kop'); + Riwayat::create([ + 'nofoto' => $nofoto, + 'jawaban' => $surat, + 'inputor' => Session('nama'), + 'verifikasi' => 'Accepted', + 'keterangan' => 'Preliminary Results', + ]); + $pesan = 'Preliminary Results Saved'; + return response()->json(['icon' => 'success', 'warna' => '#5ba035', 'status' => 'Sukses', 'message' => $pesan]); + case 'Permohonan Verifikasi': + $updateData = [ + 'keterangan' => $keterangan, + 'dlp' => $dlp, + 'analis' => $analis, + 'nmanalis' => $cekanalis->nama ?? null, + 'dokter_id' => $iddokter, + 'nmdokter' => $cekdokter->nama ?? null, + 'ppdssenior' => $ppds3, + 'nmppdssenior' => $cekppds3->nama ?? null, + 'tandatangan' => '', + 'baca' => $today, + 'nmexcutor' => Session('nama'), + 'excutor' => Session('id'), + 'nmpembaca' => Session('nama'), + 'status' => 'Expertise Saved (Un Verified)', + ]; + $periksa->update($updateData); + $surat = self::genSurat($periksa->id, 'dengan kop'); + Riwayat::create([ + 'nofoto' => $nofoto, + 'jawaban' => $surat, + 'inputor' => Session('nama'), + 'verifikasi' => 'Accepted', + 'keterangan' => 'Kirim ke SPV', + ]); + return response()->json(['icon' => 'success', 'warna' => '#5ba035', 'status' => 'Sukses', 'message' => 'Permohonan Verifikasi Terkirim']); + case 'tolakadendum': + Riwayat::where('nofoto', $nofoto)->whereNull('verifikasi')->update([ + 'verifikasi' => 'Declined', + ]); + return response()->json(['icon' => 'success', 'status' => 'Success', 'message' => 'Addendum Declined']); + case 'Draft': + $periksa->update([ + 'keterangan' => $keterangan, + 'dlp' => $dlp, + 'analis' => $analis, + 'nmanalis' => $cekanalis->nama ?? null, + 'nmdrafter' => Session('nama'), + 'nmexcutor' => Session('nama'), + 'excutor' => Session('id'), + 'status' => $statusdraft + ]); + $surat = self::genSurat($periksa->id, 'dengan kop'); + Riwayat::create([ + 'nofoto' => $nofoto, + 'jawaban' => $surat, + 'inputor' => Session('nama'), + 'verifikasi' => '', + 'keterangan' => 'Draft', + ]); + return response()->json(['icon' => 'success', 'status' => 'Success', 'message' => 'Draft Expertise Saved']); + case 'terimadendum': + $getid = Riwayat::where('keterangan', 'Adendum')->where('nofoto', $nofoto)->whereNull('verifikasi')->first(); + if (isset($getid->id)){ + Riwayat::where('id', $getid->id)->update([ 'verifikasi' => 'Accepted', - 'keterangan' => 'Kirim ke SPV', ]); - return response()->json(['icon' => 'success', 'warna' => '#5ba035', 'status' => 'Sukses', 'message' => 'Permohonan Verifikasi Terkirim']); - case 'tolakadendum': - Riwayat::where('nofoto', $nofoto)->whereNull('verifikasi')->update([ - 'verifikasi' => 'Declined', - ]); - return response()->json(['icon' => 'success', 'status' => 'Success', 'message' => 'Addendum Declined']); - case 'Draft': - $periksa->update([ - 'keterangan' => $keterangan, - 'dlp' => $dlp, - 'analis' => $analis, - 'nmanalis' => $cekanalis->nama ?? null, - 'nmdrafter' => Session('nama'), + Periksa::where('nofoto', $getid->nofoto)->update([ 'nmexcutor' => Session('nama'), 'excutor' => Session('id'), - 'status' => $statusdraft + 'tgladendum' => now(), + 'keterangan' => $getid->jawaban ]); - $surat = self::genSurat($periksa->id, 'dengan kop'); - Riwayat::create([ - 'nofoto' => $nofoto, - 'jawaban' => $surat, - 'inputor' => Session('nama'), - 'verifikasi' => '', - 'keterangan' => 'Draft', - ]); - return response()->json(['icon' => 'success', 'status' => 'Success', 'message' => 'Draft Expertise Saved']); - case 'terimadendum': - $getid = Riwayat::where('keterangan', 'Adendum')->where('nofoto', $nofoto)->whereNull('verifikasi')->first(); - if (isset($getid->id)){ - Riwayat::where('id', $getid->id)->update([ - 'verifikasi' => 'Accepted', - ]); - Periksa::where('nofoto', $getid->nofoto)->update([ - 'nmexcutor' => Session('nama'), - 'excutor' => Session('id'), - 'tgladendum' => now(), - 'keterangan' => $getid->jawaban - ]); - return response()->json(['icon' => 'success', 'status' => 'Success', 'message' => 'Addendum Accepted']); - } else { - return response()->json(['icon' => 'error', 'status' => 'Gagal', 'message' => 'Addendum Data Cannot Be Found']); - } - default: - $periksa->update([ - 'keterangan' => $keterangan, - 'dlp' => $dlp, - 'analis' => $analis, - 'nmanalis' => $cekanalis->nama ?? null, - 'dokter_id' => $iddokter, - 'nmdokter' => $cekdokter->nama ?? null, - 'ppdssenior' => $ppds3, - 'nmppdssenior' => $cekppds3->nama ?? null, - 'nmdrafter' => Session('nama'), - 'nmexcutor' => Session('nama'), - 'excutor' => Session('id'), - 'status' => $statusdraft - ]); - return response()->json(['icon' => 'success', 'status' => 'Success', 'message' => 'Expertise Saved']); - } + return response()->json(['icon' => 'success', 'status' => 'Success', 'message' => 'Addendum Accepted']); + } else { + return response()->json(['icon' => 'error', 'status' => 'Gagal', 'message' => 'Addendum Data Cannot Be Found']); + } + default: + $periksa->update([ + 'keterangan' => $keterangan, + 'dlp' => $dlp, + 'analis' => $analis, + 'nmanalis' => $cekanalis->nama ?? null, + 'dokter_id' => $iddokter, + 'nmdokter' => $cekdokter->nama ?? null, + 'ppdssenior' => $ppds3, + 'nmppdssenior' => $cekppds3->nama ?? null, + 'nmdrafter' => Session('nama'), + 'nmexcutor' => Session('nama'), + 'excutor' => Session('id'), + 'status' => $statusdraft + ]); + return response()->json(['icon' => 'success', 'status' => 'Success', 'message' => 'Expertise Saved']); } } protected function shouldMarkAsCritical(Request $request): bool @@ -1245,64 +1239,59 @@ class DokterController extends Controller $cekdatanmaddendum = Periksa::where('nofoto', $nofoto)->first(); $tgldaftarpasangan = $cekdatanmaddendum->daftar ?? ''; $nmadendum = $cekdatanmaddendum->nmadendum ?? ''; - /* - sudah OK tinggal di uncoment saja klo perlu cloning data dari pasangan - if ($nmadendum != ''){ - $getdatapasangannya = Periksa::where('nmadendum', $nmadendum)->where('nm_spesimen', 'SPUTUM')->where('nofoto', '!=', $nofoto)->get(); + $getdatapasangannya = Periksa::where('nmadendum', $nmadendum)->where('nofoto', '!=', $nofoto)->get(); + if (!empty($getdatapasangannya)){ foreach ($getdatapasangannya as $item){ $datayangperludicloning = KomponenJawaban::where('accnumber', $item->nofoto)->get(); foreach ($datayangperludicloning as $rclone){ - $ceksudahcloning = KomponenJawaban::where('accnumber', $nofoto) - ->where('komponen', $rclone->komponen) - ->where('template', $ruangan)->count(); - if ($ceksudahcloning == 0){ - $komponen = ''; - if ($rclone->komponen == 'lsg_selepitel'){ - $komponen = 'id_selepitel'; - } - if ($rclone->komponen == 'id_selepitel'){ - $komponen = 'lsg_selepitel'; - } - if ($rclone->komponen == 'lsg_selradang'){ - $komponen = 'id_selradang'; - } - if ($rclone->komponen == 'id_selradang'){ - $komponen = 'lsg_selradang'; - } - if ($rclone->komponen == 'lsg_mikroorganisme'){ - $komponen = 'id_mikroorganisme'; - } - if ($rclone->komponen == 'id_mikroorganisme'){ - $komponen = 'lsg_mikroorganisme'; - } - if ($rclone->komponen == 'lsg_mikroorganismeoptional'){ - $komponen = 'id_mikroorganismeoptional'; - } - if ($rclone->komponen == 'id_mikroorganismeoptional'){ - $komponen = 'lsg_mikroorganismeoptional'; - } - if ($rclone->komponen == 'lsg_mikroorganismeoptional'){ - $komponen = 'id_mikroorganismeoptional'; - } - if ($rclone->komponen == 'id_mikroorganismeoptional'){ - $komponen = 'lsg_mikroorganismeoptional'; - } - if ($komponen != ''){ - KomponenJawaban::create([ - 'accnumber' => $nofoto, - 'template' => $ruangan, - 'komponen' => $komponen, - 'isidata' => $rclone->isidata, - 'created_by' => Session('nama') - ]); - } - + $komponenterclone = ''; + if ($rclone->komponen == 'lsg_selepitel'){ + $komponenterclone = 'id_selepitel'; + } + if ($rclone->komponen == 'id_selepitel'){ + $komponenterclone = 'lsg_selepitel'; + } + if ($rclone->komponen == 'lsg_selradang'){ + $komponenterclone = 'id_selradang'; + } + if ($rclone->komponen == 'id_selradang'){ + $komponenterclone = 'lsg_selradang'; + } + if ($rclone->komponen == 'lsg_mikroorganisme'){ + $komponenterclone = 'id_mikroorganisme'; + } + if ($rclone->komponen == 'id_mikroorganisme'){ + $komponenterclone = 'lsg_mikroorganisme'; + } + if ($rclone->komponen == 'lsg_mikroorganismeoptional'){ + $komponenterclone = 'id_mikroorganismeoptional'; + } + if ($rclone->komponen == 'id_mikroorganismeoptional'){ + $komponenterclone = 'lsg_mikroorganismeoptional'; + } + if ($rclone->komponen == 'lsg_mikroorganismeoptional'){ + $komponenterclone = 'id_mikroorganismeoptional'; + } + $ceksudahcloning = KomponenJawaban::where('accnumber', $rclone->accnumber)->where('komponen', $komponenterclone)->count(); + if ($ceksudahcloning == 0 AND $komponenterclone != ''){ + KomponenJawaban::create([ + 'accnumber' => $rclone->accnumber, + 'template' => $ruangan, + 'komponen' => $komponenterclone, + 'isidata' => $rclone->isidata, + 'created_by' => Session('nama') + ]); + Riwayat::create([ + 'nofoto' => $rclone->accnumber, + 'jawaban' => $rclone->isidata, + 'inputor' => Session('nama'), + 'keterangan' => 'Clone Data '.$komponenterclone.' Dari ('.$nofoto.')', + 'verifikasi' => '', + ]); } } } } - - */ KomponenJawaban::where('accnumber', $nofoto)->where('template', 'all')->update([ 'template' => $ruangan, ]); @@ -2309,96 +2298,6 @@ class DokterController extends Controller ]); } return $pesan; - } else if ($worklist == 'getbbachtect' OR $worklist == 'getmgit' OR $worklist == 'getabbot'){ - $isidata = $request->input('isi'); - try { - $ketemu = ''; - $nomor = 1; - $cekdatalangsung = DataListiner::where('no_id', $nofoto)->whereIn('alat', ['BD Mikro 1', 'BD Mikro 2'])->first(); - $ketemu = $cekdatalangsung->organisme ?? ''; - if ($ketemu == ''){ - $cekada = ResultSample::where('accession_number', 'LIKE', $nofoto.'%')->get(); - if (!empty($cekada)){ - foreach($cekada as $rows){ - $ketemu = $rows->test_status; - } - } else { - $cekdata = DB::table('lis_phoenix')->where('no_id', $nofoto)->first(); - $ketemu = $cekdata->organisme ?? ''; - } - } - - if ($ketemu != ''){ - if ($isidata == '' OR is_null($isidata)){ - $isidata = $ketemu; - } else { - $isidata = $isidata.'
'.$ketemu; - } - } else { - - } - if ($isidata == '' OR is_null($isidata)){ - - } else { - KomponenJawaban::updateOrCreate( - [ - 'accnumber' => $nofoto, - 'template' => $request->input('jenis'), - 'komponen' => $request->input('komponen'), - ], - [ - 'isidata' => $isidata, - 'created_by' => Session('nama') - ] - ); - } - $pesan = $isidata; - }catch (Exception $e) { - $pesan = $isidata.'
'.$e->getMessage(); - } - return $pesan; - } else if ($worklist == 'getgenexpert'){ - $isidata = $request->input('isi'); - try { - $cekdata = Periksa::where('nofoto', $nofoto)->first(); - $noregister = $cekdata->noregister ?? ''; - $url = 'http://10.10.120.14:6002/api/genexpert/query-result'; - - $response = Http::withHeaders([ - 'Content-Type' => 'application/json', - 'Accept' => 'application/json', - ])->timeout(30) - ->post($url, [ - 'accnumber' => $nofoto, - 'register_no' => $noregister, - ]); - $body = $response->json(); - $errorMessage = $body['message'] ?? 'Unknown Error'; - $details = json_decode($errorMessage, true); - if (json_last_error() === JSON_ERROR_NONE && isset($details['message'])) { - $pesan = $details['message']; - } else { - $pesan = $errorMessage; - } - if ($response->successful()) { - Log::info('requestResult.', [ - 'status' => $response->status(), - 'message' => $response->json() - ]); - } - - Log::error('Exception dalam fungsi requestResult.', [ - 'status' => $response->status(), - 'message' => 'Python Server Error: ' . $response->body() - ]); - } catch (Exception $e) { - $pesan = (is_null($isidata) ? '' : $isidata . '
') . 'Error: ' . $e->getMessage(); - Log::error('Exception dalam fungsi requestResult.', [ - 'sample_id' => $nofoto, - 'exception' => $e->getMessage() - ]); - } - return response($pesan, 200); } else if ($worklist == 'addviralload'){ $tabelawal = $request->input('tabelawal'); $idtabel = $request->input('idtabel'); @@ -2526,7 +2425,7 @@ class DokterController extends Controller } else if ($worklist == 'generatetblpertumbuhankoloni'){ $orderid = $request->input('nofoto'); $media = $request->input('komponen'); - $sql = DB::table('pertumkolomni')->where('orderid', $orderid)->where('media', $media)->get(); + $sql = DB::table('pertumkolomni')->where('orderid', $orderid)->where('media', $media)->orderBy('id', 'asc')->get(); return $sql; } else { $periksa = Periksa::where('id', $idperiksa)->first(); diff --git a/htdocs/app/Http/Controllers/ReportController.php b/htdocs/app/Http/Controllers/ReportController.php index 6e6f67ea..5aae0f19 100644 --- a/htdocs/app/Http/Controllers/ReportController.php +++ b/htdocs/app/Http/Controllers/ReportController.php @@ -1136,7 +1136,6 @@ class ReportController extends Controller } public function genTATreport(Request $request) { - $data = []; $bulan = $request->input('bulan'); $tahun = $request->input('tahun'); if ($tahun == '' OR is_null($tahun)){ @@ -1146,59 +1145,55 @@ class ReportController extends Controller $bulan = str_replace('bulan=', '', $bulan); $tahun = str_replace('tahun=', '', $tahun); } - $query = Periksa::select('*'); - if ($bulan !== 'ALL') { - $query->whereMonth('mulai', $bulan); - } - $periksa = $query->whereYear('mulai', $tahun)->orderBy('mulai', 'ASC')->get(); + $startDate = $bulan === 'ALL' + ? Carbon::createFromDate((int) $tahun, 1, 1)->startOfYear() + : Carbon::createFromDate((int) $tahun, (int) $bulan, 1)->startOfMonth(); + $endDate = $bulan === 'ALL' + ? Carbon::createFromDate((int) $tahun, 1, 1)->endOfYear() + : Carbon::createFromDate((int) $tahun, (int) $bulan, 1)->endOfMonth(); - if ($periksa->count() == 0) { + $query = DB::table('periksa') + ->leftJoin('poli', 'poli.id', '=', 'periksa.poli_id') + ->select('periksa.id', 'periksa.kd_spesimen', 'periksa.mulai', 'periksa.verifikasi', 'poli.modaliti2') + ->whereBetween('periksa.mulai', [$startDate->toDateTimeString(), $endDate->toDateTimeString()]); + + $rekapRows = []; + $query->chunkById(1000, function ($rows) use (&$rekapRows) { + foreach ($rows as $row) { + $key = $row->kd_spesimen ?: '-'; + if (!isset($rekapRows[$key])) { + $rekapRows[$key] = [ + 'jenis_pemeriksaan' => $key, + 'memenuhi' => 0, + 'tidak_memenuhi' => 0, + 'tidak_ada_hasil' => 0, + 'total' => 0, + ]; + } + + if (empty($row->verifikasi)) { + $rekapRows[$key]['tidak_ada_hasil']++; + } else { + $target = $this->resolveTatTargetDays($row->modaliti2 ?? '1'); + $status = $this->resolveTatStatus($row->mulai, $row->verifikasi, $target); + if ($status === 'MEMENUHI TARGET') { + $rekapRows[$key]['memenuhi']++; + } else { + $rekapRows[$key]['tidak_memenuhi']++; + } + } + $rekapRows[$key]['total']++; + } + }, 'periksa.id', 'id'); + + if (empty($rekapRows)) { return response()->json([]); } - $accnumbers = $periksa->pluck('nofoto')->toArray(); - $komponen = DB::table('db_komponenjawaban')->whereIn('accnumber', $accnumbers)->whereIn('komponen', ['id_bakteri01','id_bakteri02','id_mikroorganisme'])->get()->groupBy('accnumber'); - $poli = DB::table('poli')->whereIn('id', $periksa->pluck('poli_id'))->get()->keyBy('id'); - $hasil = $periksa->map(function($row) use ($komponen, $poli){ - $k = $komponen[$row->nofoto] ?? collect([]); - $row->id_bakteri01 = optional($k->firstWhere('komponen', 'id_bakteri01'))->isidata; - $row->id_bakteri02 = optional($k->firstWhere('komponen', 'id_bakteri02'))->isidata; - $row->bakteri = optional($k->firstWhere('komponen', 'bakteri'))->isidata; - $row->filefoto = "nofoto)."'>$row->nofoto"; - $p = $poli[$row->poli_id] ?? null; - $row->subpoli = $p->subpoli ?? null; - $target = $p->modaliti2 ?? '1'; - $row->modaliti2 = $target; - if (!empty($row->verifikasi)) { - $selisih_hari = Carbon::parse($row->mulai)->diffInDays(Carbon::parse($row->verifikasi)); - $target = intval($target); - $hari = intval($selisih_hari); - $row->selisih_hari = $selisih_hari; - if ($hari <= $target) { - $row->status_target = "MEMENUHI TARGET"; - } else { - $row->status_target = "TIDAK MEMENUHI TARGET"; - } - } else { - $row->selisih_hari = null; - $row->status_target = "TIDAK ADA HASIL"; - } - return $row; - }); - $rekap = $hasil->groupBy('kd_spesimen')->map(function($group){ - return [ - 'jenis_pemeriksaan' => $group->first()->kd_spesimen, - 'memenuhi' => $group->where('status_target', 'MEMENUHI TARGET')->count(), - 'tidak_memenuhi' => $group->where('status_target', 'TIDAK MEMENUHI TARGET')->count(), - 'tidak_ada_hasil' => $group->where('status_target', 'TIDAK ADA HASIL')->count(), - 'total' => $group->count() - ]; - - })->values(); + $rekap = collect(array_values($rekapRows)); return view('cetak.tatreport', [ 'bulan' => $bulan, 'tahun' => $tahun, - 'detail' => $hasil, 'rekap' => $rekap ]); } diff --git a/htdocs/app/Livewire/BiorepositoryVisual.php b/htdocs/app/Livewire/BiorepositoryVisual.php new file mode 100644 index 00000000..a2c59350 --- /dev/null +++ b/htdocs/app/Livewire/BiorepositoryVisual.php @@ -0,0 +1,101 @@ +selectedCabinetId = BioCabinet::orderBy('name', 'ASC')->value('id'); + } + + public function selectCabinet(int $cabinetId): void + { + $this->selectedCabinetId = $cabinetId; + $this->selectedRackId = null; + $this->resetPosition(); + } + + public function selectRack(int $rackId): void + { + $this->selectedRackId = $rackId; + $this->resetPosition(); + } + + public function selectSlot(int $slot): void + { + $this->selectedSlot = $slot; + $this->selectedShelf = null; + $this->selectedBox = null; + } + + public function selectShelf(int $shelf): void + { + $this->selectedShelf = $shelf; + $this->selectedBox = null; + } + + public function selectBox(int $box): void + { + $this->selectedBox = $box; + } + + public function render() + { + $cabinets = BioCabinet::withCount(['racks', 'specimens']) + ->orderBy('name', 'ASC') + ->get(); + + if (!$this->selectedCabinetId && $cabinets->isNotEmpty()) { + $this->selectedCabinetId = (int) $cabinets->first()->id; + } + + $selectedCabinet = $this->selectedCabinetId + ? BioCabinet::with([ + 'racks' => function ($query) { + $query->withCount('specimens') + ->orderBy('rack_number', 'ASC') + ->orderBy('code', 'ASC'); + }, + ])->find($this->selectedCabinetId) + : null; + + $selectedRack = $this->selectedRackId + ? BioRack::with(['specimens' => function ($query) { + $query->orderBy('slot_number', 'ASC') + ->orderBy('shelf_number', 'ASC') + ->orderBy('box_number', 'ASC') + ->orderBy('tube_number', 'ASC'); + }])->find($this->selectedRackId) + : null; + + if ($selectedRack && (int) $selectedRack->cabinet_id !== (int) $this->selectedCabinetId) { + $selectedRack = null; + $this->selectedRackId = null; + $this->resetPosition(); + } + + return view('livewire.biorepository-visual', [ + 'cabinets' => $cabinets, + 'selectedCabinet' => $selectedCabinet, + 'selectedRack' => $selectedRack, + ]); + } + + private function resetPosition(): void + { + $this->selectedSlot = null; + $this->selectedShelf = null; + $this->selectedBox = null; + } +} diff --git a/htdocs/database/migrations/2026_06_25_000001_add_slot_count_to_bio_racks_table.php b/htdocs/database/migrations/2026_06_25_000001_add_slot_count_to_bio_racks_table.php new file mode 100644 index 00000000..e7844732 --- /dev/null +++ b/htdocs/database/migrations/2026_06_25_000001_add_slot_count_to_bio_racks_table.php @@ -0,0 +1,40 @@ +integer('slot_count')->default(1)->after('name'); + } + }); + + DB::table('bio_racks') + ->where(function ($query) { + $query->whereNull('slot_count') + ->orWhere('slot_count', '<=', 1); + }) + ->orderBy('id') + ->get(['id', 'level']) + ->each(function ($rack) { + DB::table('bio_racks') + ->where('id', $rack->id) + ->update(['slot_count' => max((int) ($rack->level ?? 1), 1)]); + }); + } + + public function down(): void + { + Schema::table('bio_racks', function (Blueprint $table) { + if (Schema::hasColumn('bio_racks', 'slot_count')) { + $table->dropColumn('slot_count'); + } + }); + } +}; diff --git a/htdocs/resources/views/admin/biorepository.blade.php b/htdocs/resources/views/admin/biorepository.blade.php index 0736c671..998e7326 100644 --- a/htdocs/resources/views/admin/biorepository.blade.php +++ b/htdocs/resources/views/admin/biorepository.blade.php @@ -17,6 +17,72 @@ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; } + .bio-step-panel { + border: 1px solid #d7e3ef; + border-radius: 8px; + background: #ffffff; + padding: 12px; + margin-bottom: 14px; + } + .bio-step-title { + font-weight: 700; + color: #1b3a57; + margin-bottom: 10px; + } + .bio-choice-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); + gap: 10px; + } + .bio-choice-wrap { + position: relative; + } + .bio-choice { + display: block; + width: 100%; + min-height: 92px; + border: 1px solid #d7e3ef; + border-radius: 6px; + background: #f8fbff; + color: #1b3a57; + text-align: left; + padding: 10px; + cursor: pointer; + } + .bio-choice strong, + .bio-choice span, + .bio-choice small { + display: block; + } + .bio-choice small { + color: #6c757d; + margin-top: 3px; + } + .bio-choice.active, + .bio-number.active { + border-color: #188ae2; + background: #eaf5ff; + box-shadow: inset 0 0 0 1px #188ae2; + } + .bio-delete-form { + position: absolute; + top: 8px; + right: 8px; + } + .bio-number-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); + gap: 8px; + } + .bio-number { + border: 1px solid #d7e3ef; + border-radius: 6px; + background: #f8fbff; + color: #1b3a57; + padding: 9px 6px; + cursor: pointer; + text-align: center; + } .rack-box { border: 1px solid #d7e3ef; border-radius: 10px; @@ -58,6 +124,7 @@ cursor: pointer; text-align: center; width: 100%; + min-height: 34px; } .slot-btn.slot-filled { background: #fce8e8; @@ -65,6 +132,10 @@ color: #8d1f1f; cursor: pointer; } + .slot-btn span, + .slot-btn small { + display: block; + } .oldest-highlight { border: 1px solid #ffd58f; background: #fff8ea; @@ -163,94 +234,10 @@
Belum ada data spesimen.
@endif -

Visualisasi Lemari, Rack, Shelf, Box, dan Tube

-

Klik nomor tube berwarna biru untuk mengisi spesimen. Tube merah artinya sudah terisi.

+

Visualisasi Lemari, Rack, Slot, Shelf, Box, dan Tube

+

Pilih posisi dari lemari sampai box. Tube biru bisa diisi, tube merah sudah terisi.

- @forelse($cabinets as $cabinet) -
-
-
{{ $cabinet->code }} - {{ $cabinet->name }} ({{ $cabinet->location ?? 'Lokasi belum diisi' }})
-
- @csrf - -
-
-
- @forelse($cabinet->racks as $rack) - @php - $tubeMap = []; - foreach ($rack->specimens as $item) { - if ($item->shelf_number && $item->tube_number) { - $tubeMap[$item->shelf_number.'-'.$item->tube_number] = $item; - } - } - $shelfCount = (int) $rack->level; - $tubeCapacity = (int) $rack->capacity; - @endphp -
-
-
{{ $rack->code }} - {{ $rack->name }}
-
- @csrf - -
-
-
Rack No {{ $rack->rack_number ?? $rack->id }} | Total Shelf {{ $shelfCount }} | 1 Box per Shelf | Tube per Box {{ $tubeCapacity }}
-
Terisi: {{ $rack->specimens->count() }}
- - @if($shelfCount > 0 && $tubeCapacity > 0) - @for($shelf = 1; $shelf <= $shelfCount; $shelf++) -
-
Shelf {{ $shelf }} - Box 1 (Tube 1-{{ $tubeCapacity }})
-
- @for($tube = 1; $tube <= $tubeCapacity; $tube++) - @php $tubeKey = $shelf.'-'.$tube; @endphp - @if(isset($tubeMap[$tubeKey])) - - @else - - @endif - @endfor -
-
- @endfor - @else -
Konfigurasi rack belum lengkap.
- @endif -
- @empty -
Belum ada rack pada lemari ini.
- @endforelse -
-
- @empty -
Belum ada data lemari biorepository.
- @endforelse + @livewire('biorepository-visual')
@@ -405,15 +392,25 @@
- + + +
+
+
+
+
+
+ + +
- Rack number dibuat otomatis oleh sistem. Struktur: 1 rack memiliki 4-6 shelf, setiap shelf memiliki 1 box, setiap box 16-100 tube. + Rack number dibuat otomatis oleh sistem. Struktur: lemari -> rack -> slot -> shelf -> box -> tube.
- +
- +
diff --git a/htdocs/resources/views/admin/report.blade.php b/htdocs/resources/views/admin/report.blade.php index 25c1c29a..cbd9c79f 100644 --- a/htdocs/resources/views/admin/report.blade.php +++ b/htdocs/resources/views/admin/report.blade.php @@ -666,7 +666,7 @@ $(document).ready(function () { type : 'error', }); } else { - var url = '{{url('/')}}/tatreport?bulan='+bulan+'?tahun='+tahun; + var url = '{{url('/')}}/tatreport?bulan='+bulan+'&tahun='+tahun; window.location.href = url; } }); diff --git a/htdocs/resources/views/dokter/pemeriksaan.blade.php b/htdocs/resources/views/dokter/pemeriksaan.blade.php index f9676015..f6f3bdfd 100644 --- a/htdocs/resources/views/dokter/pemeriksaan.blade.php +++ b/htdocs/resources/views/dokter/pemeriksaan.blade.php @@ -355,7 +355,7 @@ @php foreach($mikroorganismes[$keys[$i]] as $key => $value) { @endphp - + @php } @endphp @@ -575,142 +575,103 @@
- -
-
- -
-
- -
-
- -
-
-
-
- -
-
- -
-
- -
-
-
-
- -
-
- -
-
- -
-
-
-
- -
-
- -
-
- -
-
-
-
-
-
- -
-
- -
-
- -
-
-
- -
+ + + + + + + + + + + + + + + + + + + + +
Kirby bauer
AMCAKFOSSCF
+ + + + + + + + + + + + + + + +
@@ -727,38 +688,85 @@ C. Tes Kepekaan Antibiotika: (S: Sensitif ; I : Intermediate ; R: Resisten)
- +
+
+
+
+
Ringkasan Hasil Terakhir
+
Diperbaharui :
+
+
+
+
+ +
Media BAP
+

-

+ - +
+
+
+
+ +
Media CAP
+

-

+ - +
+
+
+
+ +
Mc Conkey
+

-

+ - +
+
+
+
+ +
Media Jamur
+

-

+ - +
+
+
+
+
+ +
+
@@ -1070,7 +1078,7 @@ @php foreach($mikroorganismes[$keys[$i]] as $key => $value) { @endphp - + @php } @endphp @@ -2113,6 +2121,7 @@
+
+
+
+
+
+
Ringkasan Hasil Terakhir
+
Diperbaharui :
+
+
+
+
+ +
Media BAP
+

-

+ - +
+
+
+
+ +
Media CAP
+

-

+ - +
+
+
+
+ +
Mc Conkey
+

-

+ - +
+
+
+
+ +
Media Jamur
+

-

+ - +
+
+
+
+
+ +
@@ -1141,7 +1149,7 @@ @php foreach($mikroorganismes[$keys[$i]] as $key => $value) { @endphp - + @php } @endphp @@ -4047,6 +4055,115 @@ data: { nofoto: idne, komponen: 'Media Tambahan Lainnya', keterangan:'generatetblpertumbuhankoloni', _token: '{{csrf_token()}}' }, url: '{{ route("getResult") }}', }; + var summaryKoloni = { + bap: [], + cap: [], + mcconkey: [], + sdar1: [], + sdar2: [], + sdai1: [], + sdai2: [], + }; + var summaryJamurKeys = ['sdar1', 'sdar2', 'sdai1', 'sdai2']; + var summaryGridMap = { + bap: '#gridmediabap', + cap: '#gridmediacap', + mcconkey: '#gridmediamcconkey', + sdar1: '#gridmediasdar1', + sdar2: '#gridmediasdar2', + sdai1: '#gridmediasdai1', + sdai2: '#gridmediasdai2', + }; + + function resetSummaryPertumbuhanKoloni() + { + $('#status_bap_status, #status_cap_status, #status_mcconkey_status, #status_jamur_status').html('-'); + $('#badge_bap_status, #badge_cap_status, #badge_mcconkey_status, #badge_jamur_status').html(' - '); + $('#last_updated').html('Diperbaharui :'); + } + + function valueSummaryPertumbuhanKoloni(value) + { + return value === null || value === undefined || value === '' ? '-' : value; + } + + function timestampSummaryPertumbuhanKoloni(row) + { + if (!row) { + return 0; + } + + var timestamp = row.updated_at || row.tglpenyimpanan || ''; + if (timestamp === '') { + return 0; + } + + var parsed = Date.parse(String(timestamp).replace(' ', 'T')); + return isNaN(parsed) ? 0 : parsed; + } + + function newestSummaryPertumbuhanKoloni(rows) + { + var newest = null; + $.each(rows || [], function(index, row) { + if (!newest || timestampSummaryPertumbuhanKoloni(row) >= timestampSummaryPertumbuhanKoloni(newest)) { + newest = row; + } + }); + return newest; + } + + function lastSummaryPertumbuhanKoloni(rows) + { + rows = rows || []; + return rows.length > 0 ? rows[rows.length - 1] : null; + } + + function updateSummaryPertumbuhanKoloni() + { + var bap = lastSummaryPertumbuhanKoloni(summaryKoloni.bap); + var cap = lastSummaryPertumbuhanKoloni(summaryKoloni.cap); + var mcconkey = lastSummaryPertumbuhanKoloni(summaryKoloni.mcconkey); + var jamurRows = []; + var lastUpdatedRow = null; + + $.each(summaryKoloni, function(key, rows) { + $.each(rows || [], function(index, row) { + if (!lastUpdatedRow || timestampSummaryPertumbuhanKoloni(row) > timestampSummaryPertumbuhanKoloni(lastUpdatedRow)) { + lastUpdatedRow = row; + } + }); + }); + $.each(summaryJamurKeys, function(index, key) { + jamurRows = jamurRows.concat(summaryKoloni[key] || []); + }); + + var jamur = newestSummaryPertumbuhanKoloni(jamurRows); + + $('#status_bap_status').html(valueSummaryPertumbuhanKoloni(bap ? bap.kuman : null)); + $('#badge_bap_status').html(valueSummaryPertumbuhanKoloni(bap ? bap.status : null)); + $('#status_cap_status').html(valueSummaryPertumbuhanKoloni(cap ? cap.kuman : null)); + $('#badge_cap_status').html(valueSummaryPertumbuhanKoloni(cap ? cap.status : null)); + $('#status_mcconkey_status').html(valueSummaryPertumbuhanKoloni(mcconkey ? mcconkey.kuman : null)); + $('#badge_mcconkey_status').html(valueSummaryPertumbuhanKoloni(mcconkey ? mcconkey.status : null)); + $('#status_jamur_status').html(valueSummaryPertumbuhanKoloni(jamur ? jamur.kuman : null)); + $('#badge_jamur_status').html(valueSummaryPertumbuhanKoloni(jamur ? jamur.status : null)); + $('#last_updated').html('Diperbaharui : ' + valueSummaryPertumbuhanKoloni(lastUpdatedRow ? (lastUpdatedRow.updated_at || lastUpdatedRow.tglpenyimpanan) : null)); + } + + function bindSummaryPertumbuhanKoloni() + { + $.each(summaryGridMap, function(key, selector) { + $(selector).off('bindingcomplete.summaryKoloni').on('bindingcomplete.summaryKoloni', function() { + summaryKoloni[key] = $(selector).jqxGrid('getrows') || []; + updateSummaryPertumbuhanKoloni(); + }); + }); + } + + resetSummaryPertumbuhanKoloni(); + bindSummaryPertumbuhanKoloni(); + $("#gridmediabap").jqxGrid({ width : '100%', source : srcjsonbap, diff --git a/htdocs/resources/views/dokter/ppdsdeveloper.blade.php b/htdocs/resources/views/dokter/ppdsdeveloper.blade.php index 13b67536..87aa2804 100644 --- a/htdocs/resources/views/dokter/ppdsdeveloper.blade.php +++ b/htdocs/resources/views/dokter/ppdsdeveloper.blade.php @@ -108,50 +108,66 @@
-
-
-
-
- -
- Logo MyLIS -
-
Template
- Spesimen -
-
-
    -
  • -
    Nomor LAB
    -

    -
  • - -
  • -
    Tanggal Periksa
    -

    -
  • -
+
+
+
+
+
Preview Hasil
+

Untuk cetak silahkan gunakan tombol cetak di laman Pengambilan Hasil

+
- +
- +
+
+
+
+
+ +
+ Logo MyLIS +
+
Template
+ Spesimen +
+
+ + + + + + + + + + + + + +
Nomor LABTanggal PeriksaPasienDokter Pengirim

+
+
Patient ID

- +
+ +
@@ -159,10 +175,6 @@ - - - - @@ -187,17 +199,12 @@ - - - -
Register Number
Name
Gender, Age , Asal Pengambilan
Spesimen
Status
-
@@ -218,10 +225,6 @@ Order - - Dokter Pengirim - - Asal Pasien @@ -315,13 +318,13 @@
-
+
- +
@@ -431,7 +434,7 @@ @php foreach($mikroorganismes[$keys[$i]] as $key => $value) { @endphp - + @php } @endphp @@ -654,141 +657,103 @@
- -
-
- -
-
- -
-
- -
-
-
-
- -
-
- -
-
- -
-
-
-
- -
-
- -
-
- -
-
-
-
- -
-
- -
-
- -
-
-
-
-
-
- -
-
- -
-
- -
-
-
-
+ + + + + + + + + + + + + + + + + + + + +
Kirby bauer
AMCAKFOSSCF
+ + + + + + + + + + + + + + + +
@@ -805,38 +770,84 @@ C. Tes Kepekaan Antibiotika: (S: Sensitif ; I : Intermediate ; R: Resisten)
- +
+
+
+
+
Ringkasan Hasil Terakhir
+
Diperbaharui :
+
+
+
+
+ +
Media BAP
+

-

+ - +
+
+
+
+ +
Media CAP
+

-

+ - +
+
+
+
+ +
Mc Conkey
+

-

+ - +
+
+
+
+ +
Media Jamur
+

-

+ - +
+
+
+
+
+ +
@@ -1148,7 +1159,7 @@ @php foreach($mikroorganismes[$keys[$i]] as $key => $value) { @endphp - + @php } @endphp @@ -3320,6 +3331,30 @@
+ +
+
+ +
+
+ +
+