Files
lis/htdocs/app/Services/AstmMessageService.php
T
2026-05-17 04:11:19 +07:00

1440 lines
66 KiB
PHP

<?php
namespace App\Services;
use Carbon\Carbon;
use App\ResultSample;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use Exception;
use App\DataListiner;
use App\Periksa;
use App\RekapAntibiotik;
use App\PendaftaranOnListiner;
use App\Organisms;
use App\KomponenJawaban;
use App\Riwayat;
// Proses untuk Growth and Detection Result
function processGrowthDetectionResult($rawData){
// Format: R|1| ^ ^ ^GND_MGIT^430100001234|INST_POSITIVE ^87| ...
$resultData = explode('|', $rawData);
return [
'test_type' => '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);
}
/**
* 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 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'
]
);
}
//Log::info("Data BD ASTM Berhasil di Parse dan di simpan ", $resultSample->toArray());
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
'<div class="instrument-result instrument-result-myla">'.
'<div><strong>HASIL ALAT MYLA</strong></div>'.
'<table>'.
'<tr><td>No. Foto</td><td>: '.$escape($accessionNumber).'</td></tr>'.
'<tr><td>No. Spesimen</td><td>: '.$escape($specimen).'</td></tr>'.
'<tr><td>Pasien</td><td>: '.$escape($patientName).'</td></tr>'.
'<tr><td>Jenis Pesan</td><td>: '.$escape($messageType).'</td></tr>'.
'<tr><td>Test</td><td>: '.$escape($testId).'</td></tr>'.
'<tr><td>Hasil</td><td>: '.$escape($organism).'</td></tr>'.
'<tr><td>Abnormal Flag</td><td>: '.$escape($abnormalFlag).'</td></tr>'.
'<tr><td>Confidence</td><td>: '.$escape($confidence).'</td></tr>'.
'<tr><td>Status</td><td>: '.$escape($status).'</td></tr>'.
'<tr><td>Operator</td><td>: '.$escape($operator).'</td></tr>'.
'<tr><td>Komentar</td><td>: '.$escape($comment).'</td></tr>'.
'<tr><td>Tanggal Hasil</td><td>: '.$escape($resultAt).'</td></tr>'.
'<tr><td>Tanggal Diterima LIS</td><td>: '.$escape($receivedAt).'</td></tr>'.
'</table>'.
'</div>';
}
$orderAt = $this->astmToDateTime($parsed['ORC'][0][8] ?? null) ?? '-';
$queryId = $qid[1] ?? ($msh[9] ?? '-');
return
'<div class="instrument-result instrument-result-genexpert">'.
'<div><strong>HASIL ALAT GENEXPERT</strong></div>'.
'<table>'.
'<tr><td>No. Foto</td><td>: '.$escape($accessionNumber).'</td></tr>'.
'<tr><td>Pasien</td><td>: '.$escape($patientName).'</td></tr>'.
'<tr><td>Jenis Pesan</td><td>: '.$escape($messageType).'</td></tr>'.
'<tr><td>Test/Assay</td><td>: '.$escape($testId).'</td></tr>'.
'<tr><td>Order/Run ID</td><td>: '.$escape($queryId).'</td></tr>'.
'<tr><td>Tanggal Order</td><td>: '.$escape($orderAt).'</td></tr>'.
'<tr><td>Tanggal Diterima LIS</td><td>: '.$escape($receivedAt).'</td></tr>'.
'<tr><td>Catatan</td><td>: Payload alat disimpan sebagai raw untuk ditinjau analis.</td></tr>'.
'</table>'.
'</div>';
}
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';
}
Periksa::where('nofoto', $accessionNumber)->whereNotIn('status', ['Selesai', 'Arsip', 'Dibatalkan (Arsip)', 'Batal'])->update([
'status' => $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 = 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
foreach ($segments as $rsegmen) {
$cekdata = explode('|', $rsegmen);
if (empty($cekdata[0])) continue;
$recordType = preg_replace("/[^a-zA-Z]/", "", $cekdata[0]);
if ($recordType === 'P') {
$patient_id = $cekdata[3] ?? ($cekdata[4] ?? '');
if (isset($cekdata[5])) {
$patient_name = trim(str_replace('^', ' ', $cekdata[5]));
}
}
if ($recordType === 'O') {
$accession_number = $cekdata[2] ?? '';
}
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 test info berdasarkan '^'
$test_info = explode('^', $test_info_raw);
// 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' => '-'
];
}
// 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;
}
}
}
}
}
if (empty($accession_number)) {
Log::warning("GeneXpert ASTM: Accession number (NoReg) tidak ditemukan.", ['alat' => $alat]);
return false;
}
// ====================================================================
// MEMBUAT HTML REPORT & GRAFIK (CHART.JS)
// ====================================================================
// 1. Buat Tabel HTML
$reporthtml = '<div class="genexpert-report" style="font-family: Arial, sans-serif;">';
$reporthtml .= '<h4 style="margin-bottom:10px;">GeneXpert Assay Result</h4>';
$reporthtml .= '<table border="1" cellpadding="5" style="width: 100%; border-collapse: collapse; text-align: left; margin-bottom: 20px;">';
$reporthtml .= '<tr style="background-color: #f4f4f4;">
<th>Target/Analyte</th>
<th>Result</th>
<th>Ct Value</th>
<th>EndPt</th>
</tr>';
$chartLabels = [];
$chartCtData = [];
$chartEndPtData = [];
foreach ($parsedResults as $target => $data) {
$reporthtml .= "<tr>
<td><strong>{$target}</strong></td>
<td>{$data['Result']}</td>
<td>{$data['Ct']}</td>
<td>{$data['EndPt']}</td>
</tr>";
// Siapkan data untuk grafik (hanya ambil target yang memiliki nilai numerik Ct/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 .= '</table>';
// 2. Buat Grafik menggunakan Chart.js (Inject Script)
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);
// Tambahkan Canvas untuk grafik
$reporthtml .= '<div style="width: 100%; max-width: 800px; margin: auto;">';
$reporthtml .= '<canvas id="'.$chartId.'"></canvas>';
$reporthtml .= '</div>';
// Tambahkan script Chart.js (asumsi CDN) dan inisialisasi
$reporthtml .= "
<script src=\"https://cdn.jsdelivr.net/npm/chart.js\"></script>
<script>
// Gunakan DOMContentLoaded agar script jalan setelah HTML di-render di frontend
document.addEventListener('DOMContentLoaded', function() {
var ctx = document.getElementById('{$chartId}').getContext('2d');
new Chart(ctx, {
type: 'bar', // Menggunakan kombinasi Bar & Line chart
data: {
labels: {$labelsJson},
datasets: [
{
label: 'Ct Value',
data: {$ctJson},
backgroundColor: 'rgba(54, 162, 235, 0.6)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1,
yAxisID: 'y'
},
{
label: 'End Point',
data: {$endPtJson},
type: 'line',
borderColor: 'rgba(255, 99, 132, 1)',
backgroundColor: 'rgba(255, 99, 132, 0.2)',
borderWidth: 2,
yAxisID: 'y1'
}
]
},
options: {
responsive: true,
scales: {
y: {
type: 'linear',
display: true,
position: 'left',
title: { display: true, text: 'Ct Value' }
},
y1: {
type: 'linear',
display: true,
position: 'right',
title: { display: true, text: 'EndPt' },
grid: { drawOnChartArea: false } // Agar garis grid tidak bertumpuk
}
}
}
});
});
</script>
";
}
$reporthtml .= '</div>';
// ====================================================================
// SIMPAN KE DATABASE
// ====================================================================
$kesimpulan = implode(" | ", $hasil_list);
$kesimpulan_safe = substr($kesimpulan, 0, 100);
try {
Periksa::where('nofoto', $accession_number)
->whereNotIn('status', ['Selesai', 'Arsip', 'Dibatalkan (Arsip)', 'Batal'])
->update([
'status' => '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; // Tetap menyimpan text summary
$resultSample->additional_result = json_encode($parsedResults); // Menyimpan JSON utuh agar lebih informatif
$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->cleanString($response);
// Validasi awal: response tidak kosong
if (empty($astmData)) {
Log::error("ASTM data kosong atau tidak valid.");
}
$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){
Periksa::where('nofoto', $accession_number)->update([
'status' => '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'),
]
);
}
}
}
Periksa::where('nofoto', $accession_number)->whereNotIn('status', ['Selesai', 'Arsip', 'Dibatalkan (Arsip)', 'Batal'])->update([
'status' => '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();
//Log::info("Data ASTM Berhasil di Parse dan di simpan ", $resultSample->toArray());
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
]);
Periksa::where('nofoto', $data->no_id)->whereNotIn('status', ['Selesai', 'Arsip', 'Dibatalkan (Arsip)', 'Batal'])->update([
'status' => '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
]);
Periksa::where('nofoto', $data->no_id)->whereNotIn('status', ['Selesai', 'Arsip', 'Dibatalkan (Arsip)', 'Batal'])->update([
'status' => '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());
}
}
}
}