'Growth/Detection',
'accession_number' => $resultData[2],
'status' => $resultData[3], // Positif atau Negatif
'completion_time' => $resultData[7]
];
}
// Proses untuk Isolate Result
function processIsolateResult($rawData){
$resultData = explode('|', $rawData);
return [
'test_type' => 'Isolate',
'isolate_result' => $resultData[3] ?? null,
'antibiotic' => $resultData[4] ?? null,
'value' => $resultData[5] ?? null,
'status' => $resultData[6] ?? null,
'completion_time' => $resultData[10] ?? null
];
}
// Proses untuk Other Test Result
function processOtherResult($rawData){
// Format: R|1| ^ ^ ^OTHER^Seq123|Complete| ...
$resultData = explode('|', $rawData);
return [
'test_type' => 'Other',
'sequence_number' => $resultData[3],
'result' => $resultData[4],
'description' => $resultData[5],
'completion_time' => $resultData[6]
];
}
class AstmMessageService
{
/**
* Membersihkan string dari karakter non-printable
*/
private function cleanString($string)
{
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)->whereNotNull('status')->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')) {
return 10;
}
if (in_array($normalized, ['expertise', 'selesai', 'final result'], true) || str_starts_with($normalized, 'expertise saved (un verified)')) {
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',
'sedang id+ast',
'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
*/
private function parseResultData($rawData, $format)
{
$resultData = explode('|', $rawData);
$parsedData = [];
foreach ($format as $key => $index) {
$parsedData[$key] = $resultData[$index] ?? null;
}
return $parsedData;
}
/**
* Proses hasil AST Record
*/
public function processAstResult($rawData)
{
$format = [
'test_type' => 0,
'accession_number' => 2,
'antibiotic' => 3,
'susceptibility' => 4,
'value' => 5,
'status' => 6,
'completion_time' => 10
];
return $this->parseResultData($rawData, $format);
}
/**
* Proses hasil ID Record
*/
public function processIdResult($rawData)
{
$format = [
'test_type' => 0,
'accession_number' => 2,
'organism_name' => 3,
'status' => 6,
'completion_time' => 10
];
return $this->parseResultData($rawData, $format);
}
public function createHeader($senderName, $versionNumber)
{
$messageDateTime = Carbon::now()->format('YmdHis');
return "H|{$senderName}|{$versionNumber}|{$messageDateTime}";
}
// Fungsi untuk membuat Patient Record (P)
public function createPatientRecord($patient)
{
// Extract fields from $patient array, adjust field positions based on mapping
return "P|{$patient['id']}|{$patient['last_name']}|{$patient['first_name']}|{$patient['middle_name']}|{$patient['suffix']}|{$patient['dob']}|{$patient['sex']}|{$patient['address']}||{$patient['phone']}|{$patient['admitting_physician']}";
}
// Fungsi untuk membuat Order Record (O)
public function createOrderRecord($order)
{
// Order fields based on mapping (Accession Number, Test ID, etc.)
return "O|{$order['accession_number']}|{$order['isolate_number']}|{$order['organism']}|{$order['exclude_isolate']}|{$order['priority']}|{$order['collection_date_time']}|{$order['collected_by']}|{$order['received_by']}|{$order['specimen_action_code']}|{$order['isolate_source_test']}|{$order['isolate_source_test_start_time']}|{$order['receipt_date_time']}|{$order['specimen_type']}|{$order['body_site']}|{$order['ordering_physician']}|{$order['ordering_physician_phone']}|{$order['ordering_physician_fax']}|{$order['ordering_physician_pager']}|{$order['specimen_user_field_1']}|{$order['specimen_user_field_2']}|{$order['specimen_user_field_3']}|{$order['specimen_user_field_4']}|{$order['specimen_user_field_5']}|{$order['finalized_date_time']}|{$order['specimen_reimbursement_value']}|{$order['test_reimbursement_value']}|{$order['isolate_classification']}"; }
public function createTerminatorRecord($order)
{
// Order fields based on mapping (Accession Number, Test ID, etc.)
return "L|1|N";
}
// Fungsi untuk membuat pesan lengkap (header + patient + order)
public function createMessage($senderName, $versionNumber, $patient, $order)
{
$header = $this->createHeader($senderName, $versionNumber);
$patientRecord = $this->createPatientRecord($patient);
$orderRecord = $this->createOrderRecord($order);
$terimatorRecord= $this->createTerminatorRecord($order);
return implode("\n", [$header, $patientRecord, $orderRecord, $terimatorRecord]);
}
/**
* Proses data ASTM Response
*/
protected function astmToDateTime(?string $value): ?string
{
if (!$value) return null;
if (preg_match('/(\d{14})/', $value, $m)) {
return Carbon::createFromFormat(
'YmdHis',
$m[1]
)->format('Y-m-d H:i:s');
}
return null;
}
protected function splitBDAstmMessages(string $raw): array
{
// bersihkan karakter kontrol
$clean = preg_replace('/[\x02\x03\x04\x17]/', '', $raw);
$lines = preg_split("/\r\n|\n|\r/", $clean);
$messages = [];
$current = [];
foreach ($lines as $line) {
// Ketemu H baru → simpan pesan sebelumnya
if (str_starts_with($line, 'H|') && !empty($current)) {
$messages[] = implode("\n", $current);
$current = [];
}
$current[] = $line;
// Akhir pesan
if (str_starts_with($line, 'L|')) {
$messages[] = implode("\n", $current);
$current = [];
}
}
// sisa buffer
if (!empty($current)) {
$messages[] = implode("\n", $current);
}
return $messages;
}
protected function reassembleAstmFrames(string $raw): string
{
$buffer = '';
$frames = explode("\x02", $raw);
foreach ($frames as $frame) {
if ($frame === '') {
continue;
}
$content = $frame;
$etxPos = strpos($content, "\x03");
$etbPos = strpos($content, "\x17");
if ($etxPos !== false && ($etbPos === false || $etxPos < $etbPos)) {
$content = substr($content, 0, $etxPos);
} elseif ($etbPos !== false) {
$content = substr($content, 0, $etbPos);
}
if ($content !== '' && ctype_digit($content[0])) {
$content = substr($content, 1);
}
$buffer .= $content;
}
return trim($buffer) !== '' ? trim($buffer) : trim($raw);
}
protected function normalizeBDResult(?string $value): ?string
{
$value = trim((string) $value);
if ($value === '') {
return null;
}
if (stripos($value, 'NEGATIVE') !== false) {
return 'NEGATIVE';
}
if (stripos($value, 'POSITIVE') !== false) {
return 'POSITIVE';
}
return explode('^', $value)[0] ?: null;
}
protected function normalizeAstmRecordLines(string $raw): string
{
$normalized = str_replace(["\r\n", "\r"], "\n", $raw);
if (str_contains($normalized, "\n")) {
return $normalized;
}
$fields = explode('|', $normalized);
$records = [];
$current = [];
foreach ($fields as $index => $field) {
$isSegmentStart = $this->isAstmSegmentStart($fields, $index);
if ($isSegmentStart && !empty($current)) {
$records[] = implode('|', $current);
$current = [];
}
$current[] = $field;
}
if (!empty($current)) {
$records[] = implode('|', $current);
}
return !empty($records) ? implode("\n", $records) : $normalized;
}
protected function isAstmSegmentStart(array $fields, int $index): bool
{
$field = $fields[$index] ?? '';
if ($field === 'H') {
return $index === 0;
}
if (!in_array($field, ['P', 'O', 'R', 'L'], true)) {
return false;
}
$next = $fields[$index + 1] ?? null;
return $next !== null && preg_match('/^\d+$/', (string) $next) === 1;
}
protected function processBDAstmResponse(string $raw, $data): bool
{
try {
// =========================
// PREPARE
// =========================
$accnumber= '';
$resultDateTime = null;
$bdResult = null;
$rawClean = preg_replace('/[\x02\x03\x04\x17]/', '', $this->reassembleAstmFrames($raw));
$lines = preg_split("/\r\n|\n|\r/", $rawClean);
$parsed = [
'header' => [],
'patient'=> [],
'order' => [],
'result' => [],
'instrument' => []
];
// =========================
// PARSE LOOP
// =========================
foreach ($lines as $line) {
if (str_starts_with($line, 'H|')) {
$f = explode('|', $line);
$resultDateTime = $this->astmToDateTime($f[13] ?? null);
$parsed['header'] = [
'sender_name' => $data->alat ?? ($f[4] ?? 'BD Instrument'),
'version_number' => $f[12] ?? 'V1.0',
'message_datetime' => $this->astmToDateTime($f[13] ?? null)
];
} elseif (str_starts_with($line, 'P|')) {
$f = explode('|', $line);
$name = explode(' ', $f[5] ?? '');
$parsed['patient'] = [
'patient_id' => $f[3] ?? null,
'patient_name_last' => $name[0] ?? null,
'patient_name_first'=> $name[1] ?? null,
'patient_dob' => $this->astmToDateTime($f[7] ?? null),
'patient_sex' => $f[8] ?? null,
'patient_phone' => $f[13] ?? null,
'address_street' => $f[11] ?? null,
'hospital_client' => $f[29] ?? null,
];
} elseif (str_starts_with($line, 'O|')) {
$f = explode('|', $line);
$test = explode('^', $f[4] ?? '');
$accnumber = $f[2] ?? null;
$parsed['order'] = [
'accession_number' => $f[2] ?? null,
'test_id' => $test[3] ?? null,
'specimen_type' => $f[15] ?? null,
'body_site' => $f[16] ?? null,
'test_start_datetime'=> $this->astmToDateTime($f[7] ?? null),
];
} elseif (str_starts_with($line, 'R|')) {
$f = explode('|', $line);
$test = explode('^', $f[2] ?? '');
$bdResult = $this->normalizeBDResult($f[3] ?? null) ?? $bdResult;
$resultDateTime = $this->astmToDateTime($f[12] ?? null)
?? $this->astmToDateTime($f[11] ?? null)
?? $resultDateTime;
// Instrument detail di akhir baris
preg_match('/(MGIT960|BACTECFX)[^|]*/', $line, $inst);
$parsed['result'] = [
'organism' => $test[2] ?? null,
'test_status' => $bdResult ?? explode('^', $f[3] ?? '')[0],
'result_status_datetime' => $resultDateTime,
];
$parsed['instrument'] = [
'instrument_type' => str_contains($line, 'MGIT960') ? 'MGIT960' : 'BACTECFX',
'instrument_number' => $inst[0] ?? null,
];
} else {
$cekline = explode('|F|', $line);
if (isset($cekline[1])){
$f = explode('|', $cekline[1]);
$resultDateTime2 = $this->astmToDateTime($f[3] ?? null);
if ($resultDateTime2){
$parsed['result'] = array_merge($parsed['result'], [
'result_status_datetime' => $resultDateTime2,
]);
$parsed['instrument'] = array_merge($parsed['instrument'], [
'instrument_type' => $f[4] ?? null,
]);
}
}
}
}
// =========================
// SAVE TO DATABASE
// =========================
$resultSample = new ResultSample();
$resultSample->fill(array_merge(
$parsed['header'],
$parsed['patient'],
$parsed['order'],
$parsed['result'],
$parsed['instrument']
));
$resultSample->additional_result = [
'raw_astm' => $raw,
'source' => 'BD'
];
$resultSample->save();
if ($accnumber != '' AND isset($resultDateTime)){
KomponenJawaban::updateOrCreate(
[
'accnumber' => $accnumber,
'komponen' => 'bd_result_date',
'isidata' => $resultDateTime,
],
[
'template' => 'Kultur',
'created_by' => 'BD'
]
);
}
if ($accnumber != '' && $bdResult){
KomponenJawaban::updateOrCreate(
[
'accnumber' => $accnumber,
'komponen' => 'bd_result',
'isidata' => $bdResult,
],
[
'template' => 'Kultur',
'created_by' => 'BD'
]
);
}
$this->updatePeriksaStatusByHierarchy($accnumber, 'Data BD Diterima ('. $bdResult . ')');
return true;
} catch (\Throwable $e) {
Log::error('BD ASTM parse error', [
'msg' => $e->getMessage()
]);
return false;
}
}
protected function splitHl7LikeMessages(string $raw): array
{
$normalized = str_replace(["\r\n", "\r"], "\n", $raw);
$normalized = preg_replace('/[\x00-\x08\x0B-\x1F\x7F]/', '', $normalized);
$normalized = preg_replace('/(?=MSH\|)/', "\n", $normalized);
$parts = preg_split('/\n\s*\n+/', trim($normalized)) ?: [];
$messages = [];
foreach ($parts as $part) {
$part = trim($part);
if ($part === '' || !str_contains($part, 'MSH|')) {
continue;
}
$start = strpos($part, 'MSH|');
if ($start !== false) {
$part = substr($part, $start);
}
$messages[] = trim($part);
}
return $messages;
}
protected function formatLocalInstrumentText(array $parsed, string $alat, ?string $accessionNumber, ?string $messageDateTime): string
{
$msh = $parsed['MSH'][0] ?? [];
$pid = $parsed['PID'][0] ?? [];
$obr = $parsed['OBR'][0] ?? [];
$obx = $parsed['OBX'][0] ?? [];
$nte = $parsed['NTE'][0] ?? [];
$qpd = $parsed['QPD'][0] ?? [];
$qid = $parsed['QID'][0] ?? [];
$spm = $parsed['SPM'][0] ?? [];
$messageType = $msh[8] ?? '-';
$patientName = $pid[3] ?? $pid[5] ?? '-';
$patientName = trim((string) $patientName, "\" \t\n\r\0\x0B");
$testId = $obr[4] ?? ($qpd[1] ?? '-');
$receivedAt = $messageDateTime ?? '-';
$escape = static fn ($value) => e($value ?: '-');
if (str_starts_with($alat, 'MYLA')) {
$organism = $obx[5] ?? '-';
$abnormalFlag = $obx[8] ?? '-';
$confidence = $obx[9] ?? '-';
$status = $obx[11] ?? '-';
$operator = $obx[16] ?? '-';
$resultAt = $this->astmToDateTime($obx[14] ?? null) ?? '-';
$comment = $nte[3] ?? '-';
$specimen = $spm[3] ?? '-';
return
'
'.
'
HASIL ALAT MYLA
'.
'
'.
'| No. Foto | : '.$escape($accessionNumber).' |
'.
'| No. Spesimen | : '.$escape($specimen).' |
'.
'| Pasien | : '.$escape($patientName).' |
'.
'| Jenis Pesan | : '.$escape($messageType).' |
'.
'| Test | : '.$escape($testId).' |
'.
'| Hasil | : '.$escape($organism).' |
'.
'| Abnormal Flag | : '.$escape($abnormalFlag).' |
'.
'| Confidence | : '.$escape($confidence).' |
'.
'| Status | : '.$escape($status).' |
'.
'| Operator | : '.$escape($operator).' |
'.
'| Komentar | : '.$escape($comment).' |
'.
'| Tanggal Hasil | : '.$escape($resultAt).' |
'.
'| Tanggal Diterima LIS | : '.$escape($receivedAt).' |
'.
'
'.
'
';
}
$orderAt = $this->astmToDateTime($parsed['ORC'][0][8] ?? null) ?? '-';
$queryId = $qid[1] ?? ($msh[9] ?? '-');
return
''.
'
HASIL ALAT GENEXPERT
'.
'
'.
'| No. Foto | : '.$escape($accessionNumber).' |
'.
'| Pasien | : '.$escape($patientName).' |
'.
'| Jenis Pesan | : '.$escape($messageType).' |
'.
'| Test/Assay | : '.$escape($testId).' |
'.
'| Order/Run ID | : '.$escape($queryId).' |
'.
'| Tanggal Order | : '.$escape($orderAt).' |
'.
'| Tanggal Diterima LIS | : '.$escape($receivedAt).' |
'.
'| Catatan | : Payload alat disimpan sebagai raw untuk ditinjau analis. |
'.
'
'.
'
';
}
protected function saveInstrumentRawResult(string $raw, string $alat): bool
{
try {
$segments = preg_split("/\r\n|\n|\r/", trim($raw)) ?: [];
$parsed = [];
foreach ($segments as $segment) {
$segment = trim($segment);
if ($segment === '' || !str_contains($segment, '|')) {
continue;
}
$fields = explode('|', $segment);
$segmentType = strtoupper(trim($fields[0] ?? ''));
if ($segmentType !== '') {
$parsed[$segmentType][] = $fields;
}
}
$msh = $parsed['MSH'][0] ?? [];
$pid = $parsed['PID'][0] ?? [];
$obr = $parsed['OBR'][0] ?? [];
$obx = $parsed['OBX'][0] ?? [];
$spm = $parsed['SPM'][0] ?? [];
$nte = $parsed['NTE'][0] ?? [];
$qpd = $parsed['QPD'][0] ?? [];
$qid = $parsed['QID'][0] ?? [];
$messageDateTime = $this->astmToDateTime($msh[6] ?? null);
$accessionNumber = $spm[3] ?? $pid[2] ?? $pid[3] ?? $qpd[3] ?? $qid[1] ?? null;
if ($accessionNumber) {
$accessionNumber = trim((string) $accessionNumber, "\"@ \t\n\r\0\x0B");
}
$patientName = $pid[3] ?? $pid[5] ?? null;
$patientName = $patientName ? trim((string) $patientName, "\" \t\n\r\0\x0B") : null;
$organism = $obx[5] ?? null;
$resultSample = new ResultSample();
$resultSample->sender_name = $alat;
$resultSample->version_number = $msh[11] ?? null;
$resultSample->message_datetime = $messageDateTime;
$resultSample->patient_id = $accessionNumber;
$resultSample->patient_name_last = $patientName;
$resultSample->accession_number = $accessionNumber;
$resultSample->test_id = $obr[4] ?? ($qpd[1] ?? null);
$resultSample->result_type_code = $obx[3] ?? ($msh[8] ?? null);
$resultSample->organism = $organism;
$resultSample->test_status = $obx[11] ?? null;
$resultSample->result_status_datetime = $this->astmToDateTime($obx[14] ?? null);
$resultSample->instrument_type = $alat;
$resultSample->protocol_name = $obr[4] ?? null;
$resultSample->result_data = $obx ? json_encode($obx) : null;
$resultSample->additional_result = [
'source' => 'local_instrument_fallback',
'raw_astm' => $raw,
'segments' => array_keys($parsed),
'nte' => $nte,
'qpd' => $qpd,
'qid' => $qid,
];
$resultSample->save();
if ($accessionNumber) {
$teksHasil = $this->formatLocalInstrumentText($parsed, $alat, $accessionNumber, $messageDateTime);
if ($organism !== '') {
$getnama = explode('^', $organism);
$organism = $getnama[1] ?? $organism;
$sudah = Organisms::where('name', $organism)->count();
if ($sudah == 0) {
Organisms::create([
'kelompok' => 'biakankultur',
'name' => $organism,
'category' => $alat,
]);
}
KomponenJawaban::updateOrCreate(
[
'accnumber' => $accessionNumber,
'komponen' => 'id_bakteri01',
'isidata' => $organism,
],
[
'template' => 'all',
'created_by' => $alat
]
);
if ($alat == 'MYLA-10.10.120.89') {
$status = 'Data Malditof di Terima';
} else {
$status = 'Data Genexpert di Terima';
}
$this->updatePeriksaStatusByHierarchy($accessionNumber, $status);
}
Riwayat::create([
'nofoto' => $accessionNumber,
'jawaban' => $teksHasil,
'inputor' => $alat,
'keterangan' => $messageDateTime ?: date('Y-m-d H:i:s'),
'verifikasi' => '',
]);
}
return true;
} catch (\Throwable $e) {
Log::error('Local instrument fallback parse error', [
'alat' => $alat,
'msg' => $e->getMessage(),
]);
return false;
}
}
public function processAstmMessagesgenExpert($response, $alat)
{
$normalizedData = $this->normalizeAstmRecordLines($response);
$segments = explode("\n", $normalizedData);
$patient_id = '';
$patient_name = '';
$accession_number = '';
$waktu_periksa = date('d-m-Y H:i:s');
$parsedResults = [];
$hasil_list = [];
foreach ($segments as $rsegmen) {
$cekdata = explode('|', $rsegmen);
if (empty($cekdata[0])) continue;
$recordType = preg_replace("/[^a-zA-Z]/", "", $cekdata[0]);
// 1. Parsing Pasien
if ($recordType === 'P') {
$rawPatientId = $cekdata[2] ?? ($cekdata[3] ?? '');
$patient_id = trim(str_replace(['\R\\', '\\R\\', '\\'], '', $rawPatientId));
$raw_name = !empty($cekdata[4])
? trim(str_replace('^', ' ', $cekdata[4]))
: (isset($cekdata[5]) ? trim(str_replace('^', ' ', $cekdata[5])) : '');
$patient_name = !empty(trim($raw_name)) ? $raw_name : $patient_id;
}
// 2. Parsing Accession Number
if ($recordType === 'O') {
$accession_number = !empty($cekdata[2]) ? $cekdata[2] : $accession_number;
if (!empty($cekdata[6])) {
$rawTime = preg_replace('/[^0-9]/', '', $cekdata[6]);
if (strlen($rawTime) >= 14) {
$waktu_periksa = date('d-m-Y H:i:s', strtotime(substr($rawTime, 0, 14)));
}
}
}
// 3. Parsing Data Result (Tahan Banting terhadap Pergeseran Index)
if ($recordType === 'R') {
if (isset($cekdata[2]) && isset($cekdata[3])) {
$test_info_raw = $cekdata[2];
$result_val = trim(str_replace('^', '', $cekdata[3]));
if ($result_val !== '') {
// Pecah berdasarkan delimiter ^ dan buang elemen yang kosong
$target_match = array_values(array_filter(explode('^', $test_info_raw), function($val) {
return trim($val) !== '';
}));
$metric_type = 'Result';
$target_parts = $target_match;
$last_part = end($target_parts);
// Jika string test_info mengandung metrik, elemen terakhir adalah metrik,
// dan elemen sebelumnya adalah nama target.
if ($last_part === 'Ct') {
$metric_type = 'Ct';
array_pop($target_parts);
} elseif ($last_part === 'EndPt') {
$metric_type = 'EndPt';
array_pop($target_parts);
} elseif (in_array($last_part, ['Delta Ct', 'LOG'], true)) {
$metric_type = $last_part;
array_pop($target_parts);
}
if (!empty($target_parts) && preg_match('/^\d+$/', (string) end($target_parts))) {
array_pop($target_parts);
}
$target_name = count($target_parts) > 0 ? end($target_parts) : 'Unknown Target';
$target_name = trim($target_name);
if ($target_name !== '') {
if (!isset($parsedResults[$target_name])) {
$parsedResults[$target_name] = [
'Result' => '-',
'Ct' => '-',
'EndPt' => '-'
];
}
$parsedResults[$target_name][$metric_type] = $result_val;
// Hanya simpan Result utama sebagai kesimpulan (abaikan baris Ct/EndPt)
if ($metric_type === 'Result') {
$hasil_list[$target_name] = "{$target_name}: {$result_val}";
}
}
}
}
}
}
if (empty($accession_number)) {
Log::warning("GeneXpert ASTM: Accession number (NoReg) tidak ditemukan.", ['alat' => $alat]);
return false;
}
$kesimpulan_html = implode(" | ", array_values($hasil_list));
$kesimpulan_db = strip_tags($kesimpulan_html);
$kesimpulan_safe = substr($kesimpulan_db, 0, 100);
// ====================================================================
// MEMBUAT HTML REPORT & GRAFIK (CHART.JS)
// ====================================================================
$reporthtml = '';
$reporthtml .= '
Hasil Pemeriksaan GeneXpert
';
$reporthtml .= '
';
$reporthtml .= '
';
$reporthtml .= '';
$reporthtml .= '| No. Reg LIS | ';
$reporthtml .= ': ' . htmlspecialchars($accession_number) . ' | ';
$reporthtml .= 'ID Pasien | ';
$reporthtml .= ': ' . htmlspecialchars($patient_id) . ' | ';
$reporthtml .= '
';
$reporthtml .= '';
$reporthtml .= '| Nama Pasien | ';
$reporthtml .= ': ' . htmlspecialchars($patient_name) . ' | ';
$reporthtml .= 'Waktu Tes | ';
$reporthtml .= ': ' . htmlspecialchars($waktu_periksa) . ' | ';
$reporthtml .= '
';
$reporthtml .= '
';
$reporthtml .= '
';
$reporthtml .= '
Kesimpulan Hasil:
';
$reporthtml .= '
' . $kesimpulan_html . '
';
$reporthtml .= '
';
$reporthtml .= '
Detail Target / Analit
';
$reporthtml .= '
';
$reporthtml .= '
| Target/Analyte |
Result |
Ct Value |
End Point |
';
$chartLabels = [];
$chartCtData = [];
$chartEndPtData = [];
foreach ($parsedResults as $target => $data) {
$reporthtml .= "
| {$target} |
{$data['Result']} |
{$data['Ct']} |
{$data['EndPt']} |
";
if (is_numeric($data['Ct']) || is_numeric($data['EndPt'])) {
$chartLabels[] = $target;
$chartCtData[] = is_numeric($data['Ct']) ? (float)$data['Ct'] : 0;
$chartEndPtData[] = is_numeric($data['EndPt']) ? (float)$data['EndPt'] : 0;
}
}
$reporthtml .= '
';
if (!empty($chartLabels)) {
$chartId = 'gxChart_' . preg_replace('/[^a-zA-Z0-9]/', '', $accession_number);
$labelsJson = json_encode($chartLabels);
$ctJson = json_encode($chartCtData);
$endPtJson = json_encode($chartEndPtData);
$reporthtml .= '
Grafik Amplifikasi
';
$reporthtml .= '
';
$reporthtml .= '';
$reporthtml .= '
';
$reporthtml .= "
";
}
$reporthtml .= '
';
// ====================================================================
// SIMPAN KE DATABASE
// ====================================================================
try {
$this->updatePeriksaStatusByHierarchy($accession_number, 'Data GeneXpert di Terima');
Riwayat::create([
'nofoto' => $accession_number,
'jawaban' => $reporthtml,
'inputor' => $alat,
'keterangan' => date('Y-m-d H:i:s'),
'verifikasi' => '',
]);
$resultSample = ResultSample::firstOrNew(['accession_number' => $accession_number]);
$resultSample->sender_name = $alat;
$resultSample->patient_id = substr($patient_id, 0, 50);
$resultSample->patient_name_first = substr($patient_name, 0, 100);
$resultSample->organism = $kesimpulan_safe;
$resultSample->additional_result = json_encode($parsedResults);
$resultSample->message_datetime = date('Y-m-d H:i:s');
$resultSample->save();
Log::info("GeneXpert Result Disimpan", ["NoReg" => $accession_number, "Hasil" => $kesimpulan_safe]);
return true;
} catch (\Exception $e) {
Log::error("GeneXpert DB Save Error: " . $e->getMessage());
return false;
}
}
public function processAstmResponse($response, $alat) {
// Bersihkan data
$astmData = $this->normalizeAstmRecordLines($this->cleanString($response));
// Validasi awal: response tidak kosong
if (empty($astmData)) {
Log::error("ASTM data kosong atau tidak valid.");
}
if (stripos($astmData, 'GeneXpert') !== false) {
return $this->processAstmMessagesgenExpert($astmData, $alat);
}
$jsonantibiotik = array(
'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',
'Tigecycline-TGC',
'Trimethoprim/Sulfamethoxazole-SXT',
'Fosfomycin-FOS',
'Vancomycin-VAN',
'Linezolid-LNZ',
'Fluconazole',
'Voriconazole',
'Caspofungin',
'Micafungin',
'Amphotericin B',
'Flucytosine'
);
$headerData = [];
$patientData = [];
$orderData = [];
$resultData = [];
$instrumenDT = [];
$mltrData = [];
$isolate = null;
$accession_number = null;
$segments = explode("\n", $astmData);
foreach ($segments as $rsegmen){
$cekdata = explode('|', $rsegmen);
$datapertama = $cekdata[0];
$cleankode = preg_replace("/[^a-zA-Z]/", "", $datapertama);
if ($cleankode == 'H'){
$headerData = array_merge([$cleankode], array_slice($cekdata, 1));
}
if ($cleankode == 'P'){
$patientData = array_merge([$cleankode], array_slice($cekdata, 1));
}
if ($cleankode == 'O'){
$orderData = array_merge([$cleankode], array_slice($cekdata, 1));
}
if ($cleankode == 'R'){
$resultData = array_merge([$cleankode], array_slice($cekdata, 1));
}
if ($cleankode == 'I'){
$instrumenDT = array_merge([$cleankode], array_slice($cekdata, 1));
}
if ($cleankode == 'mtrsl'){
$mltrData = array_merge([$cleankode], array_slice($cekdata, 1));
}
}
if (!empty($patientData) && !empty($headerData)) {
$resultSample = new ResultSample();
$noregister = $patientData[4] ?? null;
$resultSample->sender_name = $alat;
$resultSample->version_number = $headerData[11] ?? $patientData[12] ?? null;
$resultSample->message_datetime = $resultData[13] ?? null; // '20241130152734'
// Patient Record (Segment P)
$resultSample->patient_id = $patientData[4] ?? null; // '11607396'
$resultSample->patient_name_last = $patientData[6] ?? null; // 'ZAKIYATUN'
$resultSample->patient_name_first = $patientData[7] ?? null; // 'O'
$resultSample->patient_name_middle = $patientData[8] ?? null;
$resultSample->patient_name_suffix = $patientData[9] ?? null;
$resultSample->patient_name_title = $patientData[10] ?? null;
$resultSample->patient_dob = $resultData[11] ?? null; // '19800101'
$resultSample->patient_sex = $patientData[12] ?? null; // 'F'
$resultSample->address_street = $patientData[13] ?? null; // 'Street ABC'
$resultSample->address_city = $patientData[14] ?? null;
$resultSample->address_state = $patientData[15] ?? null;
$resultSample->address_zip = $patientData[16] ?? null;
$resultSample->address_country = $patientData[17] ?? null;
$resultSample->patient_phone = $patientData[18] ?? null; // '081234567890'
// Order Record (Segment O)
$resultSample->accession_number = $orderData[4] ?? null; // '12345'
$resultSample->isolate_number = $orderData[5] ?? null; // '67890'
$resultSample->organism = $orderData[6] ?? null; // 'E. coli'
$resultSample->exclude_isolate_from_statistics = $isolate; // 'false'
$resultSample->test_id = $orderData[8] ?? null; // 'Test123'
// Result Record (Segment R)
$resultSample->result_type_code = $resultData[4] ?? null; // 'S'
$resultSample->antibiotic = $resultData[5] ?? null; // 'Amoxicillin'
$resultSample->antibiotic_concentration = $resultData[6] ?? null; // '100mg'
$resultSample->antibiotic_concentration_units = $resultData[7] ?? null; // 'mg'
$resultSample->test_status = $resultData[8] ?? null; // 'Completed'
$resultSample->result_data = json_encode(array_slice($resultData, 9)); // Additional data (if any)
$resultSample->preliminary_final_status = $resultData[13] ?? null;
$resultSample->test_start_datetime = $resultData[14] ?? null;
$resultSample->result_status_datetime = $resultData[15] ?? null;
$resultSample->test_complete_datetime = $resultData[16] ?? null;
// Periksa apakah data duplikat berdasarkan accession_number
//if (ResultSample::where('accession_number', $resultSample->accession_number)->exists()) {
// return response()->json(['message' => 'Data sudah ada.'], 409);
//}
// Simpan ke database
if ($noregister){
$this->updatePeriksaStatusByHierarchy($accession_number, 'Data Vitek di Terima');
//Log::info("Data berhasil disimpan:", $resultSample->toArray());
$resultSample->save();
}
return response()->json(['message' => 'Data berhasil diproses dan disimpan.']);
} else {
if (!empty($mltrData)){
$mulaikirim = 0;
$tanggalmasuk = '';
$tanggalkeluar = '';
$organism = '';
$parsedData = [
'patient_info' => [],
'antibiotics' => []
];
$resultSample = new ResultSample();
for ($i = 0; $i < count($mltrData); $i++) {
$field = $mltrData[$i];
$kodeduadigit = substr($field, 0, 2);
if ($field == 'ra') {
$current_antibiotic = [];
for ($j = 1; $j <= 5; $j++) {
if (isset($mltrData[$i + $j])) {
$subField = $mltrData[$i + $j];
$code = substr($subField, 0, 2);
$value = substr($subField, 2);
switch ($code) {
case 'a1':
$current_antibiotic['instrument_code'] = $value; // Kode dari alat
break;
case 'a2':
$current_antibiotic['antibiotic_name'] = $value; // Nama antibiotik
break;
case 'a3':
$current_antibiotic['value'] = $value; // Nilai MIC
break;
case 'a4':
$current_antibiotic['interpretation'] = $value; // S, I, atau R
break;
case 'an':
$current_antibiotic['resistance_note'] = $value; // Catatan resistansi
break;
}
}
}
$antibioticName = $current_antibiotic['antibiotic_name'] ?? null;
if ($antibioticName && isset($kodevitek[$antibioticName])) {
$current_antibiotic['lis_code'] = $kodevitek[$antibioticName];
} else {
$current_antibiotic['lis_code'] = $current_antibiotic['instrument_code'] ?? 'NOT_FOUND';
}
$parsedData['antibiotics'][] = $current_antibiotic;
$i += 5;
} else {
if ($kodeduadigit == 'mt'){
$resultSample->sender_name = substr($field, 2);
}
if ($kodeduadigit == 'ii'){
$resultSample->version_number = substr($field, 2);
}
if ($kodeduadigit == 'rr'){
$resultSample->isolate_number = substr($field, 2);
}
if ($kodeduadigit == 'ci'){
$accession_number = substr($field, 2);
$resultSample->accession_number = $accession_number;
}
if ($kodeduadigit == 'pi'){
$resultSample->patient_id = substr($field, 2);
}
if ($kodeduadigit == 'pn'){
$patientNames = substr($field, 2);
$patientNames = explode(',', $patientNames ?? null);
if (count($patientNames) > 0) {
$resultSample->patient_name_first = trim($patientNames[0]);
}
if (count($patientNames) > 1) {
$resultSample->patient_name_last = trim($patientNames[1]);
}
if (count($patientNames) > 2) {
$resultSample->patient_name_middle = trim($patientNames[2]);
}
}
if ($kodeduadigit == 'pl'){
$resultSample->hospital_service = substr($field, 2);
}
if ($kodeduadigit == 'p2'){
$resultSample->hospital_client = substr($field, 2);
}
if ($kodeduadigit == 'ss'){
$resultSample->specimen_type = substr($field, 2);
}
if ($kodeduadigit == 'o2'){
$organism = substr($field, 2);
$resultSample->organism = $organism;
}
if ($kodeduadigit == 's1'){
$tanggalmasuk = substr($field, 2);
}
if ($kodeduadigit == 's2'){
$tanggalmasuk = $tanggalmasuk.' '.substr($field, 2);
}
if ($kodeduadigit == 's3'){
$tanggalkeluar = substr($field, 2);
}
if ($kodeduadigit == 's4'){
$tanggalkeluar = $tanggalkeluar.' '.substr($field, 2);
}
}
}
$resultSample->additional_result = json_encode($parsedData['antibiotics']);
if ($tanggalmasuk != ''){
try {
$resultSample->message_datetime = Carbon::parse($tanggalmasuk)->format('Y-m-d H:i:s') ?? null;
}catch (Exception $e) {
$resultSample->message_datetime = date('Y-m-d H:i:s');
}
}
if ($tanggalkeluar != ''){
try {
$resultSample->test_complete_datetime = Carbon::parse($tanggalkeluar)->format('Y-m-d H:i:s') ?? null;
}catch (Exception $e) {
$resultSample->test_complete_datetime = date('Y-m-d H:i:s');
}
}
$resultSample->save();
if ($accession_number){
$accession_number = substr($accession_number, 0, 9);
if ($organism !== ''){
$sudah = Organisms::where('name', $organism)->count();
if ($sudah == 0){
Organisms::create([
'kelompok' => 'biakankultur',
'name' => $organism,
'category' => 'Vitek',
]);
}
KomponenJawaban::updateOrCreate(
[
'accnumber' => $accession_number,
'komponen' => 'bakteri',
'isidata' => $organism,
],
[
'template' => 'all',
'created_by' => 'Vitek'
]
);
}
$cekdataperiksa = Periksa::where('nofoto', $accession_number)->first();
if (isset($cekdataperiksa->id)){
if (is_array($parsedData['antibiotics'])) {
foreach ($parsedData['antibiotics'] as $item) {
$glassreportname = in_array($item['antibiotic_name'], $jsonantibiotik);
RekapAntibiotik::updateOrCreate(
[
'kuman' => $organism,
'orderid' => $cekdataperiksa->id,
'antibiotic' => $item['antibiotic_name'],
],
[
'resistance' => $item['resistance_note'] ?? null,
'value' => $item['value'] ?? null,
'interpretation' => $item['interpretation'] ?? null,
'glassreportname' => $glassreportname,
'printrow' => true,
'printcol' => false,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
]
);
}
}
}
$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.']);
} else {
$headerData = explode("|", $astmData);
if (isset($headerData[3])){
$accnumber = $headerData[47] ?? null;
$noregister = $headerData[16] ?? null;
if (empty($accnumber)) {
Log::warning('ASTM BD message skipped because accession number is missing.', [
'header' => $headerData,
]);
return false;
}
$resultSample = ResultSample::firstOrNew([
'accession_number' => $accnumber,
]);
$nama = $headerData[18] ?? null;
$urgensi = $headerData[50] ?? null; //A Critical R Normal
$iddokter = $headerData[33] ?? null;
$test_start_datetime = $headerData[52] ?? null;
$result_status_datetime = $headerData[59] ?? null;
$specimen_type = $headerData[60] ?? null;
$resulttype = $headerData[34] ?? null;
$resultstatus = $headerData[63] ?? null;
$preliminary = $headerData[40] ?? null; //P
$test_complete_datetime = $headerData[44] ?? null;
$tesid = $headerData[62] ?? null;
$alamat = $headerData[23] ?? null;
$instrumen = $resultData[2] ?? null;
$body_site = '';
$tengah = '';
$depan = '';
$akhir = '';
$suffix = '';
$title = '';
$concentration_unit = '';
$kode = '';
$antibiotic = '';
$city = '';
$state = '';
$zipcode = '';
$country = '';
if ($resulttype){
$getdataresult = explode('^', $resulttype);
$kode = $getdataresult[3] ?? '';
$concentration_unit = $getdataresult[4] ?? '';
}
if ($specimen_type){
$getdata = explode('\n', $specimen_type);
$specimen_type = $getdata[0];
$body_site = $getdata[1] ?? '';
}
if ($tesid){
$gettgl = explode('^', $tesid);
$tesid = $gettgl[3] ?? null;
}
if ($instrumen){
$gettgl = explode('^', $instrumen);
$instrumen = $gettgl[0];
$media_assay_type = $gettgl[1] ?? null;
$protocol_length = $gettgl[2] ?? null;
$instrument_number = $gettgl[3] ?? null;
$instrument_location = $gettgl[4] ?? null;
$protocol_name = $gettgl[5] ?? null;
} else {
$media_assay_type = null;
$protocol_length = null;
$instrument_number = null;
$instrument_location = null;
$protocol_name = null;
}
if ($isolate == '' OR $isolate == '0' OR is_null($isolate)){
$isolate = false;
} else { $isolate = true; }
if ($test_complete_datetime){
$test_complete_datetime = substr($test_complete_datetime, 0, 14);
//$test_complete_datetime = Carbon::parse($test_complete_datetime)->format('Y-m-d H:i:s');
}
if ($result_status_datetime){
$result_status_datetime = substr($result_status_datetime, 0, 14);
//$result_status_datetime = Carbon::parse($result_status_datetime)->format('Y-m-d H:i:s');
}
if ($test_start_datetime){
$test_start_datetime = substr($test_start_datetime, 0, 14);
//$test_start_datetime = Carbon::parse($test_start_datetime)->format('Y-m-d H:i:s');
}
if ($nama){
$getnama = explode('\015', $nama);
$nama = $getnama[0];
$getnama = explode('\n', $nama);
$nama = $getnama[0];
$akhir = $getnama[1] ?? '';
$depan = $getnama[2] ?? '';
$tengah = $getnama[3] ?? '';
$suffix = $getnama[4] ?? '';
$title = $getnama[5] ?? '';
$nama = $nama.$akhir;
}
if ($alamat){
$getnama = explode('^', $alamat);
$alamat = $getnama[0];
$city = $getnama[1] ?? '';
$state = $getnama[2] ?? '';
$zipcode = $getnama[3] ?? '';
$country = $getnama[4] ?? '';
}
if ($test_start_datetime == ''){ $test_start_datetime = null; }
if ($result_status_datetime == ''){ $result_status_datetime = null; }
if ($test_complete_datetime == ''){ $test_complete_datetime = null; }
$resultSample->sender_name = $headerData[4] ?? 'Unkown';
$resultSample->version_number = $headerData[12] ?? 'V0.0';
$resultSample->message_datetime = $test_start_datetime;
// Patient Record (Segment P)
$resultSample->patient_id = $noregister; // '11607396'
$resultSample->patient_name_last = $nama; // 'ZAKIYATUN'
$resultSample->patient_name_first = $depan; // 'O'
$resultSample->patient_name_middle = $tengah;
$resultSample->patient_name_suffix = $suffix;
$resultSample->patient_name_title = $title;
$resultSample->patient_dob = $headerData[20] ?? null;
$resultSample->patient_sex = $headerData[21] ?? null;
$resultSample->address_street = $alamat;
$resultSample->address_city = $city;
$resultSample->address_state = $state;
$resultSample->address_zip = $zipcode;
$resultSample->address_country = $country;
$resultSample->patient_phone = $headerData[25] ?? null;
$resultSample->admitting_physician = $headerData[27] ?? null;
$resultSample->patient_diagnosis = $headerData[33] ?? null;
$resultSample->patient_therapy = json_encode($headerData);
$resultSample->admit_datetime = null;
$resultSample->room_number = $headerData[46] ?? '00001';
$resultSample->hospital_service = $headerData[45] ?? 'RSSA Malang';
$resultSample->hospital_client = $orderData[4] ?? 'Lab Mikro';
// Order Record (Segment O)
$resultSample->accession_number = $accnumber; // '12345'
$resultSample->isolate_number = $orderData[5] ?? null; // '67890'
$resultSample->organism = $orderData[6] ?? null; // 'E. coli'
$resultSample->exclude_isolate_from_statistics = $isolate; // 'false'
$resultSample->specimen_type = $specimen_type;
$resultSample->body_site = $body_site;
$resultSample->test_id = $tesid; // 'Test123'
$resultSample->urgensi = $urgensi; //A Critical R Normal
// Result Record (Segment R)
$resultSample->result_type_code = $kode;
$resultSample->antibiotic = $antibiotic;
$resultSample->antibiotic_concentration = $concentration_unit; // '100mg'
$resultSample->antibiotic_concentration_units = $concentration_unit; // 'mg'
$resultSample->test_status = $resultstatus; // 'Completed'
$resultSample->result_data = json_encode($orderData); // Additional data (if any)
$resultSample->preliminary_final_status = $preliminary;
$resultSample->test_start_datetime = $test_start_datetime;
$resultSample->result_status_datetime = $result_status_datetime;
$resultSample->test_complete_datetime = $test_complete_datetime;
$resultSample->instrument_type = $instrumen;
$resultSample->media_assay_type = $media_assay_type;
$resultSample->protocol_length = $protocol_length;
$resultSample->instrument_number = $instrument_number;
$resultSample->instrument_location = $instrument_location;
$resultSample->protocol_name = $protocol_name;
$resultSample->additional_result = json_encode($resultData);
if ($noregister){
$resultSample->save();
$this->updatePeriksaStatusByHierarchy($accnumber, 'Data BD di Terima ('.$orderData[6] ?? ''.')');
return response()->json(['message' => 'Data berhasil diproses dan disimpan.']);
}
} else {
Log::debug("Abaikan Data Berikut ". json_encode($headerData));
}
}
}
}
public function processAstmMessagesLokal($dataListener) {
foreach ($dataListener as $data) {
try {
$response = $data->rawdt;
if ($data->alat == 'MGIT' OR $data->alat == 'COM5' OR $data->alat == 'BACTEC'){
$assembled = $this->reassembleAstmFrames($data->rawdt);
$messages = $this->splitBDAstmMessages($assembled);
foreach ($messages as $msg) {
$ok = $this->processBDAstmResponse($msg, $data);
}
DB::table('lis_phoenix')->where('id', $data->id)->update([
'processed' => $ok ? 1 : 9
]);
$this->updatePeriksaStatusByHierarchy($data->no_id, 'Data BD di Terima ('.$data->organisme.')');
KomponenJawaban::updateOrCreate(
[
'accnumber' => $data->no_id,
'komponen' => 'bd_result',
'isidata' => $data->organisme,
],
[
'template' => 'Kultur',
'created_by' => 'BD'
]
);
} else if ( $data->alat == 'GeneXpert-10.10.120.75' OR $data->alat == 'GeneXpert-10.10.120.74' OR $data->alat == 'GeneXpert-10.10.120.73' OR $data->alat == 'GeneXpert-10.10.120.13' OR $data->alat == '10.10.120.75' OR $data->alat == '10.10.120.74' OR $data->alat == '10.10.120.73' OR $data->alat == '10.10.120.13') {
$result = $this->processAstmMessagesgenExpert($data->rawdt, $data->alat);
if ($result) {
DB::table('lis_phoenix')->where('id', $data->id)->update([
'processed' => 1
]);
} else {
Log::debug($result);
}
} else if ( $data->alat == 'MYLA-10.10.120.89' ){
$messages = $this->splitHl7LikeMessages($data->rawdt);
$ok = false;
if (empty($messages)) {
$ok = $this->saveInstrumentRawResult($data->rawdt, $data->alat);
} else {
foreach ($messages as $message) {
$saved = $this->saveInstrumentRawResult($message, $data->alat);
$ok = $ok || $saved;
}
}
DB::table('lis_phoenix')->where('id', $data->id)->update([
'processed' => $ok ? 1 : 9
]);
} else {
$result = $this->processAstmResponse($data->rawdt, $data->alat);
if ($result) {
DB::table('lis_phoenix')->where('id', $data->id)->update([
'processed' => 1
]);
} else {
Log::debug($result);
}
}
} catch (\Exception $e) {
Log::critical($e->getMessage());
}
}
}
/**
* Proses data ASTM Response
*/
public function processAstmMessages($dataListener) {
foreach ($dataListener as $data) {
try {
// Ambil pesan ASTM dari kolom 'message' atau yang relevan
$response = $data->rawdt;
if ($data->alat == 'BD Mikro 1'){
if ($data->no_id != ''){
$assembled = $this->reassembleAstmFrames($data->rawdt);
$messages = $this->splitBDAstmMessages($assembled);
foreach ($messages as $msg) {
$ok = $this->processBDAstmResponse($msg, $data);
}
DataListiner::where('urut', $data->urut)->update([
'processed' => $ok ? 1 : 9
]);
$this->updatePeriksaStatusByHierarchy($data->no_id, 'Data BD di Terima ('.$data->organisme.')');
KomponenJawaban::updateOrCreate(
[
'accnumber' => $data->no_id,
'komponen' => 'bd_result',
'isidata' => $data->organisme,
],
[
'template' => 'Kultur',
'created_by' => 'BD'
]
);
} else {
DataListiner::where('urut', $data->urut)->update([
'processed' => 9
]);
}
} else {
// Lakukan parsing menggunakan method/fungsi yang sudah dibuat
$result = $this->processAstmResponse($response, $data->alat);
// Jika berhasil, tandai data sudah diproses
if ($result) {
DataListiner::where('urut', $data->urut)->update([
'processed' => 1
]);
} else {
Log::debug($result);
}
}
} catch (\Exception $e) {
Log::critical($e->getMessage());
}
}
}
}