diff --git a/htdocs/app/Http/Controllers/DokterController.php b/htdocs/app/Http/Controllers/DokterController.php index afb02fd1..95e874f2 100644 --- a/htdocs/app/Http/Controllers/DokterController.php +++ b/htdocs/app/Http/Controllers/DokterController.php @@ -53,6 +53,8 @@ use Session; use QrCode; use Exception; use PDFCREATOR; +use PhpOffice\PhpSpreadsheet\Spreadsheet; +use PhpOffice\PhpSpreadsheet\Writer\Xlsx; define( 'API_ACCESS_KEY', 'AAAA6YBXh1k:APA91bFL0q7QAXQGohXMpTwHco79f13C8PFk1Oo8kKhg1JerOulT9-37dxyP8X5ibABI0NuQ4ZsVxKQKCt7HuR7lUdJJuB-hTVnBmOUIBYfBlHb-Lcp6aGkj4erfF7J__A5hufXjF8Vt' ); @@ -717,6 +719,11 @@ class DokterController extends Controller protected function shouldMarkAsCritical(Request $request): bool { $flag = strtolower((string) $request->input('nilai_kritis', '0')); + $master = (string) $request->input('master_mikro', ''); + + if ($master !== 'buku03') { + return false; + } return in_array($flag, ['1', 'true', 'on', 'yes'], true); } @@ -750,16 +757,24 @@ class DokterController extends Controller $criticalSample->followed_up_by_name = Session('nama'); $criticalSample->save(); } - public function criticalValueNotifications(Request $request) + protected function getPendingCriticalValueItems() { - $highlightId = $request->query('highlight'); - $items = CriticalValueSample::whereNull('followed_up_at') + return CriticalValueSample::whereNull('followed_up_at') ->orderBy('critical_set_at', 'asc') ->get(); - $followedItems = CriticalValueSample::whereNotNull('followed_up_at') + } + protected function getFollowedCriticalValueItems() + { + return CriticalValueSample::whereNotNull('followed_up_at') ->orderBy('followed_up_at', 'desc') ->limit(100) ->get(); + } + public function criticalValueNotifications(Request $request) + { + $highlightId = $request->query('highlight'); + $items = $this->getPendingCriticalValueItems(); + $followedItems = $this->getFollowedCriticalValueItems(); return view('notifications.critical-values', [ 'items' => $items, @@ -767,6 +782,80 @@ class DokterController extends Controller 'highlightId' => $highlightId, ]); } + public function criticalValueNotificationExport(Request $request) + { + $type = $request->query('type', 'pending'); + $isFollowed = $type === 'followed'; + $rows = $isFollowed ? $this->getFollowedCriticalValueItems() : $this->getPendingCriticalValueItems(); + $filename = $isFollowed + ? 'notifikasi-nilai-kritis-riwayat-'.Carbon::now()->format('Ymd_His').'.xlsx' + : 'notifikasi-nilai-kritis-belum-dilaporkan-'.Carbon::now()->format('Ymd_His').'.xlsx'; + + return response()->streamDownload(function () use ($rows, $isFollowed) { + $spreadsheet = new Spreadsheet(); + $sheet = $spreadsheet->getActiveSheet(); + $sheet->setTitle($isFollowed ? 'Riwayat Nilai Kritis' : 'Nilai Kritis'); + + $headers = [ + 'No', + 'No Foto', + 'No Register', + 'Pasien', + 'Asal Pasien', + 'Spesimen', + 'Waktu Set Nilai Kritis', + 'Diset Oleh', + 'Waktu Ditindaklanjuti', + 'Ditindaklanjuti Oleh', + 'Status Tindak Lanjut', + 'Metode', + 'Penerima Laporan', + 'Alasan', + ]; + $sheet->fromArray($headers, null, 'A1'); + + $rowNumber = 2; + foreach ($rows as $index => $item) { + $status = $item->follow_up_status ?? ''; + if ($status === 'reported') { + $statusLabel = 'Dilaporkan'; + } elseif ($status === 'not_reported') { + $statusLabel = 'Belum Dilaporkan'; + } else { + $statusLabel = '-'; + } + + $sheet->fromArray([ + $index + 1, + $item->nofoto ?? '-', + $item->noregister ?? '-', + $item->nmpasien ?? '-', + $item->asalpasien ?? '-', + $item->nm_spesimen ?? '-', + $item->critical_set_at ? Carbon::parse($item->critical_set_at)->format('d-m-Y H:i:s') : '-', + $item->critical_set_by_name ?? '-', + $item->followed_up_at ? Carbon::parse($item->followed_up_at)->format('d-m-Y H:i:s') : '-', + $item->followed_up_by_name ?? '-', + $statusLabel, + $item->follow_up_method ?? '-', + $item->follow_up_recipient ?? '-', + $item->follow_up_reason ?? '-', + ], null, 'A'.$rowNumber); + $rowNumber++; + } + + foreach (range('A', 'N') as $col) { + $sheet->getColumnDimension($col)->setAutoSize(true); + } + + $writer = new Xlsx($spreadsheet); + $writer->save('php://output'); + $spreadsheet->disconnectWorksheets(); + unset($spreadsheet); + }, $filename, [ + 'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + ]); + } public function criticalValueNotificationSummary() { if (Session::get('id') === null) { diff --git a/htdocs/app/Http/Controllers/FrontpageController.php b/htdocs/app/Http/Controllers/FrontpageController.php index 71e403f5..65ea215e 100644 --- a/htdocs/app/Http/Controllers/FrontpageController.php +++ b/htdocs/app/Http/Controllers/FrontpageController.php @@ -36,6 +36,142 @@ use Carbon\Carbon; class FrontpageController extends Controller { + protected function buildMikroViewData($master, array $extra = []) + { + $data = [ + 'dokters' => User::where('previlage', 'supervisor')->get(), + 'allppds' => User::where('previlage', 'ppds')->get(), + 'allanalis' => User::where('previlage', 'analis')->get(), + 'lokasi' => 'Lab Mikrobiologi', + 'master' => $master, + 'antrkrmsitu' => 0, + 'focusPeriksaId' => null, + 'expertiseReturnUrl' => null, + 'openExpertiseOnLoad' => false, + ]; + $allOrganisms = Organisms::orderBy('name', 'ASC')->get(); + $allASTManual = SiraB::whereNotNull('setmanual')->select('setmanual')->groupBy('setmanual')->get(); + $groupOrganisms = function ($kelompok) use ($allOrganisms) { + $organisms = $allOrganisms->where('kelompok', $kelompok); + if ($organisms->isEmpty()) { + return [ + 'organismes' => [[['id' => 0, 'name' => 'No Data']]], + 'categories' => ['No Data'], + ]; + } + $grouped = $organisms->groupBy('category'); + $organismes = []; + $categories = []; + $i = 0; + foreach ($grouped as $category => $items) { + $categories[] = $category; + $j = 0; + foreach ($items as $item) { + $organismes[$i][$j] = ['id' => $item->id, 'name' => $item->name]; + $j++; + } + $i++; + } + return [ + 'organismes' => $organismes, + 'categories' => $categories, + ]; + }; + $biakankulturData = $groupOrganisms('biakankultur'); + $mikroorganismeData = $groupOrganisms('mikroorganisme'); + $data = array_merge($data, [ + 'organismes' => $biakankulturData['organismes'], + 'bacterycateggories' => $biakankulturData['categories'], + 'mikroorganismes' => $mikroorganismeData['organismes'], + 'mikroorganismestlist' => $mikroorganismeData['categories'], + ]); + $kelompokMapping = [ + 'jsonsputum' => 'Sputum', + 'jsonswabtenggorok' => 'Swab Tenggorok', + 'jsonurine' => 'Urine', + 'jsonswabperineum' => 'Swab perineum', + 'jsonselepitel' => 'Sel Epitel', + 'jsonselradang' => 'Sel Radang', + 'jsonmikroorganisme' => 'Q Mikroorganisme', + 'jsonjumlahlactobacillus' => 'Lactobacillus', + 'jsonjumlahgardnerella' => 'Gardnerella', + 'jsonjumlahmobiluncus' => 'Mobiluncus', + 'jsonpewarnaanziehlnielsen' => 'Pewarnaan Ziehl Nielsen', + 'jsonpewarnaanneisser' => 'Pewarnaan Neisser', + 'jsonpewarnaannegatif' => 'Pewarnaan Negatif', + 'jsonpewarnaanspora' => 'Pewarnaan Spora', + 'jsonpewarnaankoh' => 'Pewarnaan KOH', + 'jsonpewarnaangiemsa' => 'Pewarnaan Giemsa', + 'jsonmediabap' => 'Media BAP', + 'jsonmediacap' => 'Media CAP', + 'jsonmediamcconkey' => 'Media Mc Conkey', + 'jsonpemeriksaantl' => 'Pemeriksaan Tambahan Lainnya', + 'jsonbiakankultur' => 'Biakan Kultur', + 'jsonvlparameter' => 'Paramater Viral Load', + ]; + foreach ($kelompokMapping as $key => $kelompok) { + $data[$key] = $allOrganisms->where('kelompok', $kelompok)->values(); + } + $data['antibiotics'] = $allASTManual; + + return array_merge($data, $extra); + } + protected function mikroViewName() + { + return Session::get('previlage') == 'developer' ? 'dokter.ppdsdeveloper' : 'dokter.ppds'; + } + protected function mikroExpertiseViewName() + { + return 'dokter.mikro-expertise'; + } + protected function mikroBookPoliMap(): array + { + return [ + 'buku01' => [15,16,43,47,48,66,96,205,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223], + 'buku02' => [20], + 'buku03' => [7,8,13,17,29,33,44,107,114,115,199,200,201,202], + 'buku04' => [30], + 'buku05' => [165,179,180,181,183,184,185,187,188,189,190,192,194,195,196,198], + 'buku06' => [26,40,45,52,53,56,60,61,68,69,75,92,102,122,123,136,137,144,145,152,153,233], + 'buku07' => [18,19,32,35,46,49,50,54,57,58,59,72,160,182,186,191,193,197,206,207,208,224,225,226,227,228,234,235,236,237], + 'buku08' => [1,12,23,24,36,39,229,230,231,232], + 'buku09' => [2,4,5,9,10,11,12,21,22,27,34,41,42,51,63,64,65,85,86,87,88,93,97,118,67,121,125,126,127,128,129,130,132,133,134,135,140,147,158,159,161,162,163,164,166,167,168,169,170,171,172,173,174,175,176,177,178], + 'buku10' => [14,28,55,62,94,104,105,124,138,146], + 'buku11' => [79,80,81,82,83,84,203], + 'buku12' => [3,6,25,31,154,155,156,157], + 'buku13' => [37,38,148,149,204], + ]; + } + protected function resolveMikroMasterFromPoliId($poliId): string + { + foreach ($this->mikroBookPoliMap() as $master => $poliIds) { + if (in_array((int) $poliId, $poliIds, true)) { + return $master; + } + } + + return 'buku0'; + } + protected function resolveExpertiseReturnUrl(Request $request, string $master): string + { + $returnTo = trim((string) $request->query('return_to', '')); + if ($returnTo === 'dashboard') { + return url('/'); + } + + if ($returnTo !== '') { + if (str_starts_with($returnTo, '/')) { + return url($returnTo); + } + + $appUrl = rtrim((string) config('app.url', url('/')), '/'); + if (str_starts_with($returnTo, $appUrl)) { + return $returnTo; + } + } + + return url('/mikro/'.$master); + } public function index() { $data = []; @@ -79,6 +215,7 @@ class FrontpageController extends Controller $rawEarlyWarnings = Periksa::leftJoin('poli', 'periksa.poli_id', '=', 'poli.id') ->select( 'periksa.id', + 'periksa.poli_id', 'periksa.nofoto', 'periksa.noregister', 'periksa.nmpasien', @@ -111,6 +248,7 @@ class FrontpageController extends Controller if ($sisaMenit <= 60) { $earlyWarnings[] = [ 'id' => $row->id, + 'mikro_master' => $this->resolveMikroMasterFromPoliId($row->poli_id), 'subpoli' => $row->subpoli ?? 'Tanpa Subpoli', 'nofoto' => $row->nofoto, 'noregister' => $row->noregister, @@ -537,83 +675,30 @@ class FrontpageController extends Controller if (!Session::has('previlage')) { return redirect('/login'); } - $data = [ - 'dokters' => User::where('previlage', 'supervisor')->get(), - 'allppds' => User::where('previlage', 'ppds')->get(), - 'allanalis' => User::where('previlage', 'analis')->get(), - 'lokasi' => 'Lab Mikrobiologi', - 'master' => $master, - 'antrkrmsitu' => 0, - ]; - $allOrganisms = Organisms::orderBy('name', 'ASC')->get(); - $allASTManual = SiraB::whereNotNull('setmanual')->select('setmanual')->groupBy('setmanual')->get(); - $groupOrganisms = function ($kelompok) use ($allOrganisms) { - $organisms = $allOrganisms->where('kelompok', $kelompok); - if ($organisms->isEmpty()) { - return [ - 'organismes' => [[['id' => 0, 'name' => 'No Data']]], - 'categories' => ['No Data'], - ]; - } - $grouped = $organisms->groupBy('category'); - $organismes = []; - $categories = []; - $i = 0; - foreach ($grouped as $category => $items) { - $categories[] = $category; - $j = 0; - foreach ($items as $item) { - $organismes[$i][$j] = ['id' => $item->id, 'name' => $item->name]; - $j++; - } - $i++; - } - return [ - 'organismes' => $organismes, - 'categories' => $categories, - ]; - }; - $biakankulturData = $groupOrganisms('biakankultur'); - $mikroorganismeData = $groupOrganisms('mikroorganisme'); - $data = array_merge($data, [ - 'organismes' => $biakankulturData['organismes'], - 'bacterycateggories' => $biakankulturData['categories'], - 'mikroorganismes' => $mikroorganismeData['organismes'], - 'mikroorganismestlist' => $mikroorganismeData['categories'], - ]); - $kelompokMapping = [ - 'jsonsputum' => 'Sputum', - 'jsonswabtenggorok' => 'Swab Tenggorok', - 'jsonurine' => 'Urine', - 'jsonswabperineum' => 'Swab perineum', - 'jsonselepitel' => 'Sel Epitel', - 'jsonselradang' => 'Sel Radang', - 'jsonmikroorganisme' => 'Q Mikroorganisme', - 'jsonjumlahlactobacillus' => 'Lactobacillus', - 'jsonjumlahgardnerella' => 'Gardnerella', - 'jsonjumlahmobiluncus' => 'Mobiluncus', - 'jsonpewarnaanziehlnielsen' => 'Pewarnaan Ziehl Nielsen', - 'jsonpewarnaanneisser' => 'Pewarnaan Neisser', - 'jsonpewarnaannegatif' => 'Pewarnaan Negatif', - 'jsonpewarnaanspora' => 'Pewarnaan Spora', - 'jsonpewarnaankoh' => 'Pewarnaan KOH', - 'jsonpewarnaangiemsa' => 'Pewarnaan Giemsa', - 'jsonmediabap' => 'Media BAP', - 'jsonmediacap' => 'Media CAP', - 'jsonmediamcconkey' => 'Media Mc Conkey', - 'jsonpemeriksaantl' => 'Pemeriksaan Tambahan Lainnya', - 'jsonbiakankultur' => 'Biakan Kultur', - 'jsonvlparameter' => 'Paramater Viral Load', - ]; - foreach ($kelompokMapping as $key => $kelompok) { - $data[$key] = $allOrganisms->where('kelompok', $kelompok)->values(); + return view($this->mikroViewName(), $this->buildMikroViewData($master)); + } + public function viewMikroExpertise(Request $request, $periksaId) + { + if (!Session::has('previlage')) { + return redirect('/login'); } - $data['antibiotics'] = $allASTManual; - if (Session::get('previlage') == 'developer'){ - return view('dokter.ppdsdeveloper', $data); - } else { - return view('dokter.ppds', $data); + $periksa = Periksa::select('id', 'poli_id')->find($periksaId); + if (!$periksa) { + abort(404); } + $requestedMaster = trim((string) $request->query('from', '')); + $validMasters = array_keys($this->mikroBookPoliMap()); + $validMasters[] = 'buku0'; + $master = in_array($requestedMaster, $validMasters, true) + ? $requestedMaster + : $this->resolveMikroMasterFromPoliId($periksa->poli_id); + $returnUrl = $this->resolveExpertiseReturnUrl($request, $master); + + return view($this->mikroExpertiseViewName(), $this->buildMikroViewData($master, [ + 'focusPeriksaId' => (string) $periksaId, + 'expertiseReturnUrl' => $returnUrl, + 'openExpertiseOnLoad' => true, + ])); } public function pengambilan() { if (Session::get('previlage') == ''){ diff --git a/htdocs/resources/views/dokter/dashborad.blade.php b/htdocs/resources/views/dokter/dashborad.blade.php index ee9ae710..46b22d34 100644 --- a/htdocs/resources/views/dokter/dashborad.blade.php +++ b/htdocs/resources/views/dokter/dashborad.blade.php @@ -150,14 +150,15 @@