whereNotNull('dokter_id') ->where('dokter_id', '<>', 0) ->whereNotNull('nmdokter') ->where('nmdokter', '<>', '') ->groupBy('dokter_id', 'nmdokter') ->orderBy('nmdokter', 'ASC') ->get(); return view('admin.report', [ 'dokterOptions' => $dokterOptions ]); } } public function rekapPeriksa(Request $request) { set_time_limit(0); $bulan = $request->input('bulan'); $tahun = $request->input('tahun'); if ($bulan == 'ALL' OR $bulan == 'Pick Month') { $orderbydate = Periksa::selectRaw('SUM(id) as jumlah, DATE(daftar) as day')->whereYear('daftar', $tahun)->groupBy(DB::raw('daftar'))->orderBy('daftar', 'ASC')->get(); $bulan = ''; } else { $tglcari = $tahun . '-' . str_pad($bulan, 2, '0', STR_PAD_LEFT); $orderbydate = Periksa::selectRaw('SUM(id) as jumlah, DATE(daftar) as day')->where('day', 'LIKE', '%' . $tglcari . '%')->groupBy(DB::raw('daftar'))->orderBy('daftar', 'ASC')->get(); $bulanNames = [ '01' => 'BULAN JANUARI', '02' => 'BULAN FEBRUARI', '03' => 'BULAN MARET', '04' => 'BULAN APRIL', '05' => 'BULAN MEI', '06' => 'BULAN JUNI', '07' => 'BULAN JULI', '08' => 'BULAN AGUSTUS', '09' => 'BULAN SEPTEMBER', '10' => 'BULAN OKTOBER', '11' => 'BULAN NOVEMBER', '12' => 'BULAN DESEMBER', ]; $bulan = $bulanNames[$bulan] ?? $bulan; } $data = []; $data['bulan'] = $bulan; $data['tahun'] = $tahun; $data['orderbydate']= $orderbydate; $generatetabel = view('cetak.rekap_periksa_table', $data)->render(); echo $generatetabel; } protected static function getPasienData($result) { return [ 'nama' => $result->nmpasien, 'tgl' => $result->tgllahirpasien, 'jk' => $result->jkpasien, ]; } protected static function updateTotals($totals, $asuransi, $urgensi, $jk) { if ($jk == 'L') { $totals['m']++; } else { $totals['f']++; } if ($asuransi == 'JKN') { $totals['jkn']++; } elseif ($asuransi == 'Umum') { $totals['umum']++; } elseif ($asuransi == 'TAG') { $totals['tag']++; } elseif ($asuransi == 'GCU') { $totals['gcu']++; } elseif ($asuransi == 'Billing') { $totals['bill']++; } else { $totals['swasta']++; } if ($urgensi == 'Elective') { $totals['electiv']++; } else { $totals['cito']++; } return $totals; } protected static function mapResultToArray($result) { $nmpasien = $result->nmpasien; $tgl = $result->tgllahirpasien; $jk = $result->jkpasien; $jenis = $result->reques; $tlppasien = $result->tlppasien; $nofoto = $result->nofoto; $verifikasi = $result->verifikasi; $tanggal = $result->daftar; $tanggalfoto = $result->foto; $asuransi = $result->asuransi; $urgensi = $result->urgensi; $from = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $result->daftar); if (is_null($verifikasi)){ $verifikasi = ''; $to = ''; $durasi = 'On Progress'; } else { $to = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $verifikasi); $durasi = $to->diffForHumans($from); } $arrayttllhr = explode("-", $tgl); if (isset($arrayttllhr[2])){ $yy = $arrayttllhr[0]; $mm = $arrayttllhr[1]; $dd = $arrayttllhr[2]; $tgllahir = $dd.'-'.$mm.'-'.$yy; } else { $tgllahir = $tgl; } $arrayttl = explode(" ", $tanggal); $tanggal = $arrayttl[0]; if ($jk == 'L') { $l = '1'; $p = ''; } else { $l = ''; $p = '1'; } if ($asuransi == 'JKN') { $jkn = '1'; $umm = ''; $swasta = ''; $gcu = ''; $tag = ''; $bill = ''; } else if ($asuransi == 'Umum') { $jkn = ''; $umm = '1'; $swasta = ''; $gcu = ''; $tag = ''; $bill = ''; } else if ($asuransi == 'TAG') { $jkn = ''; $umm = ''; $swasta = ''; $gcu = ''; $bill = ''; $tag = '1'; } else if ($asuransi == 'GCU') { $jkn = ''; $umm = ''; $swasta = ''; $gcu = '1'; $tag = ''; $bill = ''; } else if ($asuransi == 'Billing') { $jkn = ''; $umm = ''; $swasta = ''; $gcu = ''; $bill = '1'; $tag = ''; } else { $jkn = ''; $umm = ''; $swasta = '1'; $gcu = ''; $tag = ''; $bill = ''; } if ($urgensi == 'Elective') { $ele = '1'; $cito = ''; } else { $ele = ''; $cito = '1'; } $getjennofoto = explode("-", $nofoto); $jenis = $getjennofoto[0].' '.$jenis; return [ 'id' => $result->id, 'filefoto' => '' . $result->nofoto . '', 'l' => $l, 'p' => $p, 'jenis' => $jenis, 'jkn' => $jkn, 'umm' => $umm, 'gcu' => $gcu, 'tag' => $tag, 'swasta' => $swasta, 'billing' => $bill, 'ele' => $ele, 'cito' => $cito, 'asuransi' => $asuransi, 'nofoto' => $result->nofoto, 'noregister' => $result->noregister, 'nmpasien' => $nmpasien, 'usia' => $result->usia, 'kesimpulan' => $result->kesimpulan, 'ruangan' => $result->ruangan, 'daftar' => $result->daftar, 'created_at' => $result->created_at, 'nmdokter' => $result->nmdokter, 'nmppdssenior' => $result->nmppdssenior, 'nmmiddleppds' => $result->nmmiddleppds, 'nmppdsjunior' => $result->nmppdsjunior, 'nmppdsmiddle2' => $result->nmppdsmiddle2, 'nmppdsjunior2' => $result->nmppdsjunior2, 'diagnosa2' => $result->diagnosa2, 'nmanalis' => $result->nmanalis, 'nmexcutor' => $result->nmexcutor, 'alamatpasien' => $result->alamatpasien, 'tgllahirpasien'=> $tgl, 'jkpasien' => $jk, 'tlppasien' => $tlppasien, 'modality' => $result->modality, 'dlp' => $result->dlp, 'kd_spesimen' => $result->kd_spesimen, 'nm_spesimen' => $result->nm_spesimen, 'status' => $result->status, 'asalpasien' => $result->asalpasien, 'nmrs' => $result->nmrs, 'berat' => $result->berat, 'klinisi' => $result->klinisi, 'klinis' => $result->klinis, 'telpon' => $tlppasien, 'verifikasi' => $result->verifikasi, 'noloket' => $result->noloket, 'foto' => $result->foto, 'export' => $result->export, 'nmdrafter' => $result->nmdrafter, 'tgldraft' => $result->tgldraft, 'baca' => $result->baca, 'nmpembaca' => $result->nmpembaca, 'tgladendum' => $result->tgladendum, 'nmadendum' => $result->nmadendum, 'durasi' => $durasi, ]; } protected static function getTotalRow($totals) { return [ 'id' => '', 'filefoto' => '', 'noregister'=> '', 'nama' => 'Total', 'l' => $totals['m'], 'p' => $totals['f'], 'jkn' => $totals['jkn'], 'umm' => $totals['umum'], 'gcu' => $totals['gcu'], 'tag' => $totals['tag'], 'swasta' => $totals['swasta'], 'billing' => $totals['bill'], 'ele' => $totals['electiv'], 'cito' => $totals['cito'], ]; } private $listAntibiotik = [ 'Oxacillin-OX', 'Cefoxitin-FOX', 'Benzylpenicillin-P', 'Ampicillin-AM', 'Azithromycin-AZM', 'Erythromycin-ERY', 'Cefazolin-CZO', 'Cefepime-FEP', 'Cefixime-CFM', 'Cefotaxime-CTX', 'Cefuroxime-CXM', 'Ceftazidime-CAZ', 'Ceftriaxone-CRO', 'Ceftazidime/Avibactam-CZA', 'Piperacilin/Tazobactam-TZP', 'Ampicillin/Sulbactam-SAM', 'Amoxicillin/Clavulanate-AMC', 'Cefoperazon/Sulbactam-SCF', 'Aztreonam-ATM', 'Ceftaroline-CPT', 'Ciprofloxacin-CIP', 'Levofloxacin-LEV', 'Moxifloxacin-MFX', 'Clindamycin-CLI', 'Colistin-CS', 'Tetracyclin-TCY', 'Tigecycline-TGC', 'Gentamicin-GM', 'Amikacin-AN', 'Meropenem-MEM', 'Imipenem-IPM', 'Doripenem-DOR', 'Ertapenem-ETP', 'Minocycline-MNO', 'Doxycycline-DOX', 'Spectinomycin-SPT', 'Trimethoprim/Sulfamethoxazole-SXT', 'Fosfomycin-FOS', 'Vancomycin-VAN', 'Linezolid-LNZ', 'Fluconazole', 'Voriconazole', 'Caspofungin', 'Micafungin', 'Amphotericin B', 'Flucytosine' ]; private function resolveTatTargetDays($modaliti2) { return (!empty($modaliti2) && is_numeric($modaliti2) && intval($modaliti2) > 0) ? intval($modaliti2) : 1; } private function getTatDeadlineDate($mulai, $targetDays) { return Carbon::parse($mulai)->addDays(intval($targetDays))->toDateString(); } private function getTatElapsedDays($mulai, $verifikasi) { return Carbon::parse($mulai)->startOfDay()->diffInDays(Carbon::parse($verifikasi)->startOfDay()); } private function resolveTatStatus($mulai, $verifikasi, $targetDays) { $deadlineDate = $this->getTatDeadlineDate($mulai, $targetDays); return Carbon::parse($verifikasi)->toDateString() <= $deadlineDate ? 'MEMENUHI TARGET' : 'TIDAK MEMENUHI TARGET'; } public function report(Request $request) { $bulan = $request->input('bulan'); $tahun = $request->input('tahun'); $jenisreport = $request->input('jenisreport'); $dokterId = $request->input('dokter_id'); $tanggalFilter = $request->input('tanggal_filter', 'daftar'); $statusFilter = $request->input('status_filter', 'ALL'); $dateColumn = $tanggalFilter === 'verifikasi' ? 'verifikasi' : 'daftar'; $homebase = url("/"); $arraylist = []; $limit = $request->input('limit') ?? 500; $page = $request->input('pagenum') ?? 1; $order = $request->input('order') ?? 'id desc'; $filterscount = $request->input('filterscount') ?? 0; $isMdrReport = $jenisreport == 'list_hasil_mdr'; if ($jenisreport == 'biorepository'){ if ($bulan == 'ALL'){ $queryBiorepo = DB::table('db_komponenjawaban') ->select('db_komponenjawaban.*', 'periksa.nofoto', 'periksa.noregister', 'periksa.nmpasien', 'periksa.usia', 'periksa.reques', 'periksa.dlp', 'periksa.nm_spesimen', 'periksa.kd_spesimen', DB::raw("CONCAT('Lihat Hasil') as urlhasil")) ->leftJoin('periksa', 'db_komponenjawaban.accnumber', 'periksa.nofoto') ->whereIn('db_komponenjawaban.komponen', ['id_bakteri01', 'id_bakteri02', 'bakteri']) ->where('db_komponenjawaban.isidata', '!=', '') ->where('periksa.daftar', 'LIKE', $tahun.'-%'); if (!empty($dokterId) && $dokterId != 'ALL' && $dokterId != '0') { $queryBiorepo->where('periksa.dokter_id', $dokterId); } $lists = $queryBiorepo->orderBy('periksa.id', 'DESC')->get(); } else { $queryBiorepo = DB::table('db_komponenjawaban') ->select('db_komponenjawaban.*', 'periksa.nofoto', 'periksa.noregister', 'periksa.nmpasien', 'periksa.usia', 'periksa.reques', 'periksa.dlp', 'periksa.nm_spesimen', 'periksa.kd_spesimen', DB::raw("CONCAT('Lihat Hasil') as urlhasil")) ->leftJoin('periksa', 'db_komponenjawaban.accnumber', 'periksa.nofoto') ->whereIn('db_komponenjawaban.komponen', ['id_bakteri01', 'id_bakteri02', 'bakteri']) ->where('db_komponenjawaban.isidata', '!=', '') ->where('periksa.daftar', 'LIKE', $tahun.'-'.$bulan.'-%'); if (!empty($dokterId) && $dokterId != 'ALL' && $dokterId != '0') { $queryBiorepo->where('periksa.dokter_id', $dokterId); } $lists = $queryBiorepo->orderBy('periksa.id', 'DESC')->get(); } echo json_encode($lists); } else { $query = Periksa::select('id', 'poli_id', 'nofoto', 'noregister', 'nmpasien', 'tlppasien', 'tgllahirpasien', 'usia', 'alamatpasien', 'ktp', 'jkpasien', 'bpjs', 'asuransi', 'urgensi', 'asalpasien', 'klinisi', 'klinis', 'nmanalis', 'nmppdssenior', 'kd_spesimen', 'nm_spesimen', 'dlp', 'diagnosa2', 'mulai', 'verifikasi', 'status', 'reques', 'nmdokter', 'daftar') ->whereYear($dateColumn, $tahun); if ($bulan !== 'ALL') { $query->whereMonth($dateColumn, $bulan); } if (!empty($dokterId) && $dokterId != 'ALL' && $dokterId != '0') { $query->where('dokter_id', $dokterId); } if ($statusFilter === 'Selesai') { $query->where('status', 'LIKE', '%Selesai%'); } if ($isMdrReport) { $query->whereExists(function ($subquery) { $subquery->select(DB::raw(1)) ->from('db_komponenjawaban') ->whereColumn('db_komponenjawaban.accnumber', 'periksa.nofoto') ->whereIn('db_komponenjawaban.komponen', ['bakterisir', 'id_bakterisir01', 'id_bakterisir02']) ->whereNotNull('db_komponenjawaban.isidata') ->where('db_komponenjawaban.isidata', '!=', ''); }); } $periksaCursor = $query->orderBy($dateColumn, 'ASC')->cursor(); $hasil = []; $acc = []; $poli_ids = []; foreach ($periksaCursor as $r) { $acc[] = $r->nofoto; $poli_ids[] = $r->poli_id; $hasil[] = $r; } if (empty($hasil)) { return response()->json([]); } $komponen = DB::table('db_komponenjawaban') ->select('accnumber','komponen','isidata') ->whereIn('accnumber', array_unique($acc)) ->whereIn('komponen', [ 'id_bakteri01','id_bakteri02','bakteri', 'bakterisir','id_bakterisir01','id_bakterisir02' ]) ->get() ->groupBy('accnumber'); $poli = DB::table('poli') ->select('id','subpoli','modaliti2') ->whereIn('id', array_unique($poli_ids)) ->get() ->keyBy('id'); foreach ($hasil as $row) { $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->hasil_mdr = $k->whereIn('komponen', ['bakterisir', 'id_bakterisir01', 'id_bakterisir02']) ->pluck('isidata') ->filter(function ($value) { return trim(strip_tags((string) $value)) !== ''; }) ->unique() ->implode('; '); $row->filefoto = "nofoto)."'>$row->nofoto"; $p = $poli[$row->poli_id] ?? null; $row->subpoli = $p->subpoli ?? null; $row->modaliti2 = $this->resolveTatTargetDays($p->modaliti2 ?? '1'); if (!empty($row->verifikasi)) { $selisih = $this->getTatElapsedDays($row->mulai, $row->verifikasi); $row->selisih_hari = $selisih; $row->status_target = $this->resolveTatStatus($row->mulai, $row->verifikasi, $row->modaliti2); } else { $row->selisih_hari = null; $row->status_target = "TIDAK ADA HASIL"; } } if ($jenisreport == 'rekaptat') { $rekap = collect($hasil)->groupBy('kd_spesimen')->map(function($g){ return [ 'jenis_pemeriksaan' => $g->first()->kd_spesimen, 'memenuhi' => $g->where('status_target','MEMENUHI TARGET')->count(), 'tidak_memenuhi' => $g->where('status_target','TIDAK MEMENUHI TARGET')->count(), 'tidak_ada_hasil' => $g->where('status_target','TIDAK ADA HASIL')->count(), 'total' => $g->count(), ]; })->values(); return response()->json($rekap); } return response()->json($hasil); } } public function genRekapAntibiotik(Request $request) { $bulan = $request->input('bulan'); $tahun = $request->input('tahun'); if ($tahun == '' OR is_null($tahun)){ $getarray = explode('?', $bulan); $bulan = $getarray[0] ?? date('m'); $tahun = $getarray[1] ?? date('Y'); $bulan = str_replace('bulan=', '', $bulan); $tahun = str_replace('tahun=', '', $tahun); } $listAntibiotik = $this->getDynamicAntibioticHeaders($bulan, $tahun); $query = Periksa::query()->whereYear('daftar', $tahun); if ($bulan != 'ALL' && $bulan != 'Pick Month') { $query->whereMonth('daftar', $bulan); } $orderbydate = $query->paginate(50); $orderbydate->appends(['bulan' => $bulan, 'tahun' => $tahun]); $pageIds = $orderbydate->pluck('id')->toArray(); $antibiotikLookup = $this->mapAntibiotikData($pageIds); return view('admin.rekapantibiotik', [ 'orderbydate' => $orderbydate, 'antibiotikLookup' => $antibiotikLookup, 'listAntibiotik' => $listAntibiotik, 'bulan' => $bulan, 'tahun' => $tahun ]); } private function mapAntibiotikData($orderIds) { $raw = RekapAntibiotik::whereIn('orderid', $orderIds)->get(); $lookup = []; foreach($raw as $row) { $lookup[$row->orderid][$row->antibiotic] = $row->interpretation; } return $lookup; } private function getDynamicAntibioticHeaders($bulan, $tahun) { $query = DB::table('rekapantibiotik') ->join('periksa', 'rekapantibiotik.orderid', '=', 'periksa.id') ->whereYear('periksa.daftar', $tahun); if ($bulan != 'ALL' && $bulan != 'Pick Month') { $query->whereMonth('periksa.daftar', $bulan); } return $query->distinct() ->orderBy('rekapantibiotik.antibiotic', 'ASC') ->pluck('rekapantibiotik.antibiotic') ->toArray(); } private function getGlassReportHeaders() { $tableC = [ 'ID Rumah Sakit', 'Nama Pasien', 'No Rekam Medis', 'Jenis Kelamin', 'Tanggal Lahir', 'Usia', 'Ruang Rawat', 'Tanggal Pasien Masuk', 'Tanggal Pengambilan Spesimen', 'Specimen Origin', 'Jenis Spesimen', ]; $tableAAntibiotics = [ 'Cefoxitin', 'Oxacillin', 'Penicillin', 'Ampicillin', 'Amoxicillin', 'Cefazolin', 'Cefuroxime', 'Cefixime', 'Cefotaxime', 'Ceftriaxone', 'Ceftazidime', 'Cefepime', 'Ceftaroline', 'Ertapenem', 'Imipenem', 'Meropenem', 'Aztreonam', 'Amoxicillin-clavulanate', 'Ampicillin-sulbactam', 'Piperacillin-tazobactam', 'Ceftazidime-avibactam', 'Gentamicin', 'Amikacin', 'Ciprofloxacin', 'Levofloxacin', 'Moxifloxacin', 'Trimethoprim-sulfamethoxazole', 'Azithromycin', 'Clarithromycin', 'Erythromycin', 'Clindamycin', 'Tetracycline', 'Minocycline', 'Doxycycline', 'Colistin', 'Vancomycin', 'Linezolid', 'Tigecycline', 'Daptomycin', 'Nitrofurantoin', 'Fosfomycin', ]; $tableBAntibiotics = [ 'Fluconazole', 'Voriconazole', 'Amphotericin B', 'Micafungin', 'Caspofungin', 'Flucytosine', ]; return [ 'A' => array_merge($tableC, ['Nama Spesies Bakteri', 'Pertumbuhan Bakteri', 'SIR Bakteri', 'ESBL', 'MRSA'], $tableAAntibiotics, $tableBAntibiotics), 'C' => array_merge($tableC, ['Pertumbuhan Bakteri']), 'A_antibiotics' => $tableAAntibiotics, 'B_antibiotics' => $tableBAntibiotics, ]; } private function getGlassReportAntibioticAliases() { return [ 'Cefoxitin' => ['cefoxitin', 'cefoxitinscreen'], 'Oxacillin' => ['oxacillin'], 'Penicillin' => ['penicillin', 'benzylpenicillin'], 'Ampicillin' => ['ampicillin'], 'Amoxicillin' => ['amoxicillin'], 'Cefazolin' => ['cefazolin', 'cefazolinurine', 'cefazolinother'], 'Cefuroxime' => ['cefuroxime', 'cefuroximeiv', 'cefuroximeoral'], 'Cefixime' => ['cefixime'], 'Cefotaxime' => ['cefotaxime'], 'Ceftriaxone' => ['ceftriaxone'], 'Ceftazidime' => ['ceftazidime'], 'Cefepime' => ['cefepime'], 'Ceftaroline' => ['ceftaroline'], 'Ertapenem' => ['ertapenem'], 'Imipenem' => ['imipenem'], 'Meropenem' => ['meropenem'], 'Aztreonam' => ['aztreonam'], 'Amoxicillin-clavulanate' => ['amoxicillinclavulanate', 'amoxicillinclavulanicacid'], 'Ampicillin-sulbactam' => ['ampicillinsulbactam'], 'Piperacillin-tazobactam' => ['piperacillintazobactam'], 'Ceftazidime-avibactam' => ['ceftazidimeavibactam'], 'Gentamicin' => ['gentamicin'], 'Amikacin' => ['amikacin'], 'Ciprofloxacin' => ['ciprofloxacin'], 'Levofloxacin' => ['levofloxacin'], 'Moxifloxacin' => ['moxifloxacin'], 'Trimethoprim-sulfamethoxazole' => ['trimethoprimsulfamethoxazole', 'trimetrophimesulfamethoxazole'], 'Azithromycin' => ['azithromycin'], 'Clarithromycin' => ['clarithromycin'], 'Erythromycin' => ['erythromycin'], 'Clindamycin' => ['clindamycin'], 'Tetracycline' => ['tetracycline', 'tetracyclinescreenonly', 'tetracyclineu'], 'Minocycline' => ['minocycline'], 'Doxycycline' => ['doxycycline'], 'Colistin' => ['colistin'], 'Vancomycin' => ['vancomycin'], 'Linezolid' => ['linezolid'], 'Tigecycline' => ['tigecycline'], 'Daptomycin' => ['daptomycin'], 'Nitrofurantoin' => ['nitrofurantoin'], 'Fosfomycin' => ['fosfomycin'], 'Fluconazole' => ['fluconazole'], 'Voriconazole' => ['voriconazole'], 'Amphotericin B' => ['amphotericinb'], 'Micafungin' => ['micafungin'], 'Caspofungin' => ['caspofungin'], 'Flucytosine' => ['flucytosine'], ]; } private function normalizeGlassReportValue($value) { return preg_replace('/[^a-z0-9]+/', '', strtolower(strip_tags((string) $value))); } private function pickGlassReportResistanceValue($row, $header) { $rawResistance = $row->resistence ?? $row->resistance ?? null; $rawInterpretation = $row->interpretation ?? null; $resistance = trim((string) $rawResistance); $interpretation = trim((string) $rawInterpretation); if ($resistance === '') { return $interpretation; } $normalizedResistance = $this->normalizeGlassReportValue($resistance); $normalizedAntibiotic = $this->normalizeGlassReportValue($row->antibiotic ?? ''); $normalizedHeader = $this->normalizeGlassReportValue($header); if ($normalizedResistance === $normalizedAntibiotic || $normalizedResistance === $normalizedHeader) { return $interpretation; } return $resistance; } private function getGlassReportOrigin($row) { if (empty($row->daftar) || empty($row->mulai)) { return ''; } try { $selisihHari = Carbon::parse($row->daftar)->diffInDays(Carbon::parse($row->mulai)); return $selisihHari >= 3 ? 'Hospital Origin' : 'Community Origin'; } catch (\Throwable $e) { return ''; } } private function buildGlassReportBaseRow($row) { $jenisSpesimen = trim(implode(' ', array_filter([ $row->kd_spesimen ?? '', $row->nm_spesimen ?? '', ]))); return [ $row->nmrs ?? '', $row->nmpasien ?? '', $row->noregister ?? '', $row->jkpasien ?? '', $row->tgllahirpasien ?? '', $row->usia ?? '', $row->asalpasien ?? '', $row->daftar ?? '', $row->mulai ?? '', $this->getGlassReportOrigin($row), $jenisSpesimen, ]; } private function getGlassReportLookups($rows) { $orderIds = $rows->pluck('id')->filter()->values()->all(); $accnumbers = $rows->pluck('nofoto')->filter()->values()->all(); $komponen = DB::table('db_komponenjawaban') ->select('accnumber', 'komponen', 'isidata') ->whereIn('accnumber', $accnumbers) ->whereIn('komponen', ['bakteri', 'id_bakteri01', 'id_bakteri02', 'id_mikroorganisme', 'id_biakankultur', 'bakterisir', 'id_bakterisir01', 'id_bakterisir02']) ->whereNotNull('isidata') ->where('isidata', '!=', '') ->get() ->groupBy('accnumber'); $antibiotik = RekapAntibiotik::query() ->whereIn('orderid', $orderIds) ->get(['orderid', 'antibiotic', 'resistance', 'interpretation']) ->groupBy('orderid'); return [ 'komponen' => $komponen, 'antibiotik' => $antibiotik, ]; } private function splitGlassReportRows($rows, $lookups) { $headers = $this->getGlassReportHeaders(); $aliases = $this->getGlassReportAntibioticAliases(); $tables = ['A' => [], 'C' => []]; foreach ($rows as $row) { $baseRow = $this->buildGlassReportBaseRow($row); $komponenRows = $lookups['komponen'][$row->nofoto] ?? collect([]); $antibioticRows = $lookups['antibiotik'][$row->id] ?? collect([]); $speciesNames = []; $growthValue = ''; $sirValues = [ 'bakteri' => '', 'id_bakteri01' => '', 'id_bakteri02' => '', ]; foreach ($komponenRows as $komponenRow) { $value = trim(strip_tags((string) $komponenRow->isidata)); if ($value === '') { continue; } if (in_array($komponenRow->komponen, ['bakteri', 'id_bakteri01', 'id_bakteri02'], true) && stripos($value, 'Ditemukan morfologi') === false) { $speciesNames[] = [ 'name' => $value, 'component' => $komponenRow->komponen, ]; } if ($komponenRow->komponen === 'id_biakankultur' && $growthValue === '') { $growthValue = $value; } if ($komponenRow->komponen === 'bakterisir' && $sirValues['bakteri'] === '') { $sirValues['bakteri'] = $value; } if ($komponenRow->komponen === 'id_bakterisir01' && $sirValues['id_bakteri01'] === '') { $sirValues['id_bakteri01'] = $value; } if ($komponenRow->komponen === 'id_bakterisir02' && $sirValues['id_bakteri02'] === '') { $sirValues['id_bakteri02'] = $value; } } $speciesNames = array_values(array_filter($speciesNames, function ($value) { return trim((string) ($value['name'] ?? '')) !== ''; })); $antibioticValues = []; foreach ($antibioticRows as $antibioticRow) { $matchedHeader = null; $normalizedAntibiotic = $this->normalizeGlassReportValue($antibioticRow->antibiotic ?? ''); $normalizedResistance = $this->normalizeGlassReportValue($antibioticRow->resistance ?? ''); foreach ($aliases as $header => $variants) { if (in_array($normalizedAntibiotic, $variants, true) || in_array($normalizedResistance, $variants, true)) { $matchedHeader = $header; break; } } if ($matchedHeader === null || isset($antibioticValues[$matchedHeader])) { continue; } $antibioticValues[$matchedHeader] = $this->pickGlassReportResistanceValue($antibioticRow, $matchedHeader); } $hasJenisSpesimen = trim((string) ($baseRow[10] ?? '')) !== ''; if (!empty($speciesNames) && $hasJenisSpesimen) { foreach ($speciesNames as $speciesData) { $sirKey = $speciesData['component'] ?? 'bakteri'; $sirValue = $sirValues[$sirKey] ?? ''; $tableRow = array_merge($baseRow, [ $speciesData['name'] ?? '', $growthValue, $sirValue, $row->id_esbl ?? '', $row->id_mrsa ?? '', ]); foreach ($headers['A_antibiotics'] as $antibioticHeader) { $tableRow[] = $antibioticValues[$antibioticHeader] ?? ''; } foreach ($headers['B_antibiotics'] as $antibioticHeader) { $tableRow[] = $antibioticValues[$antibioticHeader] ?? ''; } $tables['A'][] = $tableRow; } continue; } $tables['C'][] = array_merge($baseRow, [$growthValue]); } return $tables; } public function genGlassReport(Request $request) { $bulan = $request->input('bulan'); $tahun = $request->input('tahun'); if ($tahun == '' OR is_null($tahun)){ $getarray = explode('?', $bulan); $bulan = $getarray[0] ?? date('m'); $tahun = $getarray[1] ?? date('Y'); $bulan = str_replace('bulan=', '', $bulan); $tahun = str_replace('tahun=', '', $tahun); } $query = Periksa::query()->where('dlp', 'Kultur')->whereNotNull('dokter_id')->whereYear('daftar', $tahun); if ($bulan != 'ALL' && $bulan != 'Pick Month') { $query->whereMonth('daftar', $bulan); } $orderbydate = $query->orderBy('daftar', 'ASC')->orderBy('id', 'ASC')->paginate(50); $orderbydate->appends(['bulan' => $bulan, 'tahun' => $tahun]); $pageIds = $orderbydate->pluck('id')->toArray(); $antibiotikLookup = $this->mapAntibiotikData($pageIds); $glassRows = $orderbydate->getCollection(); $glassLookups = $this->getGlassReportLookups($glassRows); $glassTables = $this->splitGlassReportRows($glassRows, $glassLookups); $glassHeaders = $this->getGlassReportHeaders(); return view('admin.glassreport', [ 'orderbydate' => $orderbydate, 'antibiotikLookup' => $antibiotikLookup, 'jsonantibiotik' => $this->listAntibiotik, 'glassTables' => $glassTables, 'glassHeaders' => $glassHeaders, 'bulan' => $bulan, 'tahun' => $tahun ]); } public function exportGlassReport(Request $request) { // Set memory limit sementara untuk proses export berat, tapi streaming tetap kuncinya ini_set('memory_limit', '512M'); ini_set('max_execution_time', 300); // 5 menit $bulan = $request->input('bulan'); $tahun = $request->input('tahun'); // Logic cleaning input... if (strpos($bulan, 'bulan=') !== false) { $parts = explode('?', $bulan); $bulan = str_replace('bulan=', '', $parts[0]); $tahun = str_replace('tahun=', '', $parts[1] ?? date('Y')); } $response = new StreamedResponse(function() use ($bulan, $tahun) { $handle = fopen('php://output', 'w'); $headers = $this->getGlassReportHeaders(); $tables = [ 'A' => [], 'C' => [], ]; // Query Tanpa Get() tapi Chunk() $query = Periksa::query()->where('dlp', 'Kultur')->whereNotNull('dokter_id')->whereYear('daftar', $tahun); if ($bulan != 'ALL' && $bulan != 'Pick Month') { $query->whereMonth('daftar', $bulan); } // Proses per 500 data agar RAM stabil $query->orderBy('id')->chunk(500, function($rows) use (&$tables) { $lookups = $this->getGlassReportLookups($rows); $chunkTables = $this->splitGlassReportRows($rows, $lookups); foreach (['A', 'C'] as $tableKey) { foreach ($chunkTables[$tableKey] as $tableRow) { $tables[$tableKey][] = $tableRow; } } }); foreach (['A', 'C'] as $tableKey) { fputcsv($handle, ['TABEL '.$tableKey]); fputcsv($handle, $headers[$tableKey]); foreach ($tables[$tableKey] as $tableRow) { fputcsv($handle, $tableRow); } fputcsv($handle, []); } fclose($handle); }); $response->headers->set('Content-Type', 'text/csv'); $response->headers->set('Content-Disposition', 'attachment; filename="GlassReport_'.$bulan.'_'.$tahun.'.csv"'); return $response; } public function exportRekapAntibiotik(Request $request) { ini_set('memory_limit', '512M'); ini_set('max_execution_time', 600); // 10 menit jika data besar $bulan = $request->input('bulan'); $tahun = $request->input('tahun'); if (strpos($bulan, 'bulan=') !== false) { $parts = explode('?', $bulan); $bulan = str_replace('bulan=', '', $parts[0]); $tahun = str_replace('tahun=', '', $parts[1] ?? date('Y')); } $listAntibiotik = $this->getDynamicAntibioticHeaders($bulan, $tahun); $response = new StreamedResponse(function() use ($bulan, $tahun, $listAntibiotik) { $handle = fopen('php://output', 'w'); $staticHeaders = [ 'No', 'Status', 'No.RM', 'Name', 'Order', 'Gender', 'Date', 'Urgensi', 'Comming From', 'Code', 'Spesimen', 'Finish', 'BHP Media', 'BHP Pot Sputum', 'BHP Pot Urine', 'BHP Oshe', 'BHP Obyek Glass', 'BHP Botol BD', 'BHP Parafilm', 'BHP Tips', 'BHP Cotton Swab', 'BHP Ab Tambahan', 'ESBL', 'MRSA' ]; fputcsv($handle, array_merge($staticHeaders, $listAntibiotik)); $query = Periksa::query()->whereYear('daftar', $tahun); if ($bulan != 'ALL' && $bulan != 'Pick Month') { $query->whereMonth('daftar', $bulan); } $query->chunk(500, function($rows) use ($handle, $listAntibiotik) { $chunkIds = $rows->pluck('id')->toArray(); $antibiotikLookup = $this->mapAntibiotikData($chunkIds); foreach ($rows as $row) { $csvRow = [ $row->noloket, $row->status, $row->noregister, $row->nmpasien, $row->reques, $row->jkpasien, $row->daftar, $row->urgensi, $row->asalpasien, $row->kd_spesimen, $row->nm_spesimen, $row->updated_at, $row->bhp_media, $row->bhp_potsputum, $row->bhp_poturine, $row->bhp_oshe, $row->bhp_obyekglass, $row->bhp_botolbd, $row->bhp_parafilm, $row->bhp_tips, $row->bhp_cottonswab, $row->bhp_antibiotiktambahan, $row->id_esbl, $row->id_mrsa ]; foreach ($listAntibiotik as $headerAb) { $val = $antibiotikLookup[$row->id][$headerAb] ?? ''; $csvRow[] = $val; } fputcsv($handle, $csvRow); } }); fclose($handle); }); $response->headers->set('Content-Type', 'text/csv'); $response->headers->set('Content-Disposition', 'attachment; filename="RekapAntibiotik_'.$bulan.'_'.$tahun.'.csv"'); return $response; } private function getZnReportKomponenList() { return [ 'id_pewarnaanziehlnielsen', 'id_pewarnaanziehlnielsensewaktu', 'lsg_pewarnaanziehlnielsen', 'lsg_pewarnaanziehlnielsensewaktu', 'hasilpemeriksaantbbiakan_pagi', 'hasilpemeriksaantbbiakan_sewaktu', 'hasilpemeriksaantmikroskopis_hasilpagi', 'hasilpemeriksaantmikroskopis_hasilsewaktu', ]; } private function normalizeZnReportValue($value) { $value = trim(strip_tags((string) $value)); $value = preg_replace('/\s+/', ' ', $value); $upperValue = strtoupper($value); if ($upperValue === 'NEG') { return 'Tidak ditemukan Bakteri Tahan Asam (BTA)'; } if ($upperValue === '1-9') { return 'Ditemukan Bakteri Tahan Asam 0-9 BTA (scanty)'; } if ($value === '+') { return 'Ditemukan Bakteri Tahan Asam (BTA) 1+'; } if ($value === '++') { return 'Ditemukan Bakteri Tahan Asam (BTA) 2+'; } if ($value === '+++') { return 'Ditemukan Bakteri Tahan Asam (BTA) 3+'; } return $value; } private function periksaHasZnReportValue($periksa, $nilai, $komponenList) { return $periksa->komponen ->whereIn('komponen', $komponenList) ->filter(function ($komponen) use ($nilai) { return $this->normalizeZnReportValue($komponen->isidata) === $nilai; }) ->count() > 0; } public function genZNreport(Request $request) { $data = []; $bulan = $request->input('bulan'); $tahun = $request->input('tahun'); if ($tahun == '' OR is_null($tahun)){ $getarray = explode('?', $bulan); $bulan = $getarray[0] ?? date('m'); $tahun = $getarray[1] ?? date('Y'); $bulan = str_replace('bulan=', '', $bulan); $tahun = str_replace('tahun=', '', $tahun); } $komponenList = $this->getZnReportKomponenList(); $nilaiList = Organisms::where('kelompok', 'Pewarnaan Ziehl Nielsen')->pluck('name')->toArray(); if ($bulan == '' OR $bulan == 'ALL'){ $periksa = Periksa::with(['komponen' => function($q) use ($komponenList){ $q->whereIn('komponen', $komponenList); }]) ->whereYear('mulai', $tahun) ->get(); } else { $periksa = Periksa::with(['komponen' => function($q) use ($komponenList){ $q->whereIn('komponen', $komponenList); }]) ->whereMonth('mulai', $bulan) ->whereYear('mulai', $tahun) ->get(); } $kdSpesimenList = $periksa ->pluck('kd_spesimen') ->unique() ->values(); $rekapLaki = []; $rekapPerempuan = []; foreach ($nilaiList as $nilai) { foreach ($kdSpesimenList as $spesimen) { $rekapLaki[$nilai][$spesimen] = $periksa ->where('kd_spesimen', $spesimen) ->where('jkpasien', 'L') ->filter(function($px) use ($nilai, $komponenList){ return $this->periksaHasZnReportValue($px, $nilai, $komponenList); })->count(); $rekapPerempuan[$nilai][$spesimen] = $periksa ->where('kd_spesimen', $spesimen) ->where('jkpasien', 'P') ->filter(function($px) use ($nilai, $komponenList){ return $this->periksaHasZnReportValue($px, $nilai, $komponenList); })->count(); } } $chartL = []; $chartP = []; foreach ($nilaiList as $nilai) { $chartL[] = array_sum($rekapLaki[$nilai]); $chartP[] = array_sum($rekapPerempuan[$nilai]); } return view('cetak.znreport', compact( 'rekapLaki', 'rekapPerempuan', 'kdSpesimenList', 'nilaiList', 'bulan', 'tahun', 'chartL', 'chartP' )); } public function genTATreport(Request $request) { $data = []; $bulan = $request->input('bulan'); $tahun = $request->input('tahun'); if ($tahun == '' OR is_null($tahun)){ $getarray = explode('?', $bulan); $bulan = $getarray[0] ?? date('m'); $tahun = $getarray[1] ?? date('Y'); $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(); if ($periksa->count() == 0) { 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(); return view('cetak.tatreport', [ 'bulan' => $bulan, 'tahun' => $tahun, 'detail' => $hasil, 'rekap' => $rekap ]); } public function genRekapPenerimaanSample(Request $request) { $data = []; $tanggal = $request->input('tanggal'); $tanggal = str_replace('tanggal=', '', $tanggal); $query = Periksa::select('*'); $periksa = $query->whereDate('daftar', $tanggal)->orderBy('id', 'ASC')->get(); if ($periksa->count() == 0) { return response()->json([]); } $histories = RekapPenerimaanSamplePrintHistory::whereDate('tanggal', $tanggal) ->orderBy('printed_at', 'DESC') ->orderBy('id', 'DESC') ->get() ->map(function ($h) { $rowIds = json_decode($h->row_ids, true); $rowsPayload = json_decode($h->rows_payload, true); return [ 'id' => $h->id, 'printed_by_id' => $h->printed_by_id, 'printed_by_name' => $h->printed_by_name, 'printed_at' => $h->printed_at, 'printed_at_label' => $h->printed_at ? Carbon::parse($h->printed_at)->format('Y-m-d H:i:s') : '-', 'row_ids' => is_array($rowIds) ? $rowIds : [], 'rows_payload' => is_array($rowsPayload) ? $rowsPayload : [], 'total_rows' => is_array($rowIds) ? count($rowIds) : 0, ]; }) ->values(); return view('cetak.rekappenerimaansample', [ 'tanggal' => $tanggal, 'detail' => $periksa, 'printHistories' => $histories ]); } public function markRekapPenerimaanSamplePrinted(Request $request) { $userId = Session::get('id'); $userNama = Session::get('nama'); if (empty($userId)) { return response()->json([ 'status' => 'error', 'message' => 'Session login tidak valid.' ], 401); } $ids = $request->input('ids', []); if (!is_array($ids) || count($ids) === 0) { return response()->json([ 'status' => 'error', 'message' => 'Data yang dipilih tidak valid.' ], 422); } $ids = collect($ids) ->filter(function ($id) { return is_numeric($id); }) ->map(function ($id) { return intval($id); }) ->unique() ->values() ->toArray(); if (count($ids) === 0) { return response()->json([ 'status' => 'error', 'message' => 'Data yang dipilih tidak valid.' ], 422); } $tanggal = $request->input('tanggal'); $tanggal = !empty($tanggal) ? $tanggal : null; $printableIds = Periksa::whereIn('id', $ids) ->where(function ($query) { $query->whereNull('ppdsjunior2') ->orWhere('ppdsjunior2', 0); }) ->pluck('id') ->toArray(); if (count($printableIds) === 0) { return response()->json([ 'status' => 'error', 'message' => 'Semua data yang dipilih sudah pernah dicetak.' ], 422); } if (count($printableIds) > 0) { Periksa::whereIn('id', $printableIds)->update([ 'ppdsjunior2' => $userId, 'nmppdsjunior2' => $userNama, 'updated_at' => date('Y-m-d H:i:s'), ]); } // Ambil data setelah update supaya payload cetak (petugas) sesuai yang tampil di tabel $rowsToPrint = Periksa::whereIn('id', $printableIds) ->orderBy('id', 'ASC') ->get() ->map(function ($row) { $petugas = trim(($row->nmppdsmiddle2 ?? '').' '.($row->nmppdsjunior2 ?? '')); $status = trim((string)($row->status ?? '')); if ($status === '') { $status = '-'; } return [ 'id' => $row->id, 'noregister' => $row->noregister ?? '', 'nmpasien' => $row->nmpasien ?? '', 'nofoto' => $row->nofoto ?? '', 'asalpasien' => $row->asalpasien ?? '', 'daftar' => $row->daftar ?? '', 'reques' => $row->reques ?? '', 'kd_spesimen' => $row->kd_spesimen ?? '', 'nm_spesimen' => $row->nm_spesimen ?? '', 'status' => $status, 'tgldraft' => $row->tgldraft ?? '', 'petugas' => $petugas, ]; }) ->values() ->toArray(); $history = RekapPenerimaanSamplePrintHistory::create([ 'tanggal' => $tanggal, 'printed_by_id' => $userId, 'printed_by_name' => $userNama, 'printed_at' => Carbon::now()->format('Y-m-d H:i:s'), 'row_ids' => json_encode(array_values($printableIds)), 'rows_payload' => json_encode($rowsToPrint), 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s'), ]); $historyResponse = [ 'id' => $history->id, 'printed_by_id' => $history->printed_by_id, 'printed_by_name' => $history->printed_by_name, 'printed_at' => $history->printed_at, 'printed_at_label' => Carbon::parse($history->printed_at)->format('Y-m-d H:i:s'), 'row_ids' => $printableIds, 'rows_payload' => $rowsToPrint, 'total_rows' => count($printableIds), ]; return response()->json([ 'status' => 'success', 'message' => 'Status cetak berhasil diperbarui.', 'affected_ids'=> $printableIds, 'printed_by' => $userNama, 'history' => $historyResponse ]); } }