diff --git a/htdocs/app/Http/Controllers/ReportController.php b/htdocs/app/Http/Controllers/ReportController.php index 904083e4..4d15426b 100644 --- a/htdocs/app/Http/Controllers/ReportController.php +++ b/htdocs/app/Http/Controllers/ReportController.php @@ -1055,6 +1055,53 @@ class ReportController extends Controller 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'); @@ -1068,12 +1115,7 @@ class ReportController extends Controller } // komponen Ziehl yang mau dianalisa - $komponenList = [ - 'id_pewarnaanziehlnielsen', - 'id_pewarnaanziehlnielsensewaktu', - 'lsg_pewarnaanziehlnielsen', - 'lsg_pewarnaanziehlnielsensewaktu' - ]; + $komponenList = $this->getZnReportKomponenList(); // Nilai Ziehl yang ingin dihitung $nilaiList = Organisms::where('kelompok', 'Pewarnaan Ziehl Nielsen')->pluck('name')->toArray(); @@ -1111,10 +1153,7 @@ class ReportController extends Controller ->where('kd_spesimen', $spesimen) ->where('jkpasien', 'L') ->filter(function($px) use ($nilai, $komponenList){ - return $px->komponen - ->whereIn('komponen', $komponenList) - ->where('isidata', $nilai) - ->count() > 0; + return $this->periksaHasZnReportValue($px, $nilai, $komponenList); })->count(); // hitung perempuan @@ -1122,10 +1161,7 @@ class ReportController extends Controller ->where('kd_spesimen', $spesimen) ->where('jkpasien', 'P') ->filter(function($px) use ($nilai, $komponenList){ - return $px->komponen - ->whereIn('komponen', $komponenList) - ->where('isidata', $nilai) - ->count() > 0; + return $this->periksaHasZnReportValue($px, $nilai, $komponenList); })->count(); } } diff --git a/htdocs/app/Services/AstmMessageService.php b/htdocs/app/Services/AstmMessageService.php index df1b2beb..f3267975 100644 --- a/htdocs/app/Services/AstmMessageService.php +++ b/htdocs/app/Services/AstmMessageService.php @@ -600,55 +600,64 @@ class AstmMessageService return false; } } + public function processAstmMessagesgenExpert($response, $alat) { - // 1. Normalisasi karakter pembatas baris (\r\n, \r, atau \n diubah jadi \n) - $normalizedData = str_replace(["\r\n", "\r"], "\n", $response); - $segments = explode("\n", $normalizedData); + $normalizedData = str_replace(["\r\n", "\r"], "\n", $response); + $segments = explode("\n", $normalizedData); + $patient_id = ''; + $patient_name = ''; + $accession_number = ''; + + // Array untuk menyimpan data terstruktur + $parsedResults = []; + $hasil_list = []; // Tetap dipertahankan untuk kebutuhan legacy/summary - $patient_id = ''; - $patient_name = ''; - $accession_number = ''; // NoReg - $hasil_list = []; - - // 2. Looping setiap baris data ASTM foreach ($segments as $rsegmen) { $cekdata = explode('|', $rsegmen); if (empty($cekdata[0])) continue; - + $recordType = preg_replace("/[^a-zA-Z]/", "", $cekdata[0]); - - // Ekstrak Data Pasien (P) + if ($recordType === 'P') { $patient_id = $cekdata[3] ?? ($cekdata[4] ?? ''); if (isset($cekdata[5])) { $patient_name = trim(str_replace('^', ' ', $cekdata[5])); } } - - // Ekstrak Nomor Order (O) + if ($recordType === 'O') { $accession_number = $cekdata[2] ?? ''; } - - // Ekstrak Hasil Analisa (R) + if ($recordType === 'R') { if (isset($cekdata[2]) && isset($cekdata[3])) { - $test_info = $cekdata[2]; // Format contoh: ^^^MTB-RIF_ULTRA 2^^^MTB^ - $result_val = trim(str_replace('^', '', $cekdata[3])); // Contoh: DETECTED / PASS / INVALID - - // [KUNCI]: Buang baris yang berisi kurva angka (Ct / EndPt) agar tidak nyampah dan kepanjangan - if (strpos($rsegmen, 'Ct|') === false && strpos($rsegmen, 'EndPt|') === false && $result_val !== '') { + $test_info_raw = $cekdata[2]; + $result_val = trim(str_replace('^', '', $cekdata[3])); + + if ($result_val !== '') { + // Pecah test info berdasarkan '^' + $test_info = explode('^', $test_info_raw); - // Ambil nama target spesifik (misal 'MTB' atau 'RIF Resistance' atau 'SPC') - $target_match = explode('^^^', $test_info); - $target_name = ''; - if (count($target_match) > 1) { - $target_name = trim(str_replace('^', '', end($target_match))); + // Pada format GeneXpert: index ke-6 biasanya nama target (FII, FII 20210G, dll) + // index ke-7 biasanya penanda tipe data (Ct, EndPt) + $target_name = $test_info[6] ?? 'Unknown Target'; + $metric_type = $test_info[7] ?? 'Result'; // Jika tidak ada, berarti ini Result (POS/NEG) + + // Inisialisasi array untuk target ini jika belum ada + if (!isset($parsedResults[$target_name])) { + $parsedResults[$target_name] = [ + 'Result' => '-', + 'Ct' => '-', + 'EndPt' => '-' + ]; } - // Simpan ke array jika valid - if ($target_name && $result_val) { + // Masukkan nilai ke dalam struktur data + $parsedResults[$target_name][$metric_type] = $result_val; + + // Untuk summary legacy (kolom organism/additional_result) + if ($metric_type === 'Result') { $hasil_list[] = $target_name . ": " . $result_val; } } @@ -661,50 +670,143 @@ class AstmMessageService return false; } - // 3. Gabungkan hasil dari array menjadi 1 string ("MTB: DETECTED | RIF Resistance: NOT DETECTED") - $kesimpulan = implode(" | ", $hasil_list); + // ==================================================================== + // MEMBUAT HTML REPORT & GRAFIK (CHART.JS) + // ==================================================================== + + // 1. Buat Tabel HTML + $reporthtml = '
| Target/Analyte | +Result | +Ct Value | +EndPt | +
|---|---|---|---|
| {$target} | +{$data['Result']} | +{$data['Ct']} | +{$data['EndPt']} | +