diff --git a/htdocs/app/Http/Controllers/DokterController.php b/htdocs/app/Http/Controllers/DokterController.php index e607e1ea..33036b3c 100644 --- a/htdocs/app/Http/Controllers/DokterController.php +++ b/htdocs/app/Http/Controllers/DokterController.php @@ -842,7 +842,7 @@ class DokterController extends Controller return 9; } - if (str_starts_with($normalized, 'id/ast pending result')) { + if (str_starts_with($normalized, 'id/ast pending result') || $normalized === 'sedang id+ast') { return 10; } @@ -862,7 +862,6 @@ class DokterController extends Controller } protected function isProsesingKoloniMediaStatus(string $normalizedStatus): bool { $exactStatuses = [ - 'sedang id/ast', 'tidak ada pertumbuhan', 'tidak lanjut identifikasi', 'tidak tindak lanjut identifikasi', diff --git a/htdocs/app/Services/AstmMessageService.php b/htdocs/app/Services/AstmMessageService.php index 8527eeac..ef73230f 100644 --- a/htdocs/app/Services/AstmMessageService.php +++ b/htdocs/app/Services/AstmMessageService.php @@ -64,6 +64,147 @@ class AstmMessageService return preg_replace('/[^\x20-\x7E|]+/', '', $string); } + protected function updatePeriksaStatusByHierarchy($nofoto, $proposedStatus): void + { + $proposedStatus = trim((string) $proposedStatus); + + if ($nofoto === null || $nofoto === '' || $proposedStatus === '') { + return; + } + + Periksa::where('nofoto', $nofoto)->get()->each(function ($periksa) use ($proposedStatus) { + if (in_array($periksa->status, ['Arsip', 'Dibatalkan (Arsip)', 'Batal'], true)) { + return; + } + + $resolvedStatus = $this->resolvePeriksaHierarchyStatus($periksa->status, $proposedStatus); + + if ($resolvedStatus !== $periksa->status) { + $periksa->update(['status' => $resolvedStatus]); + } + }); + } + + protected function resolvePeriksaHierarchyStatus($currentStatus, $proposedStatus): string + { + $currentStatus = trim((string) $currentStatus); + $proposedStatus = trim((string) $proposedStatus); + + if ($proposedStatus === '') { + return $currentStatus; + } + + $currentRank = $this->periksaHierarchyStatusRank($currentStatus); + $proposedRank = $this->periksaHierarchyStatusRank($proposedStatus); + + if ($currentStatus === '') { + return $proposedStatus; + } + + if ($proposedRank === null) { + return $currentRank === null ? $proposedStatus : $currentStatus; + } + + if ($currentRank === null || $proposedRank >= $currentRank) { + return $proposedStatus; + } + + return $currentStatus; + } + + protected function periksaHierarchyStatusRank($status): ?int + { + $normalized = $this->normalizePeriksaStatus($status); + + if ($normalized === '') { + return null; + } + + if ($normalized === 'penerimaan sampel') { + return 1; + } + + if (in_array($normalized, ['pemeriksaan awal', 'pemeriksaan sampel', 'proses analisis sampel'], true)) { + return 2; + } + + if (str_starts_with($normalized, 'data bd di terima') || str_starts_with($normalized, 'data bd diterima')) { + return 3; + } + + if ($normalized === 'pewarnaan langsung') { + return 4; + } + + if ($this->isProsesingKoloniMediaStatus($normalized)) { + return 5; + } + + if (str_starts_with($normalized, 'data malditof diterima') + || str_starts_with($normalized, 'data malditof di terima') + || str_starts_with($normalized, 'data genexpert diterima') + || str_starts_with($normalized, 'data genexpert di terima')) { + return 6; + } + + if (str_starts_with($normalized, 'otor maldi (un verified)')) { + return 7; + } + + if (str_starts_with($normalized, 'preliminary results')) { + return 8; + } + + if (str_starts_with($normalized, 'data vitek di terima') || str_starts_with($normalized, 'data vitek diterima')) { + return 9; + } + + if (str_starts_with($normalized, 'id/ast pending result') || $normalized === 'sedang id+ast') { + return 10; + } + + if (str_starts_with($normalized, 'expertise saved (un verified)') + || in_array($normalized, ['expertise', 'selesai', 'final result'], true)) { + return 11; + } + + return null; + } + + protected function normalizePeriksaStatus($status): string + { + $status = strtolower(trim((string) $status)); + $status = str_replace(['_', '-'], ' ', $status); + $status = preg_replace('/\s+/', ' ', $status); + + return trim($status); + } + + protected function isProsesingKoloniMediaStatus(string $normalizedStatus): bool + { + $exactStatuses = [ + 'tidak ada pertumbuhan', + 'tidak lanjut identifikasi', + 'tidak tindak lanjut identifikasi', + 'inkubasi lanjutan', + 'sub kultur', + 'menunggu kultur yg lain', + 'menunggu kultur yang lain', + 'proses identifikasi dan uji kepekaan', + 'sedang malditof', + 'pertumbuhan primer', + ]; + + if (in_array($normalizedStatus, $exactStatuses, true)) { + return true; + } + + return str_starts_with($normalizedStatus, 'prosesing koloni media') + || str_starts_with($normalizedStatus, 'processing koloni media') + || str_starts_with($normalizedStatus, 'proses identifikasi') + || str_starts_with($normalizedStatus, 'proses uji kepekaan'); + } + /** * Parsing data berdasarkan format yang diberikan */ @@ -621,9 +762,7 @@ class AstmMessageService } else { $status = 'Data Genexpert di Terima'; } - Periksa::where('nofoto', $accessionNumber)->whereNotIn('status', ['Selesai', 'Arsip', 'Dibatalkan (Arsip)', 'Batal'])->update([ - 'status' => $status, - ]); + $this->updatePeriksaStatusByHierarchy($accessionNumber, $status); } Riwayat::create([ @@ -881,11 +1020,7 @@ class AstmMessageService // ==================================================================== try { - Periksa::where('nofoto', $accession_number) - ->whereNotIn('status', ['Selesai', 'Arsip', 'Dibatalkan (Arsip)', 'Batal']) - ->update([ - 'status' => 'Data GeneXpert di Terima' - ]); + $this->updatePeriksaStatusByHierarchy($accession_number, 'Data GeneXpert di Terima'); Riwayat::create([ 'nofoto' => $accession_number, @@ -1050,9 +1185,7 @@ class AstmMessageService // Simpan ke database if ($noregister){ - Periksa::where('nofoto', $accession_number)->update([ - 'status' => 'Data Vitek di Terima', - ]); + $this->updatePeriksaStatusByHierarchy($accession_number, 'Data Vitek di Terima'); //Log::info("Data berhasil disimpan:", $resultSample->toArray()); $resultSample->save(); } @@ -1231,9 +1364,7 @@ class AstmMessageService } } - Periksa::where('nofoto', $accession_number)->whereNotIn('status', ['Selesai', 'Arsip', 'Dibatalkan (Arsip)', 'Batal'])->update([ - 'status' => 'Data Vitek di Terima', - ]); + $this->updatePeriksaStatusByHierarchy($accession_number, 'Data Vitek di Terima'); } //Log::info("Data MTRL Berhasil di Parse dan di simpan ", $resultSample->toArray()); return response()->json(['message' => 'Data berhasil diproses dan disimpan.']); @@ -1428,9 +1559,7 @@ class AstmMessageService DB::table('lis_phoenix')->where('id', $data->id)->update([ 'processed' => $ok ? 1 : 9 ]); - Periksa::where('nofoto', $data->no_id)->whereNotIn('status', ['Selesai', 'Arsip', 'Dibatalkan (Arsip)', 'Batal'])->update([ - 'status' => 'Data BD di Terima ('.$data->organisme.')', - ]); + $this->updatePeriksaStatusByHierarchy($data->no_id, 'Data BD di Terima ('.$data->organisme.')'); KomponenJawaban::updateOrCreate( [ 'accnumber' => $data->no_id, @@ -1500,9 +1629,7 @@ class AstmMessageService DataListiner::where('urut', $data->urut)->update([ 'processed' => $ok ? 1 : 9 ]); - Periksa::where('nofoto', $data->no_id)->whereNotIn('status', ['Selesai', 'Arsip', 'Dibatalkan (Arsip)', 'Batal'])->update([ - 'status' => 'Data BD di Terima ('.$data->organisme.')', - ]); + $this->updatePeriksaStatusByHierarchy($data->no_id, 'Data BD di Terima ('.$data->organisme.')'); KomponenJawaban::updateOrCreate( [ 'accnumber' => $data->no_id, diff --git a/listener/geneexpert.py b/listener/geneexpert.py index 431e81e9..5e8a24e3 100644 --- a/listener/geneexpert.py +++ b/listener/geneexpert.py @@ -184,8 +184,8 @@ GENEXPERT_TEST_MAPPING = { } GENEXPERT_IP_CAPABILITIES = { "10.10.120.75": ["MTBRIF", "HBVVL", "HIV1-VL", "MTB-XDR 2", "HCV", "SARSCOV2FLURSV"], - "10.10.120.108": ["HCV", "HIV1-VL", "HBVVL"], "10.10.120.73": ["MTBRIF", "HBVVL", "HIV1-VL", "HCV", "SARSCOV2FLURSV"], + "10.10.120.108": ["HCV", "HIV1-VL", "HBVVL"], } DEFAULT_GXP_CODE = "MTBRIF"