Compare commits

...
23 Commits
Author SHA1 Message Date
servdal 4b915caad7 update 2025-08-27 15:33:56 +07:00
servdal ab494fddf8 update 2025-08-27 15:33:53 +07:00
servdal fef0acb867 Update 2025-08-27 15:29:56 +07:00
servdal c7ecb66ba1 Update Rating Fitur 2025-08-24 20:50:04 +07:00
servdal 2af18f0f68 Update Metode Pengiriman 2025-08-24 16:53:12 +07:00
servdal 0cecf8760c Update send order ke Python MiniPCs 2025-08-23 19:59:36 +07:00
servdal 094ceb0b9f Update open cancel button dan tambah buttun ulang 2025-08-12 17:32:54 +07:00
servdal 92e7cad787 Update pembacaan API 2025-08-07 16:40:10 +07:00
servdal d9e70fc1e9 Stop tracking .env file 2025-08-06 17:30:11 +07:00
servdal d77047db52 Stop tracking .env file 2025-08-06 17:29:26 +07:00
servdal 2d4c608bc9 Update Git Ignore 2025-08-06 17:27:29 +07:00
servdal 77ae72b154 Update Git Ignore 2025-08-06 17:13:41 +07:00
servdal 0c47dc4166 Update Penamaan Variable 2025-08-05 10:16:40 +07:00
servdal 62c2e6bf8e Update ke Laravel 12 struktur modular 2025-08-03 18:09:58 +07:00
servdal 79da34a3e3 Update Port 2025-07-31 11:36:52 +07:00
servdal 0f7bdcefc5 Edit Gitingore 2025-07-17 08:54:38 +07:00
servdal 132d0a0d5f remove force to ssl 2025-07-17 08:32:59 +07:00
servdal 1bbf9c00f1 disable ssl 2025-07-17 08:30:55 +07:00
servdal 9437483030 Update bug waiting laravel 2025-07-17 08:13:00 +07:00
servdal 8289968849 Update Compiler 2025-07-17 07:41:21 +07:00
servdal cd3f9f1628 Update gitignore 2025-07-17 06:32:11 +07:00
servdal 3237dbf10c Update Dockerfile 2025-07-17 06:31:35 +07:00
servdal cedb72d57f Update Add Python 2025-07-16 18:21:10 +07:00
31 changed files with 1355 additions and 468 deletions
-4
View File
@@ -1,4 +0,0 @@
AUTHENTIK_ERROR_REPORTING__ENABLED=true
PG_PASS=guR8uchQhQFAGi4yXfHPrF2AHTgN15sOViDL7tu0bfoiPmdI
AUTHENTIK_SECRET_KEY=HeBg31UJE0AEK2JNWpXx1+6v7SjlYr9HKxDZi66dNsrhy+9XpOz9LOw81bWNHDo/lFiORMxVa1f+
q1Yt
+4
View File
@@ -3,8 +3,12 @@
mergekemain.sh
# Ignore Laravel cache, logs, and storage
/htdocs/storage/*
/database
!/htdocs/storage/.gitignore
/htdocs/.env
# Ignore bootstrap cache
/htdocs/bootstrap/cache/*
/htdocs/listenerlis/listener.log
/htdocs/listenerlis/tcp_raw_data.bin
.env
!/htdocs/bootstrap/cache/.gitignore
+19 -3
View File
@@ -15,7 +15,7 @@ services:
retries: 5
timeout: 5s
volumes:
- ./authentik/database:/var/lib/postgresql/data
- ./database:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${PG_PASS:?database password required}
POSTGRES_USER: ${PG_USER:-authentik}
@@ -36,11 +36,27 @@ services:
ports:
- "8088:8080"
depends_on:
- laravel-db
postgresql:
condition: service_healthy
command: php artisan serve --host=0.0.0.0 --port=8080
networks:
- proxy
python-listener:
build:
context: ./htdocs/listenerlis
dockerfile: Dockerfile
container_name: python-listener
restart: unless-stopped
volumes:
- ./htdocs/listenerlis:/app
ports:
- "5000:5000"
- "6001:6001"
depends_on:
postgresql:
condition: service_healthy
networks:
- proxy
networks:
proxy:
external: true
+8 -2
View File
@@ -23,6 +23,7 @@ RUN apt-get update && apt-get install -y \
libtool \
libsqlite3-dev \
mariadb-client \
libpq-dev \
&& docker-php-ext-configure imap --with-kerberos --with-imap-ssl \
&& docker-php-ext-install \
dom \
@@ -38,6 +39,8 @@ RUN apt-get update && apt-get install -y \
pcntl \
pdo_mysql \
pdo_sqlite \
pdo_pgsql \
pgsql \
posix \
shmop \
simplexml \
@@ -60,7 +63,10 @@ WORKDIR /var/www/html
# RUN composer create-project laravel/laravel:^10 /var/www/html
# Set permission
RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache
#RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache
EXPOSE 9000
CMD ["php-fpm"]
#CMD ["php-fpm"]
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
@@ -22,7 +22,7 @@ class ProcessAstmMessages extends Command
public function handle()
{
// Ambil data dari DataListener
$dataListener = DataListiner::whereNull('processed')->get();
$dataListener = DataListiner::where('processed', '0')->orderBy('created_at', 'DESC')->get();
if ($dataListener) {
$jumlah = count($dataListener);
$pesan = $this->astmMessageService->processAstmMessages($dataListener);
@@ -51,6 +51,11 @@ define( 'API_ACCESS_KEY', 'AAAA6YBXh1k:APA91bFL0q7QAXQGohXMpTwHco79f13C8PFk1Oo8k
class DokterController extends Controller
{
protected $lisServiceUrl;
public function __construct()
{
$this->lisServiceUrl = env('LIS_SERVICE_URL', 'http://localhost:5000');
}
protected static function genSurat($id, $tabel){
if ($tabel == 'dengan kop'){
$kopsurat = url('/templateimage/kopsurat.png');
@@ -1075,6 +1080,7 @@ class DokterController extends Controller
]);
}
}
$jsondata = json_decode($jsondata, true);
if(is_array($jsondata) && count($jsondata) > 0){
foreach ($jsondata as $item){
RekapAntibiotik::updateOrCreate(
@@ -1097,9 +1103,9 @@ class DokterController extends Controller
$gentabel = RekapAntibiotik::where('orderid', $orderid)->get();
if (!empty($gentabel)){
$nomor = 1;
$isidata = '<table border="1" cellpadding="0" cellspacing="0" width="100%"><tr><td width="5%"><strong>No</strong></td><td width="65%"><strong>Antibiotik</strong></td><td width="15%"><strong>Value</strong></td><td width="15%"><strong>S/I/R</strong></td></tr>';
$isidata = $isidata.'<br /><table border="1" cellpadding="0" cellspacing="0" width="100%"><tr><td width="5%"><strong>No</strong></td><td width="65%"><strong>Antibiotik</strong></td><td width="15%"><strong>Value</strong></td><td width="15%"><strong>S/I/R</strong></td></tr>';
foreach($gentabel as $rtabel){
$isidata = $isidata.'<tr><td>'.$nomor.'</td><td>'.$rtabel->antibiotic.'</td<td>'.$rtabel->value.'</td><td>'.$rtabel->interpretation.'</td></tr>';
$isidata = $isidata.'<tr><td>'.$nomor.'</td><td>'.$rtabel->resistance.'</td><td>'.$rtabel->value.'</td><td>'.$rtabel->interpretation.'</td></tr>';
$nomor++;
}
$isidata = $isidata.'</table>';
@@ -1127,7 +1133,7 @@ class DokterController extends Controller
}
return response()->json(['pesan' => $pesan, 'organism' => $organism]);
return back();
} else if ($worklist == 'getbbachtect' OR $worklist == 'getmgit' OR $worklist == 'getgenexpert' OR $worklist == 'getabbot'){
} else if ($worklist == 'getbbachtect' OR $worklist == 'getmgit' OR $worklist == 'getabbot'){
$isidata = $request->input('isi');
try {
$ketemu = '';
@@ -1166,6 +1172,67 @@ class DokterController extends Controller
$pesan = $isidata.'<br />'.$e->getMessage();
}
return $pesan;
} else if ($worklist == 'getgenexpert'){
$isidata = $request->input('isi');
try {
$ketemu = '';
$cekada = ResultSample::where('accession_number', 'LIKE', $nofoto.'%')->get();
if ($cekada->isNotEmpty()){
foreach($cekada as $rows){
$ketemu .= ($ketemu ? '<br />' : '') . $rows->test_status;
}
} else {
$payload = [
'command' => 'request_result',
'data' => [
'sample_id' => $nofoto
],
];
$response = Http::timeout(30)->post($this->lisServiceUrl . '/command', $payload);
if ($response->successful()) {
Log::info('Permintaan hasil berhasil dikirim ke LIS service.', [
'sample_id' => $nofoto,
'response' => $response->json()
]);
} else {
Log::error('Gagal terhubung ke LIS service saat meminta hasil.', [
'sample_id' => $nofoto,
'status' => $response->status(),
'body' => $response->body()
]);
}
}
if ($ketemu != ''){
if (is_null($isidata) || $isidata == ''){
$isidata = $ketemu;
} else {
$isidata = $isidata.'<br />'.$ketemu;
}
}
if (!is_null($isidata) && $isidata != ''){
KomponenJawaban::updateOrCreate(
[
'accnumber' => $nofoto,
'template' => $request->input('jenis'),
'komponen' => $request->input('komponen'),
],
[
'isidata' => $isidata,
'created_by' => Session('nama')
]
);
}
$pesan = $isidata;
} catch (Exception $e) {
$pesan = (is_null($isidata) ? '' : $isidata . '<br />') . 'Error: ' . $e->getMessage();
Log::error('Exception dalam fungsi requestResult.', [
'sample_id' => $nofoto,
'exception' => $e->getMessage()
]);
}
return response($pesan, 200);
} else if ($worklist == 'addviralload'){
$tabelawal = $request->input('tabelawal');
$idtabel = $request->input('idtabel');
@@ -1262,10 +1329,10 @@ class DokterController extends Controller
$setval = $batasbawah;
}
if ($nomor == 1){
$tabel = '<table border="1" cellpadding="0" cellspacing="0" width="100%"><tr><td width="5%"><strong>No</strong></td><td width="20%"><strong>Antibiotik</strong></td><td width="20%"><strong>Sub</strong></td><td width="10%"><strong>Disc Content</strong></td><td width="5%"><strong>S/I/R</strong></td></tr><tr><td>'.$nomor.'</td><td>'.$getdata->antibiotik.'</td><td>'.$getdata->subantibiotik.'</td><td>'.$getdata->diskcontent.'</td><td>'.$setnilai.'</td></tr></table>';
$tabel = '<table border="1" cellpadding="0" cellspacing="0" width="100%"><tr><td width="5%"><strong>No</strong></td><td width="20%"><strong>Antibiotik</strong></td><td width="20%"><strong>Sub</strong></td><td width="10%"><strong>Disc Content</strong></td><td width="5%"><strong>S/I/R</strong></td></tr><tr><td>'.$nomor.'</td><td>'.$getdata->antibiotik.' '.$getdata->subantibiotik.'</td><td>'.$getdata->diskcontent.'</td><td>'.$setnilai.'</td></tr></table>';
} else {
$baris = '<tr><td>'.$nomor.'</td><td>'.$getdata->antibiotik.'</td><td>'.$getdata->subantibiotik.'</td><td>'.$getdata->diskcontent.'</td><td>'.$setnilai.'</td></tr>';
$baris = '<tr><td>'.$nomor.'</td><td>'.$getdata->antibiotik.' '.$getdata->subantibiotik.'</td><td>'.$getdata->diskcontent.'</td><td>'.$setnilai.'</td></tr>';
$tabel = str_replace('</table>', $baris, $tabelawal);
$tabel = $tabel.'</table>';
}
@@ -1664,6 +1731,35 @@ class DokterController extends Controller
'antibiotikall' => $antibiotikall,
);
}
$getsirab = SiraB::orderBy('family', 'ASC')->orderBy('spesies', 'ASC')->where('cek', '0')->get();
foreach($getsirab as $row){
$family = $row->family;
$spesies= $row->spesies;
$getallantibiotik = SiraB::where('family', $family)->get();
foreach ($getallantibiotik as $row2){
SiraB::updateOrCreate(
[
'family' => $row->family,
'spesies' => $row->spesies,
'antibiotik' => $row2->antibiotik,
'subantibiotik' => $row2->subantibiotik,
],
[
'diskcontent' => $row2->diskcontent,
'batasatas' => $row2->batasatas,
'midrange' => $row2->midrange,
'batasbawah' => $row2->batasbawah,
'sumber' => $row2->sumber,
'kodedok' => $row2->kodedok,
'atu' => $row2->atu,
'kelompok' => $row2->kelompok,
'glassreportname' => trim($row2->glassreportname),
'cek' => '1',
]
);
}
}
echo json_encode($arrayfiles);
} else if ($idpasien == 'Bakteri'){
$getsirab = Organisms::where('kelompok', 'biakankultur')->orderBy('category', 'ASC')->orderBy('name', 'ASC')->get();
@@ -4,6 +4,8 @@ namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Http;
use App\Services\AstmMessageService;
use App\Services\SerialCommunicationService;
use App\Http\Controllers\SendMail;
@@ -29,21 +31,57 @@ use Validator;
use Session;
use DateTime;
use QrCode;
use Exception;
use Carbon\Carbon;
use Aranyasen\HL7\Message;
use Aranyasen\HL7\Connection;
use Aranyasen\HL7\Segment;
use Aranyasen\HL7\Segments\MSH;
use Aranyasen\HL7\Segments\PV1;
use Aranyasen\HL7\Segments\OBR;
use Aranyasen\HL7\Segments\ORC;
use Aranyasen\HL7\Segments\PID;
use Aranyasen\HL7\Segments\OBX;
use Aranyasen\HL7\Segments\NTE;
use Aranyasen\HL7\Segments\EVN;
class FrontpageController extends Controller
{
protected $lisServiceUrl;
public function __construct()
{
// Mengambil URL service dari file .env, dengan fallback default
$this->lisServiceUrl = env('LIS_SERVICE_URL', 'http://10.10.120.14:5000');
}
private function sendRegistrationToLis(array $data)
{
// Memetakan data dari fungsi register Anda ke format yang dibutuhkan LIS service
// PENTING: Pastikan pemetaan ini benar, terutama 'test_code'.
$payload = [
'command' => 'register_patient',
'data' => [
'patient_name' => $data['nama'],
'patient_id' => $data['noregister'], // Menggunakan no register sebagai ID Pasien
'sample_id' => $data['nofoto'], // Menggunakan nofoto sebagai ID Sampel unik
'test_code' => $data['kd_spesimen'],// Kode tes spesifik untuk GeneXpert (e.g., MTBRIF)
'test_name' => $data['nm_spesimen'],
'dob' => $data['tgllahir'] ? \Carbon\Carbon::parse($data['tgllahir'])->format('Ymd') : '',
'gender' => $data['jk'],
],
];
try {
$response = Http::timeout(30)->post($this->lisServiceUrl . '/command', $payload);
if ($response->failed()) {
Log::error('Gagal mengirim data pendaftaran ke LIS service.', [
'sample_id' => $data['nofoto'],
'status' => $response->status(),
'response' => $response->body()
]);
} else {
Log::info('Data pendaftaran berhasil dikirim ke LIS service.', [
'sample_id' => $data['nofoto'],
'response' => $response->json()
]);
}
} catch (Exception $e) {
Log::error('Koneksi ke LIS service gagal saat pendaftaran.', [
'sample_id' => $data['nofoto'],
'exception' => $e->getMessage()
]);
}
}
public function index() {
$data = [];
$data['antrkrmsitu']= PeriksaSYNC::where('created_by', Session('username'))->where('status', '')->count();
@@ -588,8 +626,8 @@ class FrontpageController extends Controller
$insurance = $request->input('asuransi') ?? 'UMM';
$rekues = $request->input('layanan');
$urgensi = $request->input('urgensi') ?? 'Elective';
$kd_spesimen = $request->input('kd_spesimen') ?? '';
$nm_spesimen = $request->input('nm_spesimen') ?? '';
$kd_spesimen = $request->input('kode') ?? '';
$nm_spesimen = $request->input('spesimen') ?? '';
$klinis = $request->input('klinis');
$notransaksi = $request->input('notransaksi');
$telpon = str_replace('_', '', $telpon);
@@ -724,6 +762,27 @@ class FrontpageController extends Controller
'orderid' => $notransaksi,
]);
$pesan = $nofoto;
DB::table('paslab')->insert([
'rnoreg' => $nofoto,
'nama' => $nama,
'norm' => $noregister,
'rtglast' => $mulai,
'alamat' => $alamat,
'rjenis' => $jk,
'umur' => $usia,
'namadok' => $klinisi,
'ruangan' => 'Mikrobiologi',
'tes' => $rekues,
'alat' => 'ALL',
'kd_spesimen' => $kd_spesimen,
'nm_spesimen' => $nm_spesimen,
'tgllahir' => $tgllahir,
'flg_vitek1' => false,
'flg_vitek2' => false,
'flg_bd1' => false,
'flg_bd2' => false,
'flg_gxp' => false,
]);
if ($kd_spesimen != '' AND $nm_spesimen != ''){
PendaftaranOnListiner::updateOrCreate(
[
@@ -748,6 +807,7 @@ class FrontpageController extends Controller
'nm_spesimen' => $nm_spesimen,
]
);
}
if ($pesan != ''){
return response()->json(['status' => 'Sukses', 'message' => $pesan], 201);
@@ -756,21 +816,8 @@ class FrontpageController extends Controller
}
}
public function registerApi(Request $request) {
//$dataJson = json_encode($request->input());
//$decodedFirst = json_decode($dataJson, true);
Log::info(' Incomming '.json_encode($request->input()));
$decodedData = $request->json()->all();
//$decodedData = $request->input();
//if (json_last_error() !== JSON_ERROR_NONE) {
// Log::error('JSON Decode Error (First): ' . json_last_error_msg());
// return response()->json(['error' => 'Invalid first-level JSON data'], 400);
//}
//$innerJson = key($decodedFirst);
//$decodedData = json_decode($innerJson, true);
//if (json_last_error() !== JSON_ERROR_NONE) {
// Log::error('JSON Decode Error (Second): ' . json_last_error_msg());
// return response()->json(['error' => 'Invalid second-level JSON data'], 400);
//}
$norm = $decodedData['norm'] ?? null;
$nama = $decodedData['nama'] ?? null;
$alamat = $decodedData['alamat'] ?? config('global.addressapps');
@@ -784,23 +831,42 @@ class FrontpageController extends Controller
$bpjs = $decodedData['nobpjs'] ?? '0';
$drpeminta = $decodedData['drpeminta'] ?? null;
$tlsasal = $decodedData['asalpasien'] ?? null;
$rekues = $decodedData['layanan'] ?? null;
//$rekues = $decodedData['layanan'] ?? null;
$statusbayar = $decodedData['statusbayar'] ?? null;
$notransaksi = $decodedData['notransaksi'] ?? null;
$insurance = $decodedData['asuransi'] ?? 'UMM';
$klinis = $decodedData['klinis'] ?? null;
$klinisi = $decodedData['klinisi'] ?? $drpeminta;
$kd_spesimen = $decodedData['kd_spesimen'] ?? null;
$nm_spesimen = $decodedData['nm_spesimen'] ?? null;
$rekues = $decodedData['kode'] ?? null;
$nm_spesimen = $decodedData['spesimen'] ?? null;
$pengambilan = $decodedData['pengambilan'] ?? null;
$nmrs = $decodedData['namarspengirim'] ?? 'RSSA Malang';
$telpon = str_replace('_', '', $nohap);
$rekues = str_replace('_', ' ', $rekues);
//$rekues = str_replace('_', ' ', $rekues);
$tlsasal = str_replace('_', ' ', $tlsasal);
$klinisi = str_replace('_', ' ', $klinisi);
$nama = str_replace('_', ' ', $nama);
$alamat = str_replace('_', ' ', $alamat);
$kd_spesimen = '';
$getkodespesimen= Organisms::where('name', $nm_spesimen)->where('kelompok', 'listkodespesimen')->first();
if (isset($getkodespesimen->category)){
$kd_spesimen= $getkodespesimen->category;
} else {
$cekdulu = explode(' ', $nm_spesimen);
if (isset($cekdulu[1])){
$kd_spesimen = str_replace('.', '', $cekdulu[0]);
} else {
foreach ($cekdulu as $kata) {
$kd_spesimen .= substr($kata, 0, 1);
}
}
Organisms::create([
'name' => $nm_spesimen,
'category' => $kd_spesimen,
'kelompok' => 'listkodespesimen'
]);
}
$iddokter = '';
$ruangan = 1;
$kelompok = 'admin';
@@ -926,6 +992,27 @@ class FrontpageController extends Controller
]);
$pesan = $nofoto;
try {
DB::table('paslab')->insert([
'rnoreg' => $nofoto,
'nama' => $nama,
'norm' => $noregister,
'rtglast' => $mulai,
'alamat' => $alamat,
'rjenis' => $jk,
'umur' => $usia,
'namadok' => $dokter,
'ruangan' => 'Mikrobiologi',
'tes' => $rekues,
'alat' => 'ALL',
'kd_spesimen' => $kd_spesimen,
'nm_spesimen' => $nm_spesimen,
'tgllahir' => $tgllahir,
'flg_vitek1' => false,
'flg_vitek2' => false,
'flg_bd1' => false,
'flg_bd2' => false,
'flg_gxp' => false,
]);
if ($kd_spesimen != '' AND $nm_spesimen != ''){
PendaftaranOnListiner::updateOrCreate(
[
@@ -950,6 +1037,18 @@ class FrontpageController extends Controller
'nm_spesimen' => $nm_spesimen,
]
);
/*
$dataForLis = [
'nama' => $nama,
'noregister' => $noregister,
'nofoto' => $nofoto,
'kd_spesimen' => $kd_spesimen,
'nm_spesimen' => $nm_spesimen,
'tgllahir' => $tgllahir,
'jk' => $jk,
];
$this->sendRegistrationToLis($dataForLis);
*/
}
return response()->json(['status' => 'Sukses', 'message' => $pesan], 201);
} catch (Exception $e) {
@@ -1165,6 +1264,26 @@ class FrontpageController extends Controller
'pendaftar' => Session('previlage'),
'nmpendaftar' => Session('nama'),
]);
DB::table('paslab')->insert([
'rnoreg' => $nofoto,
'nama' => $nama,
'norm' => $noregister,
'rtglast' => $mulai,
'alamat' => $alamat,
'rjenis' => $jk,
'umur' => $usia,
'namadok' => $dokter,
'ruangan' => 'Mikrobiologi',
'tes' => $rekues,
'alat' => 'ALL',
'kd_spesimen' => $kd_spesimen,
'nm_spesimen' => $nm_spesimen,
'tgllahir' => $tgllahir,
'flg_vitek1' => false,
'flg_vitek2' => false,
'flg_bd1' => false,
'flg_bd2' => false,
]);
if ($kd_spesimen != '' AND $nm_spesimen != ''){
PendaftaranOnListiner::updateOrCreate(
[
@@ -1189,6 +1308,18 @@ class FrontpageController extends Controller
'nm_spesimen' => $nm_spesimen,
]
);
/*
$dataForLis = [
'nama' => $nama,
'noregister' => $noregister,
'nofoto' => $nofoto,
'kd_spesimen' => $kd_spesimen,
'nm_spesimen' => $nm_spesimen,
'tgllahir' => $tgllahir,
'jk' => $jk,
];
$this->sendRegistrationToLis($dataForLis);
*/
}
$pesan = $pesan.' Nomor Lokal '.$nofoto.' dengan No. Urut '.$noloket.' Berhasil di Simpan';
if ($pesan != ''){
@@ -1280,6 +1411,30 @@ class FrontpageController extends Controller
'kd_spesimen' => $kd_spesimen,
'nm_spesimen' => $nm_spesimen,
]);
$ceksudah = DB::table('paslab')->where('rnoreg', $nofoto)->count();
if ($ceksudah == 0){
DB::table('paslab')->insert([
'rnoreg' => $nofoto,
'nama' => $nama,
'norm' => $noregister,
'rtglast' => $mulai,
'alamat' => $alamat,
'rjenis' => $jk,
'umur' => $usia,
'namadok' => $getdata->dokter ?? 'Unkown',
'ruangan' => 'Mikrobiologi',
'tes' => $rekues,
'alat' => 'ALL',
'kd_spesimen' => $kd_spesimen,
'nm_spesimen' => $nm_spesimen,
'tgllahir' => $tgllahir,
'flg_vitek1' => false,
'flg_vitek2' => false,
'flg_bd1' => false,
'flg_bd2' => false,
]);
}
$pesan = $pesan.' Data Berhasil di Update';
if ($kd_spesimen != '' AND $nm_spesimen != ''){
PendaftaranOnListiner::updateOrCreate(
@@ -1305,6 +1460,18 @@ class FrontpageController extends Controller
'nm_spesimen' => $nm_spesimen,
]
);
/*
$dataForLis = [
'nama' => $nama,
'noregister' => $noregister,
'nofoto' => $nofoto,
'kd_spesimen' => $kd_spesimen,
'nm_spesimen' => $nm_spesimen,
'tgllahir' => $tgllahir,
'jk' => $jk,
];
$this->sendRegistrationToLis($dataForLis);
*/
}
if ($pesan != ''){
if ($file != '' AND $jenisgambar != ''){
@@ -1341,81 +1508,38 @@ class FrontpageController extends Controller
$modality = $request->input('reques');
$cekdata = Periksa::where('nofoto', $nofoto)->first();
if (isset($cekdata->id)){
$senderName = 'LIS_System';
$versionNumber = 'V1.0';
$nama = $cekdata->nmpasien;
$jk = $cekdata->jkpasien;
$urgensi = $cekdata->urgensi ?? 'Elective';
$alamat = $cekdata->alamatpasien ?? 'Malang';
$arrayttl = explode(" ", $nama);
$fname = iconv("UTF-8", "tis-620", $arrayttl[0]);
if (isset($arrayttl[1])){
$tengah = iconv("UTF-8", "tis-620", $arrayttl[1]);
}
if (isset($arrayttl[2])){
$blakang = iconv("UTF-8", "tis-620", $arrayttl[2]);
} else {
$blakang = $tengah;
$tengah = '';
}
if ($jk == 'L'){ $panggilan = 'TN'; $jk = 'M'; }
else if ($jk == 'P') { $panggilan = 'NY'; $jk = 'F'; }
else { $panggilan = 'UNK'; $jk = 'O'; }
$panggilan = '';
if ($blakang == ''){ $blakang = $fname; }
if ($urgensi == 'Elective'){ $urgensi = 'INPATIENT'; $prioritas = 'R'; }
else if ($urgensi == 'CITO'){ $urgensi = 'EMERGENCY'; $prioritas = 'A'; }
else { $urgensi = 'OUTPATIENT'; $prioritas = 'A'; }
$patient = [
'id' => $cekdata->id,
'last_name' => $fname,
'first_name' => $blakang,
'middle_name' => $tengah,
'suffix' => $panggilan,
'dob' => $cekdata->noregister,
'sex' => $jk,
'address' => $alamat.'^^MALANG^^ID^65123',
'phone' => $cekdata->tlppasien,
'admitting_physician' => $cekdata->klinisi ?? 'Dokter Pengirim'
];
$order = [
'accession_number' => $cekdata->nofoto,
'isolate_number' => 'MGIT^TestName',
'organism' => $cekdata->reques ?? 'Mycobacterium tuberculosis',
'exclude_isolate' => 'No',
'priority' => $prioritas,
'collection_date_time' => date("YmdHi"),
'collected_by' => $cekdata->nmradiografer ?? Session('nama'),
'received_by' => Session('nama'),
'specimen_action_code' => '',
'isolate_source_test' => 'Blood',
'isolate_source_test_start_time'=> date("YmdHi"),
'receipt_date_time' => date("YmdHi"),
'specimen_type' => 'Blood Culture',
'body_site' => 'Lung',
'ordering_physician' => $cekdata->klinisi ?? 'Dokter Pengirim',
'ordering_physician_phone' => '',
'ordering_physician_fax' => '',
'ordering_physician_pager' => '',
'specimen_user_field_1' => '',
'specimen_user_field_2' => '',
'specimen_user_field_3' => '',
'specimen_user_field_4' => '',
'specimen_user_field_5' => '',
'finalized_date_time' => date("YmdHi"),
'specimen_reimbursement_value' => '100',
'test_reimbursement_value' => '50',
'isolate_classification' => 'Nosocomial'
];
Periksa::where('nofoto', $nofoto)->update([
'excutor' => Session('id'),
'nmexcutor' => Session('nama'),
]);
try {
if ($modality == 'genexpert01' OR $modality == 'genexpert02' OR $modality == 'genexpert03'){
$pesan = $this->Hl7Register($cekdata->id, $modality);
} else {
$pesan = 'Cannot send on Serial Port From Server';
$ceksudah = DB::table('paslab')->where('rnoreg', $nofoto)->count();
if ($ceksudah == 0){
DB::table('paslab')->insert([
'rnoreg' => $nofoto,
'nama' => $nama,
'norm' => $cekdata->noregister,
'rtglast' => $cekdata->mulai,
'alamat' => $alamat,
'rjenis' => $jk,
'umur' => $cekdata->usia,
'namadok' => $getdata->dokter ?? 'Unkown',
'ruangan' => 'Mikrobiologi',
'tes' => $cekdata->reques,
'alat' => 'ALL',
'kd_spesimen' => $cekdata->kd_spesimen,
'nm_spesimen' => $cekdata->nm_spesimen,
'tgllahir' => $cekdata->tgllahirpasien,
'flg_vitek1' => false,
'flg_vitek2' => false,
'flg_bd1' => false,
'flg_bd2' => false,
]);
}
}catch (Exception $e) {
$pesan = $e->getMessage();
@@ -1434,23 +1558,56 @@ class FrontpageController extends Controller
if ($nofoto == 'noregister'){
$noregister = $request->input('noregister');
$tabel = '';
$periksa = Periksa::where('noregister', $noregister)->where('tgllahirpasien', $tgllahir)->get();
if (!empty($periksa)){
$lists = DB::table('periksa')
->select('periksa.*', 'organisms.satuan as satuanperspesimen', 'organisms.nilai as nilaiperspesimen')
->leftJoin('periksa', 'organisms.category', 'periksa.kd_spesimen')
->where('periksa.noregister', $noregister)
->where('periksa.tgllahirpasien', $tgllahir)
->get();
if (!empty($lists)){
$tabel = '<div class="timeline">';
$kanan = '';
foreach($periksa as $rows){
$status = $rows->status;
foreach($lists as $rows){
$status = $rows->status;
$id_periksa = $rows->id;
if ( !empty($rows->rating) ) {
$saved_rating = $rows->rating;
$bintang_html = '';
for ($i = 1; $i <= 5; $i++) {
if ( $i <= $saved_rating ) {
$bintang_html .= '<i class="fa fa-star" style="font-size:18px; color:orange;"></i>';
} else {
$bintang_html .= '<i class="fa fa-star-o" style="font-size:18px; color:orange;"></i>';
}
}
$ratingBintang = '
<div class="rating-stars" data-id="'.$id_periksa.'">
<small class="text-muted">Terimka kasih atas rating yang diberikan:</small><br>
'.$bintang_html.'
</div>';
} else {
$ratingBintang = '
<div class="rating-stars" data-id="'.$id_periksa.'">
<small class="text-muted">Beri Rating:</small><br>
<i class="fa fa-star-o" style="cursor:pointer; font-size:18px; color:orange;" onclick="btnisiRating('.$id_periksa.', 1)"></i>
<i class="fa fa-star-o" style="cursor:pointer; font-size:18px; color:orange;" onclick="btnisiRating('.$id_periksa.', 2)"></i>
<i class="fa fa-star-o" style="cursor:pointer; font-size:18px; color:orange;" onclick="btnisiRating('.$id_periksa.', 3)"></i>
<i class="fa fa-star-o" style="cursor:pointer; font-size:18px; color:orange;" onclick="btnisiRating('.$id_periksa.', 4)"></i>
<i class="fa fa-star-o" style="cursor:pointer; font-size:18px; color:orange;" onclick="btnisiRating('.$id_periksa.', 5)"></i>
</div>';
}
if ($status == 'Selesai'){
$tombolcetak = url('/').'/hasil/'.$rows->nofoto;
$tombolcetak = '<a href="'.$tombolcetak.'"><button type="button" class="btn btn-icon waves-effect waves-light btn-success"> <i class="fa fa-print"></i> </button></a>';
} else {
$tombolcetak = '';
$tombolcetak = 'Masih dalam proses dan perkiraan selesai adalah '.$rows->nilaiperspesimen.' '.$rows->satuanperspesimen.' dari sample diterima';
}
if ($kanan == ''){
$tabel = $tabel.'<article class="timeline-item"><div class="timeline-desk"><div class="panel"><div class="timeline-box"><span class="arrow"></span><span class="timeline-icon bg-custom"><i class="mdi mdi-adjust"></i></span><h4 class="text-custom">'.$rows->daftar.'</h4><p class="timeline-date text-muted"><small>'.$rows->reques.'</small></p><p>'.$rows->status.'</p><div class="btn btn-group">'.$tombolcetak.'</div></div></div></div></article>';
$tabel = $tabel.'<article class="timeline-item"><div class="timeline-desk"><div class="panel"><div class="timeline-box"><span class="arrow"></span><span class="timeline-icon bg-custom"><i class="mdi mdi-adjust"></i></span><h4 class="text-custom">'.$rows->daftar.'</h4><p class="timeline-date text-muted"><small>'.$rows->reques.'</small></p><p>'.$rows->status.'</p>'.$ratingBintang.'<div class="btn btn-group">'.$tombolcetak.'</div></div></div></div></article>';
$kanan = 'kanan';
} else {
$tabel = $tabel.'<article class="timeline-item alt"><div class="timeline-desk"><div class="panel"><div class="timeline-box"><span class="arrow-alt"></span><span class="timeline-icon bg-custom"><i class="mdi mdi-adjust"></i></span><h4 class="text-custom">'.$rows->daftar.'</h4><p class="timeline-date text-muted"><small>'.$rows->reques.'</small></p><p>'.$rows->status.'</p><div class="btn btn-group">'.$tombolcetak.'</div></div></div></div></article>';
$tabel = $tabel.'<article class="timeline-item alt"><div class="timeline-desk"><div class="panel"><div class="timeline-box"><span class="arrow-alt"></span><span class="timeline-icon bg-custom"><i class="mdi mdi-adjust"></i></span><h4 class="text-custom">'.$rows->daftar.'</h4><p class="timeline-date text-muted"><small>'.$rows->reques.'</small></p><p>'.$rows->status.'</p>'.$ratingBintang.'<div class="btn btn-group">'.$tombolcetak.'</div></div></div></div></article>';
$kanan = '';
}
}
@@ -1459,6 +1616,10 @@ class FrontpageController extends Controller
$tabel = 'Data Tidak ditemukan, Pastikan Kembali Apakah No. RM ('.$noregister.') dan tanggal lahir ('.$tgllahir.') sudah benar';
}
echo $tabel;
} else if ($nofoto == 'isirating'){
Periksa::where('id', $request->input('id'))->update([
'rating' => $request->input('rating')
]);
} else {
$periksa = Periksa::where('nofoto', $nofoto)->where('tgllahirpasien', $tgllahir)->first();
if (isset($periksa->id)){
@@ -0,0 +1,116 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class LisController extends Controller
{
/**
* Alamat IP dan port dari service Python/Flask.
* Sebaiknya diletakkan di file .env
* LIS_SERVICE_URL=http://127.0.0.1:5000
*/
protected $lisServiceUrl;
public function __construct()
{
// Mengambil URL service dari file .env, dengan fallback default
$this->lisServiceUrl = env('LIS_SERVICE_URL', 'http://localhost:5000');
}
/**
* Mengirim perintah untuk mendaftarkan tes pasien baru ke GeneXpert.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function registerPatient(Request $request)
{
// Validasi input dari request (sangat direkomendasikan)
$validatedData = $request->validate([
'patient_name' => 'required|string|max:100',
'patient_id' => 'required|string|max:50',
'sample_id' => 'required|string|max:50',
'test_code' => 'required|string|max:20',
'test_name' => 'sometimes|string|max:50',
'dob' => 'sometimes|date_format:Ymd',
'gender' => 'sometimes|string|in:M,F,O,U',
]);
// Membangun payload sesuai format yang diharapkan oleh app.py
$payload = [
'command' => 'register_patient',
'data' => $validatedData,
];
try {
// Mengirim request POST ke service Python
$response = Http::timeout(30) // Set timeout 30 detik
->post($this->lisServiceUrl . '/command', $payload);
// Cek jika request gagal di level HTTP
if ($response->failed()) {
Log::error('Gagal terhubung ke LIS service saat registrasi.', [
'status' => $response->status(),
'body' => $response->body()
]);
return response()->json([
'error' => 'Tidak dapat terhubung ke LIS service.',
'details' => $response->body()
], 503); // Service Unavailable
}
// Mengembalikan response dari service Python ke client
return response()->json($response->json(), $response->status());
} catch (\Illuminate\Http\Client\ConnectionException $e) {
Log::error('Koneksi ke LIS service gagal.', ['exception' => $e->getMessage()]);
return response()->json(['error' => 'Koneksi ke LIS service gagal.'], 504); // Gateway Timeout
}
}
/**
* Mengirim perintah untuk meminta ulang hasil tes berdasarkan Sample ID.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function requestResult(Request $request)
{
// Validasi input
$validatedData = $request->validate([
'sample_id' => 'required|string|max:50',
]);
// Membangun payload
$payload = [
'command' => 'request_result',
'data' => $validatedData,
];
try {
// Mengirim request POST ke service Python
$response = Http::timeout(30)->post($this->lisServiceUrl . '/command', $payload);
if ($response->failed()) {
Log::error('Gagal terhubung ke LIS service saat meminta hasil.', [
'status' => $response->status(),
'body' => $response->body()
]);
return response()->json([
'error' => 'Tidak dapat terhubung ke LIS service.',
'details' => $response->body()
], 503);
}
return response()->json($response->json(), $response->status());
} catch (\Illuminate\Http\Client\ConnectionException $e) {
Log::error('Koneksi ke LIS service gagal.', ['exception' => $e->getMessage()]);
return response()->json(['error' => 'Koneksi ke LIS service gagal.'], 504);
}
}
}
+107 -30
View File
@@ -224,41 +224,118 @@ class ListController extends Controller
$id = $request->input('val01');
$alasan = $request->input('val02');
$tabel = $request->input('val03');
if ($alasan == ''){
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Mohon isi semua form']);
return back();
} else {
if ($tabel == 'aktif'){
$alasan = 'Dibatalkan dengan alasan '.$alasan;
$input = Periksa::where('id', $id)->update([
'noloket' => null,
'status' => $alasan
if ($id == 'buatulang'){
$getdata= Periksa::where('id', $request->input('val02'))->first();
if (isset($getdata->nofoto)){
$ceksudah = Periksa::where('nofoto', 'LIKE', $getdata->nofoto.'_%')->count();
$nomorbaru = $ceksudah++;
$periksaid = Periksa::insertGetId([
'mulai' => $getdata->mulai,
'akhir' => $getdata->akhir,
'noloket' => $getdata->noloket,
'nofoto' => $getdata->nofoto.'_'.$nomorbaru,
'noregister' => $getdata->noregister,
'asalpasien' => $getdata->asalpasien,
'nmrs' => $getdata->nmrs,
'pasien_id' => $getdata->pasien_id,
'nmpasien' => $getdata->nmpasien,
'jkpasien' => $getdata->jkpasien,
'ktp' => $getdata->ktp,
'bpjs' => $getdata->bpjs,
'tgllahirpasien'=> $getdata->tgllahirpasien,
'tlppasien' => $getdata->tlppasien,
'alamatpasien' => $getdata->alamatpasien,
'reques' => $getdata->reques,
'usia' => $getdata->usia,
'berat' => $getdata->berat,
'ruangan_id' => $getdata->ruangan_id,
'ruangan' => $getdata->ruangan,
'klinisi' => $getdata->klinisi,
'klinis' => $getdata->klinis,
'poli_id' => $getdata->poli_id,
'kd_spesimen' => $getdata->kd_spesimen,
'nm_spesimen' => $getdata->nm_spesimen,
'keterangan' => '',
'kesimpulan' => '',
'asuransi' => $getdata->asuransi,
'urgensi' => $getdata->urgensi,
'daftar' => $getdata->daftar,
'pendaftar' => Session('id'),
'nmpendaftar' => Session('nama'),
'orderid' => $getdata->orderid,
]);
$pesan = 'Order Expertise Canceled';
} else if ($tabel == 'arsip'){
$total = 0;
$input = Periksa::whereIn('id', $id)->update([
'status'=> 'Arsip'
]);
if ($input){
$total++;
}
$pesan = 'Expertise Archieved '.$total;
try {
if ($getdata->kd_spesimen != '' AND $getdata->nm_spesimen != ''){
PendaftaranOnListiner::updateOrCreate(
[
'rnoreg' => $getdata->nofoto,
],
[
'rtglast' => date('Y-m-d'),
'norm' => $getdata->noregister,
'nama' => $getdata->nmpasien,
'alamat' => $getdata->alamatpasien,
'telp' => $getdata->tlppasien,
'hp' => $getdata->tlppasien,
'tgllahir' => $getdata->tgllahirpasien,
'umur' => $getdata->usia,
'rjenis' => $getdata->jkpasien,
'kodedok' => Session('id'),
'namadok' => Session('nama'),
'ruangan' => $getdata->ruangan,
'tes' => '',
'alat' => 'All',
'kd_spesimen' => $getdata->kd_spesimen,
'nm_spesimen' => $getdata->nm_spesimen,
]
);
}
return response()->json(['status' => 'Sukses', 'message' => 'Data Order Berhasil di Gandakan'], 201);
} catch (Exception $e) {
return response()->json(['status' => 'Sukses', 'message' => 'Data Order Berhasil di Gandakan'], 201);
}
} else {
$alasan = 'Dibatalkan dengan alasan '.$alasan;
$input = Jadwalperiksa::where('id', $id)->update([
'noloket' => null,
'status' => $alasan
]);
$pesan = 'Schedulling Canceled';
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Data Tidak Valid']);
return back();
}
if ($input){
return response()->json(['icon' => 'success', 'warna' => '#5ba035', 'status' => 'Sukses', 'message' => $pesan]);
return back();
}else {
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'System Down, please try again in a few years...']);
} else {
if ($alasan == ''){
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'Mohon isi semua form']);
return back();
} else {
if ($tabel == 'aktif'){
$alasan = 'Dibatalkan dengan alasan '.$alasan;
$input = Periksa::where('id', $id)->update([
'noloket' => null,
'status' => $alasan
]);
$pesan = 'Order Expertise Canceled';
} else if ($tabel == 'arsip'){
$total = 0;
$input = Periksa::whereIn('id', $id)->update([
'status'=> 'Arsip'
]);
if ($input){
$total++;
}
$pesan = 'Expertise Archieved '.$total;
} else {
$alasan = 'Dibatalkan dengan alasan '.$alasan;
$input = Jadwalperiksa::where('id', $id)->update([
'noloket' => null,
'status' => $alasan
]);
$pesan = 'Schedulling Canceled';
}
if ($input){
return response()->json(['icon' => 'success', 'warna' => '#5ba035', 'status' => 'Sukses', 'message' => $pesan]);
return back();
}else {
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Gagal', 'message' => 'System Down, please try again in a few years...']);
return back();
}
}
}
}
}
@@ -105,48 +105,39 @@ class PasienController extends Controller
]);
} else {
try {
$client = new Client();
$res = $client->request('GET', 'http://10.10.123.51:8000/mr/'.$norm);
$response_data = json_decode($res->getBody()->getContents());
if (isset($response_data[0])) {
$hasil = $response_data[0];
$nama = $hasil->Nama;
$alamat = $hasil->Alamat;
$telpon = $hasil->Telp;
$kota = $hasil->Kota;
$kelamin = $hasil->JenisKelamin;
$tgllahir = $hasil->tanggal_lahir;
$nik = $hasil->nik;
$bpjs = $hasil->bpjs;
if ($kelamin == 'WANITA'){
$kelamin = 'P';
} else { $kelamin = 'L'; }
return response()->json([
'id' => 'new',
'norm' => $norm,
'telpon' => $telpon,
'nama' => $nama,
'tgl_lahir' => $tgllahir,
'jk' => $kelamin,
'alamat' => $alamat,
'kota' => $kota,
'nik' => $nik,
'bpjs' => $bpjs,
]);
} else {
return response()->json([
'id' => '',
'telpon' => '000000000',
'norm' => $norm,
'nama' => '',
'tgl_lahir' => date("d-m-Y"),
'jk' => 'L',
'alamat' => 'Malang',
'kota' => 'Malang',
'nik' => '',
'bpjs' => '',
]);
}
$client = new Client();
$res = $client->request('GET', env('GETPASIEN_API'), ['query' => ['limit' => 10, 'nomedis' => $norm]]);
$response_data = json_decode($res->getBody()->getContents());
if (isset($response_data->response[0])) {
$hasil = $response_data->response[0];
$nama = $hasil->Nama;
$alamat = $hasil->Alamat;
$telpon = $hasil->Telp;
$kota = $hasil->Kota;
$kelamin = $hasil->JenisKelamin;
$tgllahir = $hasil->tanggal_lahir;
return response()->json([
'id' => 'new',
'norm' => $norm,
'telpon' => $telpon,
'nama' => $nama,
'tgl_lahir' => date('d-m-Y', strtotime($tgllahir)),
'jk' => $kelamin,
'alamat' => $alamat,
'kota' => $kota,
]);
} else {
return response()->json([
'id' => '',
'telpon' => '000000000',
'norm' => $norm,
'nama' => '',
'tgl_lahir' => date("d-m-Y"),
'jk' => 'L',
'alamat' => 'Malang',
'kota' => 'Malang',
]);
}
}catch (Exception $e) {
return response()->json([
'id' => '',
@@ -308,25 +308,34 @@ class ReportController extends Controller
}
}
public function genRekapAntibiotik(Request $request) {
$data = [];
$bulan = $request->input('bulan');
$tahun = $request->input('tahun');
$data = [];
$bulan = $request->input('bulan');
$tahun = $request->input('tahun');
if ($tahun == '' OR is_null($tahun)){
$getarray = explode('?', $bulan);
$bulan = $getarray[0] ?? date('m');
$tahun = $getarray[1] ?? date('Y');
$bulan = str_replace('bulan=', '', $bulan);
$tahun = str_replace('tahun=', '', $tahun);
}
$getarray = explode('?', $bulan);
$bulan = $getarray[0] ?? date('m');
$tahun = $getarray[1] ?? date('Y');
$bulan = str_replace('bulan=', '', $bulan);
$tahun = str_replace('tahun=', '', $tahun);
}
if ($bulan == '' OR $bulan == 'ALL' OR $bulan == 'Pick Month') {
$orderbydate = Periksa::whereYear('daftar', $tahun)->get();
$jsonantibiotik = RekapAntibiotik::whereIn('orderid', $orderbydate->pluck('id'))->get()->groupBy('orderid');
$orderbydate = Periksa::whereYear('daftar', $tahun)->orderBy('daftar', 'asc')->get();
} else {
$orderbydate = Periksa::whereMonth('daftar', $bulan)->whereYear('daftar', $tahun)->get();
$jsonantibiotik = RekapAntibiotik::whereIn('orderid', $orderbydate->pluck('id'))->get()->groupBy('orderid');
$orderbydate = Periksa::whereMonth('daftar', $bulan)->whereYear('daftar', $tahun)->orderBy('daftar', 'asc')->get();
}
return view('admin.rekapantibiotik', compact('orderbydate', 'jsonantibiotik', 'bulan', 'tahun'));
}
$orderIds = $orderbydate->pluck('id');
$allAntibiotics = RekapAntibiotik::whereIn('orderid', $orderIds)->get();
$masterAntibioticList = $allAntibiotics->pluck('resistance')->unique()->sort()->values();
$jsonantibiotik = $allAntibiotics->groupBy('orderid')->map(function ($items) {
return $items->pluck('interpretation', 'resistance');
});
return view('admin.rekapantibiotik', compact('orderbydate', 'jsonantibiotik', 'bulan', 'tahun', 'masterAntibioticList'));
}
public function genGlassReport(Request $request) {
$data = [];
$bulan = $request->input('bulan');
@@ -275,6 +275,34 @@ class TemplateController extends Controller
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Failed', 'message' => 'Unkown Error']);
return back();
}
} else if ($tabel == 'Speciment'){
if ($id == 'new'){
$ceksudah = Organisms::where('name', $request->name)->where('category', $request->category)->where('kelompok', $request->kelompok)->count();
if ($ceksudah == 0){
$data = new Organisms;
$inputData = $request->except(['id', 'tabel', '_token']);
$data->fill($inputData);
$data->save();
} else {
$pesan = $request->name.' ('.$request->category.') Sudah ada, Mohon ubah Data sebelum simpan kembali';
}
} else {
$ceksudah = Organisms::where('id', '!=', $id)->where('name', $request->name)->where('category', $request->category)->where('kelompok', $request->kelompok)->count();
if ($ceksudah == 0){
$data = Organisms::find($id);
$inputData = $request->except(['id', 'tabel', '_token']);
$data->update($inputData);
} else {
$pesan = $request->name.' ('.$request->category.') Sudah ada, Mohon ubah Data sebelum simpan kembali';
}
}
if ($data){
return response()->json(['icon' => 'success', 'warna' => '#5ba035', 'status' => 'Success', 'message' => 'Saved']);
return back();
} else {
return response()->json(['icon' => 'error', 'warna' => '#bf441d', 'status' => 'Failed', 'message' => 'Unkown Error']);
return back();
}
} else if ($tabel == 'Parameter'){
$getdatalama = Organisms::where('kelompok', $request->kelompok)->first();
$category = $getdatalama->category ?? $request->kelompok;
@@ -24,8 +24,8 @@ class RouteServiceProvider extends ServiceProvider
*/
public function boot(): void
{
resolve(\Illuminate\Routing\UrlGenerator::class)->forceScheme('https');
parent::boot();
//resolve(\Illuminate\Routing\UrlGenerator::class)->forceScheme('https');
//parent::boot();
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
+15
View File
@@ -0,0 +1,15 @@
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ResultOnListiner extends Model
{
protected $connection = 'mysqllistener';
protected $primaryKey = "urut";
protected $table = "lis_phoenix";
public $timestamps = false;
protected $guarded = [];
}
+67 -97
View File
@@ -231,110 +231,80 @@ class AstmMessageService
return response()->json(['message' => 'Data berhasil diproses dan disimpan.']);
} else {
if (!empty($mltrData)){
Log::info("Trying parser MTRSL :", $mltrData);
$parsedData = [];
$parsedData['antibiotics'] = [];
$antibiotic = '';
$resistance = '';
$value = '';
$interpretation = '';
$mulaikirim = 0;
$resultSample = new ResultSample();
foreach ($mltrData as $index => $field) {
if ($field == 'ra'){
if ($antibiotic != ''){
$parsedData['antibiotics'][] = [
'antibiotic' => $antibiotic, // Antibiotik
'resistance' => $resistance, // Hasil Resistansi
'value' => $value, // Nilai
'interpretation'=> $interpretation // Interpretasi
];
$antibiotic = '';
$resistance = '';
$value = '';
$interpretation = '';
} else {
$mulaikirim = 1;
}
} else {
if ($mulaikirim == 1){
$antibiotic = substr($field, 2);
$mulaikirim++;
} else if ($mulaikirim == 2){
$resistance = substr($field, 2);
$mulaikirim++;
} else if ($mulaikirim == 3){
$value = substr($field, 2);
$mulaikirim++;
} else if ($mulaikirim == 4){
$interpretation = substr($field, 2);
$mulaikirim++;
} else {
$field = substr($field, 2);
switch ($index) {
case 0:
$resultSample->sender_name = $alat;
break;
case 1:
$resultSample->version_number = $field; // iiV2
break;
case 2:
$resultSample->isolate_number = $field; // is000015F278BD
break;
case 4:
$resultSample->patient_id = $field; // pi12009427
break;
case 5:
$patientNames = explode(',', $field ?? null);
if (count($patientNames) > 0) {
$resultSample->patient_name_last = trim($patientNames[0]); // Last name
}
if (count($patientNames) > 1) {
$resultSample->patient_name_first = trim($patientNames[1]); // First name
}
if (count($patientNames) > 2) {
$resultSample->patient_name_middle = trim($patientNames[2]); // Middle name
}
break;
case 6:
$resultSample->address_street = $field; // plMANINJAU
break;
case 12:
try {
$resultSample->message_datetime = Carbon::parse($field)->format('Y-m-d') ?? null;
}catch (Exception $e) {
$resultSample->message_datetime = date('Y-m-d');
}
break;
case 13:
try {
$resultSample->test_complete_datetime = Carbon::parse($field)->format('Y-m-d') ?? null;
}catch (Exception $e) {
$resultSample->test_complete_datetime = date('Y-m-d');
}
break;
case 14:
$resultSample->accession_number = substr($field, 6); // ci30112024.26859
break;
case 23:
$resultSample->organism = $field; // o2Staphylococcus haemolyticus
break;
if (!empty($mltrData)) {
Log::info("Trying robust parser for MTRSL:", $mltrData);
$resultSample = new ResultSample();
$antibioticResults = [];
$currentAntibiotic = [];
foreach ($mltrData as $field) {
if (strlen($field) < 2) continue; // Lewati field kosong
// 1. Identifikasi TAG dan VALUE dari setiap field
$tag = substr($field, 0, 2);
$value = substr($field, 2);
// 2. Gunakan SWITCH pada TAG, bukan pada INDEX
switch ($tag) {
// == Data Pasien & Sampel ==
case 'pi': $resultSample->patient_id = $value; break;
case 'pn':
$patientNames = explode(',', $value ?? null);
$resultSample->patient_name_last = trim($patientNames[0] ?? '');
$resultSample->patient_name_first = trim($patientNames[1] ?? '');
$resultSample->patient_name_middle = trim($patientNames[2] ?? '');
break;
case 'pl': $resultSample->address_street = $value; break;
case 'ci': $resultSample->accession_number = substr($value, 6); break;
case 'o2': $resultSample->organism = $value; break;
// Tanggal bisa memiliki tag s1, s3, dll. Sesuaikan jika perlu
case 's3':
try {
// Contoh parsing tanggal dari format Vitek: 08/25/2025
$resultSample->test_complete_datetime = Carbon::createFromFormat('m/d/Y', $value)->format('Y-m-d H:i:s');
} catch (Exception $e) {
$resultSample->test_complete_datetime = now();
}
}
break;
// == Logika Cerdas untuk Blok Antibiotik ==
case 'ra':
// 'ra' adalah sinyal bahwa blok antibiotik SEBELUMNYA sudah selesai.
// Jika $currentAntibiotic tidak kosong, simpan ke hasil utama.
if (!empty($currentAntibiotic)) {
$antibioticResults[] = $currentAntibiotic;
}
// Reset untuk menampung data antibiotik yang baru.
$currentAntibiotic = [];
break;
case 'a1': $currentAntibiotic['antibiotic'] = $value; break; // Kode Antibiotik
case 'a2': $currentAntibiotic['resistance'] = $value; break; // Nama Antibiotik
case 'a3': $currentAntibiotic['value'] = $value; break; // Nilai MIC
case 'a4': $currentAntibiotic['interpretation'] = $value; break; // Interpretasi
case 'an':
// Jika 'an' ada, ini adalah interpretasi final, timpa yang sebelumnya.
$currentAntibiotic['interpretation'] = $value;
break;
// == Metadata Lainnya (opsional) ==
case 'ii': $resultSample->version_number = $value; break;
case 'is': $resultSample->isolate_number = $value; break;
}
}
//$resultSample->specimen_type = $parsedData['specimen_type'] ?? null; // Could be inferred
//$resultSample->test_id = $parsedData['test_id'] ?? null;
// Result Record
$resultSample->additional_result = json_encode($parsedData['antibiotics']);
// Penting: Simpan blok antibiotik TERAKHIR setelah loop selesai
if (!empty($currentAntibiotic)) {
$antibioticResults[] = $currentAntibiotic;
}
$resultSample->sender_name = $alat ?? 'VITEK'; // Pastikan var $alat ada
$resultSample->additional_result = json_encode($antibioticResults);
// Menyimpan data yang sudah diparse
$resultSample->save();
Log::info("Data MTRL Berhasil di Parse dan di simpan ", $resultSample->toArray());
Log::info("Data MTRSL successfully parsed and saved.", $resultSample->toArray());
return response()->json(['message' => 'Data berhasil diproses dan disimpan.']);
} else {
$headerData = explode("|", $response);
@@ -50,7 +50,7 @@ return new class extends Migration
$table->string('nmanalis', 250)->nullable();
$table->string('nmexcutor', 250)->nullable();
$table->string('klinisi', 250)->nullable();
$table->string('klinis', 250)->nullable();
$table->mediumText('klinis')->nullable();
$table->integer('poli_id')->nullable();
$table->text('keterangan')->nullable();
$table->text('kesimpulan')->nullable();
@@ -89,6 +89,7 @@ return new class extends Migration
$table->integer('bhp_antibiotiktambahan')->nullable();
$table->string('id_esbl', 5)->nullable();
$table->string('id_mrsa', 5)->nullable();
$table->integer('rating')->nullable();
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent();
});
@@ -11,13 +11,15 @@ return new class extends Migration
*/
public function up(): void
{
Schema::create('samples', function (Blueprint $table) {
$table->id();
$table->string('patient_name', 250)->nullable();
$table->string('test_details', 255)->nullable();
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent();
});
if (!Schema::hasTable('samples')) {
Schema::create('samples', function (Blueprint $table) {
$table->id();
$table->string('patient_name', 250)->nullable();
$table->string('test_details', 255)->nullable();
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent();
});
}
}
/**
@@ -11,16 +11,18 @@ return new class extends Migration
*/
public function up(): void
{
Schema::create('test_results', function (Blueprint $table) {
$table->id(); // ID primary key
$table->unsignedBigInteger('sample_id'); // Kolom referensi
$table->text('result'); // Kolom result
$table->string('status', 50); // Kolom status
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent();
// Foreign key
$table->foreign('sample_id')->references('id')->on('samples')->onDelete('cascade');
});
if (!Schema::hasTable('test_results')) {
Schema::create('test_results', function (Blueprint $table) {
$table->id(); // ID primary key
$table->unsignedBigInteger('sample_id'); // Kolom referensi
$table->text('result'); // Kolom result
$table->string('status', 50); // Kolom status
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent();
// Foreign key
$table->foreign('sample_id')->references('id')->on('samples')->onDelete('cascade');
});
}
}
/**
+1 -2
View File
@@ -13,8 +13,7 @@ class DatabaseSeeder extends Seeder
*/
public function run(): void
{
User::factory(10)->create();
User::factory()->create([
User::create([
'nama' => 'Administrator',
'username' => 'admin',
'password' => bcrypt('semangat'),
+14
View File
@@ -0,0 +1,14 @@
#!/bin/bash
# Cek apakah migration sudah pernah dijalankan
if php artisan migrate:status | grep -q "| Y"; then
echo "Database already migrated, skipping migration and seeding."
else
echo "Running migrations and seeders..."
php artisan migrate --force
php artisan db:seed --force
fi
# Jalankan Laravel server
exec php artisan serve --host=0.0.0.0 --port=8080
+14
View File
@@ -0,0 +1,14 @@
FROM python:3.11-slim
WORKDIR /app
COPY . /app
RUN pip install --no-cache-dir -r requirements.txt
RUN apt-get update && apt-get install -y \
net-tools \
iproute2 \
procps \
lsof \
&& rm -rf /var/lib/apt/lists/*
CMD ["python", "app.py"]
+18 -3
View File
@@ -6,7 +6,9 @@ from flask import Flask, request, jsonify
from sqlalchemy import create_engine, Column, Integer, String, Text, ForeignKey, DateTime
from sqlalchemy.orm import declarative_base, sessionmaker
import datetime
import time
import traceback
from sqlalchemy.exc import OperationalError
# Konfigurasi logging
logging.basicConfig(
filename='listener.log',
@@ -18,9 +20,21 @@ logging.basicConfig(
app = Flask(__name__)
# Konfigurasi Database dengan SQLAlchemy
DATABASE_URL = "postgresql://lismikro:lismikro@localhost:5432/lismikro"
DATABASE_URL = "postgresql://lismikro:guR8uchQhQFAGi4yXfHPrF2AHTgN15sOViDL7tu0bfoiPmdI@postgresql:5432/lismikro"
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(bind=engine)
for i in range(10):
try:
engine = create_engine(DATABASE_URL)
connection = engine.connect()
connection.close()
print("Database connected successfully.")
break
except OperationalError as e:
print(f"Database not ready yet ({i+1}/10): {e}")
time.sleep(5)
else:
raise Exception("Database not available after 10 attempts")
Base = declarative_base()
# Model Database
@@ -63,6 +77,7 @@ def process_and_save_to_db(hl7_message):
logging.info("Data successfully saved to the database.")
except Exception as e:
logging.error(f"Error processing and saving data: {e}")
logging.error(traceback.format_exc())
raise
def is_astm_format(data):
# ASTM biasanya menggunakan karakter STX (\x02) sebagai awal dan ETX (\x03) sebagai akhir
@@ -172,6 +187,6 @@ if __name__ == "__main__":
threading.Thread(target=listen_on_port, args=(6001,), daemon=True).start()
# Jalankan Flask untuk menerima HTTP POST
app.run(host='10.10.123.218', port=5000, debug=True)
app.run(host='0.0.0.0', port=5000, debug=True)
except KeyboardInterrupt:
logging.info("Application stopped by user.")
+223
View File
@@ -1548,3 +1548,226 @@ OBR|||1|TEST123^Exa
2025-01-24 08:15:54,435 - INFO - Data is not in HL7 or ASTM format, skipping.
2025-01-24 11:47:47,313 - INFO - New connection from ('10.10.120.13', 54104)
2025-01-24 11:47:47,313 - INFO - Handling client from ('10.10.120.13', 54104)
2025-07-17 00:18:48,302 - INFO - Listening on TCP port 6001...
2025-07-17 00:18:50,828 - INFO - Listening on TCP port 6001...
2025-07-17 00:18:52,964 - INFO - Listening on TCP port 6001...
2025-07-17 00:18:55,171 - INFO - Listening on TCP port 6001...
2025-07-17 00:18:58,412 - INFO - Listening on TCP port 6001...
2025-07-17 00:19:03,971 - INFO - Listening on TCP port 6001...
2025-07-17 00:19:12,311 - INFO - Listening on TCP port 6001...
2025-07-17 00:19:27,600 - INFO - Listening on TCP port 6001...
2025-07-17 00:20:10,491 - INFO - Listening on TCP port 6001...
2025-07-17 00:20:13,968 - INFO - Listening on TCP port 6001...
2025-07-17 00:20:17,049 - INFO - Listening on TCP port 6001...
2025-07-17 00:20:20,457 - INFO - Listening on TCP port 6001...
2025-07-17 00:20:23,453 - INFO - Listening on TCP port 6001...
2025-07-17 00:20:26,802 - INFO - Listening on TCP port 6001...
2025-07-17 00:20:31,975 - INFO - Listening on TCP port 6001...
2025-07-17 00:20:40,787 - INFO - Listening on TCP port 6001...
2025-07-17 00:20:56,867 - INFO - Listening on TCP port 6001...
2025-07-17 00:21:25,278 - INFO - Listening on TCP port 6001...
2025-07-17 00:22:20,552 - INFO - Listening on TCP port 6001...
2025-07-17 00:23:23,402 - INFO - Listening on TCP port 6001...
2025-07-17 00:24:26,166 - INFO - Listening on TCP port 6001...
2025-07-17 00:25:28,435 - INFO - Listening on TCP port 6001...
2025-07-17 00:26:30,664 - INFO - Listening on TCP port 6001...
2025-07-17 00:26:30,699 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://172.18.0.4:5000
2025-07-17 00:26:30,700 - INFO - Press CTRL+C to quit
2025-07-17 00:26:30,704 - INFO - * Restarting with stat
2025-07-17 00:26:32,625 - ERROR - Failed to bind to port 6001: [Errno 98] Address already in use
2025-07-17 00:26:32,654 - WARNING - * Debugger is active!
2025-07-17 00:26:32,657 - INFO - * Debugger PIN: 951-713-775
2025-07-17 00:27:38,154 - INFO - Listening on TCP port 6001...
2025-07-17 00:27:38,357 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://172.18.0.4:5000
2025-07-17 00:27:38,358 - INFO - Press CTRL+C to quit
2025-07-17 00:27:38,360 - INFO - * Restarting with stat
2025-07-17 00:27:40,799 - ERROR - Failed to bind to port 6001: [Errno 98] Address already in use
2025-07-17 00:27:40,825 - WARNING - * Debugger is active!
2025-07-17 00:27:40,826 - INFO - * Debugger PIN: 139-464-079
2025-07-17 00:57:38,623 - INFO - Listening on TCP port 6001...
2025-07-17 00:57:38,798 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://172.18.0.4:5000
2025-07-17 00:57:38,798 - INFO - Press CTRL+C to quit
2025-07-17 00:57:38,799 - INFO - * Restarting with stat
2025-07-17 00:57:42,059 - ERROR - Failed to bind to port 6001: [Errno 98] Address already in use
2025-07-17 00:57:42,102 - WARNING - * Debugger is active!
2025-07-17 00:57:42,111 - INFO - * Debugger PIN: 682-061-109
2025-07-17 01:07:55,681 - INFO - Listening on TCP port 6001...
2025-07-17 01:07:56,048 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://172.18.0.3:5000
2025-07-17 01:07:56,048 - INFO - Press CTRL+C to quit
2025-07-17 01:07:56,050 - INFO - * Restarting with stat
2025-07-17 01:08:00,741 - ERROR - Failed to bind to port 6001: [Errno 98] Address already in use
2025-07-17 01:08:00,765 - WARNING - * Debugger is active!
2025-07-17 01:08:00,767 - INFO - * Debugger PIN: 455-916-409
2025-07-17 01:10:05,931 - INFO - Listening on TCP port 6001...
2025-07-17 01:10:06,006 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://172.18.0.3:5000
2025-07-17 01:10:06,007 - INFO - Press CTRL+C to quit
2025-07-17 01:10:06,008 - INFO - * Restarting with stat
2025-07-17 01:10:10,441 - ERROR - Failed to bind to port 6001: [Errno 98] Address already in use
2025-07-17 01:10:10,464 - WARNING - * Debugger is active!
2025-07-17 01:10:10,465 - INFO - * Debugger PIN: 195-044-760
2025-07-17 01:11:48,115 - INFO - Listening on TCP port 6001...
2025-07-17 01:11:48,313 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://172.18.0.3:5000
2025-07-17 01:11:48,314 - INFO - Press CTRL+C to quit
2025-07-17 01:11:48,316 - INFO - * Restarting with stat
2025-07-17 01:11:53,049 - ERROR - Failed to bind to port 6001: [Errno 98] Address already in use
2025-07-17 01:11:53,099 - WARNING - * Debugger is active!
2025-07-17 01:11:53,100 - INFO - * Debugger PIN: 804-449-067
2025-07-17 01:21:30,786 - INFO - Listening on TCP port 6001...
2025-07-17 01:21:31,276 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://172.18.0.3:5000
2025-07-17 01:21:31,277 - INFO - Press CTRL+C to quit
2025-07-17 01:21:31,278 - INFO - * Restarting with stat
2025-07-17 01:24:26,800 - INFO - Listening on TCP port 6001...
2025-07-17 01:24:27,334 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://172.18.0.4:5000
2025-07-17 01:24:27,373 - INFO - Press CTRL+C to quit
2025-07-17 01:24:27,375 - INFO - * Restarting with stat
2025-07-17 01:24:33,347 - ERROR - Failed to bind to port 6001: [Errno 98] Address already in use
2025-07-17 01:24:33,371 - WARNING - * Debugger is active!
2025-07-17 01:24:33,616 - INFO - * Debugger PIN: 631-229-636
2025-07-17 01:31:34,776 - INFO - Listening on TCP port 6001...
2025-07-17 01:31:35,467 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://172.18.0.4:5000
2025-07-17 01:31:35,468 - INFO - Press CTRL+C to quit
2025-07-17 01:31:35,470 - INFO - * Restarting with stat
2025-07-17 01:31:44,028 - ERROR - Failed to bind to port 6001: [Errno 98] Address already in use
2025-07-17 01:31:44,108 - WARNING - * Debugger is active!
2025-07-17 01:31:44,110 - INFO - * Debugger PIN: 135-554-149
2025-07-31 03:54:40,581 - INFO - Listening on TCP port 6001...
2025-07-31 03:54:40,647 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://172.18.0.3:5000
2025-07-31 03:54:40,647 - INFO - Press CTRL+C to quit
2025-07-31 03:54:40,648 - INFO - * Restarting with stat
2025-07-31 03:54:41,259 - ERROR - Failed to bind to port 6001: [Errno 98] Address already in use
2025-07-31 03:54:41,273 - WARNING - * Debugger is active!
2025-07-31 03:54:41,276 - INFO - * Debugger PIN: 128-029-017
2025-07-31 03:55:15,330 - INFO - Listening on TCP port 6001...
2025-07-31 03:55:15,351 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://172.18.0.3:5000
2025-07-31 03:55:15,352 - INFO - Press CTRL+C to quit
2025-07-31 03:55:15,354 - INFO - * Restarting with stat
2025-07-31 03:55:15,830 - ERROR - Failed to bind to port 6001: [Errno 98] Address already in use
2025-07-31 03:55:15,848 - WARNING - * Debugger is active!
2025-07-31 03:55:15,849 - INFO - * Debugger PIN: 117-557-421
2025-07-31 03:58:14,623 - INFO - Listening on TCP port 6001...
2025-07-31 03:58:14,684 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://172.18.0.4:5000
2025-07-31 03:58:14,685 - INFO - Press CTRL+C to quit
2025-07-31 03:58:14,686 - INFO - * Restarting with stat
2025-07-31 03:58:15,367 - ERROR - Failed to bind to port 6001: [Errno 98] Address already in use
2025-07-31 03:58:15,390 - WARNING - * Debugger is active!
2025-07-31 03:58:15,392 - INFO - * Debugger PIN: 454-857-589
2025-07-31 04:26:26,758 - INFO - Processing HL7 message: MSH|^~\&|SendingApp|SendingFac|ReceivingApp|ReceivingFac|20231130120000||ORU^R01|MSGID1234|P|2.3
PID|||12345||John^Doe||19800101|M
OBR|||1|TEST123^Example Test
OBX|||POSITIVE
2025-07-31 04:26:26,789 - INFO - Data successfully saved to the database.
2025-07-31 04:26:26,790 - INFO - 192.168.65.1 - - [31/Jul/2025 04:26:26] "POST /listener HTTP/1.1" 201 -
2025-07-31 04:26:44,980 - INFO - New connection from ('192.168.65.1', 45962)
2025-07-31 04:26:44,981 - INFO - Handling client from ('192.168.65.1', 45962)
2025-07-31 04:26:44,982 - INFO - Raw binary data saved: 504f5354202f6c697374656e657220485454502f312e310d0a486f73743a206c6f63616c686f73743a363030310d0a557365722d4167656e743a206375726c2f382e372e310d0a4163636570743a202a2f2a0d0a436f6e74656e742d547970653a20746578742f706c61696e0d0a436f6e74656e742d4c656e6774683a203137350d0a0d0a4d53487c5e7e5c267c53656e64696e674170707c53656e64696e674661637c526563656976696e674170707c526563656976696e674661637c32303233313133303132303030307c7c4f52555e5230317c4d53474944313233347c507c322e330a5049447c7c7c31323334357c7c4a6f686e5e446f657c7c31393830303130317c4d0a4f42527c7c7c317c544553543132335e4578616d706c6520546573740a4f42587c7c7c504f5349544956450a
2025-07-31 04:26:44,983 - INFO - Data is not in HL7 or ASTM format, skipping.
2025-07-31 04:26:44,984 - INFO - Connection closed by client ('192.168.65.1', 45962)
2025-07-31 04:27:48,808 - INFO - New connection from ('192.168.65.1', 28125)
2025-07-31 04:27:48,809 - INFO - Handling client from ('192.168.65.1', 28125)
2025-07-31 04:27:56,578 - INFO - Raw binary data saved: 4d53487c5e7e5c267c53656e64696e674170707c53656e64696e674661637c526563656976696e674170707c526563656976696e674661637c32303233313133303132303030307c7c4f52555e5230317c4d53474944313233347c507c322e330a
2025-07-31 04:27:56,579 - INFO - Received HL7 message: MSH|^~\&|SendingApp|SendingFac|ReceivingApp|ReceivingFac|20231130120000||ORU^R01|MSGID1234|P|2.3
2025-07-31 04:27:56,583 - INFO - Processing HL7 message: MSH|^~\&|SendingApp|SendingFac|ReceivingApp|ReceivingFac|20231130120000||ORU^R01|MSGID1234|P|2.3
2025-07-31 04:27:56,633 - INFO - Data successfully saved to the database.
2025-07-31 04:27:56,635 - INFO - Raw binary data saved: 5049447c7c7c31323334357c7c4a6f686e5e446f657c7c31393830303130317c4d0a4f42527c7c7c317c544553543132335e4578616d706c6520546573740a
2025-07-31 04:27:56,636 - INFO - Received HL7 message: PID|||12345||John^Doe||19800101|M
OBR|||1|TEST123^Example Test
2025-07-31 04:27:56,636 - INFO - Processing HL7 message: PID|||12345||John^Doe||19800101|M
OBR|||1|TEST123^Example Test
2025-07-31 04:27:56,636 - ERROR - Error processing and saving data: First segment is PID, must be one of MHS, FHS or BHS
2025-07-31 04:27:56,636 - ERROR - Error processing data: First segment is PID, must be one of MHS, FHS or BHS
2025-07-31 04:29:51,996 - INFO - * Detected change in '/app/app.py', reloading
2025-07-31 04:29:52,204 - INFO - * Restarting with stat
2025-07-31 04:29:52,966 - ERROR - Failed to bind to port 6001: [Errno 98] Address already in use
2025-07-31 04:29:52,985 - WARNING - * Debugger is active!
2025-07-31 04:29:52,986 - INFO - * Debugger PIN: 454-857-589
2025-07-31 04:29:54,122 - INFO - Connection closed by client ('192.168.65.1', 28125)
2025-07-31 04:30:20,134 - INFO - Listening on TCP port 6001...
2025-07-31 04:30:20,207 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://172.18.0.4:5000
2025-07-31 04:30:20,207 - INFO - Press CTRL+C to quit
2025-07-31 04:30:20,209 - INFO - * Restarting with stat
2025-07-31 04:30:21,252 - ERROR - Failed to bind to port 6001: [Errno 98] Address already in use
2025-07-31 04:30:21,273 - WARNING - * Debugger is active!
2025-07-31 04:30:21,274 - INFO - * Debugger PIN: 919-933-610
2025-07-31 04:32:50,618 - INFO - New connection from ('192.168.65.1', 59039)
2025-07-31 04:32:50,619 - INFO - Handling client from ('192.168.65.1', 59039)
2025-07-31 04:33:10,684 - INFO - Raw binary data saved: 4d53487c5e7e5c267c53656e64696e674170707c53656e64696e674661637c526563656976696e674170707c526563656976696e674661637c32303233313133303132303030307c7c4f52555e5230317c4d53474944313233347c507c322e330a
2025-07-31 04:33:10,685 - INFO - Received HL7 message: MSH|^~\&|SendingApp|SendingFac|ReceivingApp|ReceivingFac|20231130120000||ORU^R01|MSGID1234|P|2.3
2025-07-31 04:33:10,688 - INFO - Processing HL7 message: MSH|^~\&|SendingApp|SendingFac|ReceivingApp|ReceivingFac|20231130120000||ORU^R01|MSGID1234|P|2.3
2025-07-31 04:33:10,736 - INFO - Data successfully saved to the database.
2025-07-31 04:33:10,737 - INFO - Raw binary data saved: 5049447c7c7c31323334357c7c4a6f686e5e446f657c7c31393830303130317c4d0a4f42527c7c7c317c544553543132335e4578616d706c6520546573740a4f42587c7c7c504f5349544956450a
2025-07-31 04:33:10,738 - INFO - Received HL7 message: PID|||12345||John^Doe||19800101|M
OBR|||1|TEST123^Example Test
OBX|||POSITIVE
2025-07-31 04:33:10,738 - INFO - Processing HL7 message: PID|||12345||John^Doe||19800101|M
OBR|||1|TEST123^Example Test
OBX|||POSITIVE
2025-07-31 04:33:10,738 - ERROR - Error processing and saving data: First segment is PID, must be one of MHS, FHS or BHS
2025-07-31 04:33:10,740 - ERROR - Traceback (most recent call last):
File "/app/app.py", line 66, in process_and_save_to_db
message = hl7.parse(hl7_message)
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/hl7/parser.py", line 98, in parse
plan = create_parse_plan(strmsg, factory)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/hl7/parser.py", line 348, in create_parse_plan
raise ParseException(
hl7.exceptions.ParseException: First segment is PID, must be one of MHS, FHS or BHS
2025-07-31 04:33:10,741 - ERROR - Error processing data: First segment is PID, must be one of MHS, FHS or BHS
2025-07-31 04:33:11,645 - INFO - Raw binary data saved: 0a
2025-07-31 04:33:11,645 - INFO - Data is not in HL7 or ASTM format, skipping.
2025-07-31 04:33:20,965 - INFO - Raw binary data saved: 4d53487c5e7e5c267c53656e64696e674170707c53656e64696e674661637c526563656976696e674170707c526563656976696e674661637c32303233313133303132303030307c7c4f52555e5230317c4d53474944313233347c507c322e335049447c7c7c31323334357c7c4a6f686e5e446f657c7c31393830303130317c4d4f42527c7c7c317c544553543132335e4578616d706c6520546573744f42587c7c7c504f5349544956450a
2025-07-31 04:33:20,965 - INFO - Received HL7 message: MSH|^~\&|SendingApp|SendingFac|ReceivingApp|ReceivingFac|20231130120000||ORU^R01|MSGID1234|P|2.3PID|||12345||John^Doe||19800101|MOBR|||1|TEST123^Example TestOBX|||POSITIVE
2025-07-31 04:33:20,965 - INFO - Processing HL7 message: MSH|^~\&|SendingApp|SendingFac|ReceivingApp|ReceivingFac|20231130120000||ORU^R01|MSGID1234|P|2.3PID|||12345||John^Doe||19800101|MOBR|||1|TEST123^Example TestOBX|||POSITIVE
2025-07-31 04:33:20,972 - INFO - Data successfully saved to the database.
2025-07-31 04:35:43,445 - INFO - Connection closed by client ('192.168.65.1', 59039)
+4
View File
@@ -0,0 +1,4 @@
flask
sqlalchemy
hl7
psycopg2-binary
+20 -1
View File
@@ -6,4 +6,23 @@ MSH|^~\&|SendingApp|SendingFac|...
MSH|^~\&|SendingApp|SendingFac|...
MSH|^~\&|SendingApp|SendingFac|...
MSH|^~\&|SendingApp|SendingFac|...

POST /listener HTTP/1.1
Host: localhost:6001
User-Agent: curl/8.7.1
Accept: */*
Content-Type: text/plain
Content-Length: 175
MSH|^~\&|SendingApp|SendingFac|ReceivingApp|ReceivingFac|20231130120000||ORU^R01|MSGID1234|P|2.3
PID|||12345||John^Doe||19800101|M
OBR|||1|TEST123^Example Test
OBX|||POSITIVE
MSH|^~\&|SendingApp|SendingFac|ReceivingApp|ReceivingFac|20231130120000||ORU^R01|MSGID1234|P|2.3
PID|||12345||John^Doe||19800101|M
OBR|||1|TEST123^Example Test
MSH|^~\&|SendingApp|SendingFac|ReceivingApp|ReceivingFac|20231130120000||ORU^R01|MSGID1234|P|2.3
PID|||12345||John^Doe||19800101|M
OBR|||1|TEST123^Example Test
OBX|||POSITIVE
MSH|^~\&|SendingApp|SendingFac|ReceivingApp|ReceivingFac|20231130120000||ORU^R01|MSGID1234|P|2.3PID|||12345||John^Doe||19800101|MOBR|||1|TEST123^Example TestOBX|||POSITIVE
+128 -9
View File
@@ -208,6 +208,57 @@
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div>
<div id="ModalSpecimen" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Editor Data Specimen</h4>
</div>
<div class="modal-body">
<form class="form-horizontal">
<div class="form-group m-b-25">
<div class="col-12">
<label>Name</label>
<input type="text" class="form-control" id="sp_name">
</div>
</div>
<div class="form-group m-b-25">
<div class="col-12">
<label>Category Name</label>
<input type="text" class="form-control" id="sp_kategori">
</div>
</div>
<div class="form-group">
<label>Target Selesai</label>
<div class="form-group m-b-25">
<div class="col-6">
<label>Satuan</label>
<select class="form-control" id="sp_satuan" name="sp_satuan">
<option value="Jam">Jam</option>
<option value="Hari">Hari</option>
<option value="Minggu">Minggu</option>
<option value="Bulan">Bulan</option>
</select>
</div>
<div class="col-6">
<label>Nilai</label>
<input type="number" class="form-control" id="sp_nilai" placeholder="Hanya Angka">
</div>
</div>
</div>
<div class="form-group account-btn text-center m-t-10">
<div class="col-12">
<input type="hidden" class="form-control" id="sp_id">
<input type="hidden" class="form-control" id="sp_kelompok">
<button class="btn w-lg btn-custom waves-effect waves-light" id="btnAddSP" type="button">Save</button>
</div>
</div>
</form>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div>
<input type="hidden" name="_token" id="token" value="{{ csrf_token() }}">
<div style="overflow: hidden; display: none;">
<div class="form-group m-b-25">
@@ -500,6 +551,8 @@
{ name: 'name',type: 'text'},
{ name: 'category',type: 'text'},
{ name: 'kelompok',type: 'text'},
{ name: 'nilai',type: 'text'},
{ name: 'satuan',type: 'text'},
],
type: 'POST',
data: { val01:'listkodespesimen', _token: token },
@@ -524,15 +577,19 @@
editrowpoli = row;
var offset = $("#gridbakteri").offset();
var dataRecord = $("#gridbakteri").jqxGrid('getrowdata', editrowpoli);
$("#mb_id").val(dataRecord.id);
$("#mb_kelompok").val(dataRecord.kelompok);
$("#mb_kategori").val(dataRecord.category);
$("#mb_name").val(dataRecord.name);
$('#ModalMikroandBakteri').modal('show');
$("#sp_id").val(dataRecord.id);
$("#sp_kelompok").val(dataRecord.kelompok);
$("#sp_kategori").val(dataRecord.category);
$("#sp_name").val(dataRecord.name);
$("#sp_nilai").val(dataRecord.nilai);
$("#sp_satuan").val(dataRecord.satuan);
$('#ModalSpecimen').modal('show');
}
},
{ text: 'Name', datafield: 'name', width: '60%', cellsalign: 'left', align: 'center' },
{ text: 'Name', datafield: 'name', width: '40%', cellsalign: 'left', align: 'center' },
{ text: 'Category', datafield: 'category', width: '20%', cellsalign: 'left', align: 'center' },
{ text: 'Satuan', datafield: 'satuan', width: '10%', cellsalign: 'left', align: 'center' },
{ text: 'Nilai', datafield: 'nilai', width: '10%', cellsalign: 'center', align: 'center' },
{ text: 'Delete', editable: false, sortable: false, filterable: false, columntype: 'button', width: '10%', cellsrenderer: function () {
return "Delete";
}, buttonclick: function (row) {
@@ -730,9 +787,9 @@
]
});
$("#btnaddModalSpecimen").click(function() {
$("#mb_id").val('new');
$("#mb_kelompok").val('listkodespesimen');
$('#ModalMikroandBakteri').modal('show');
$("#sp_id").val('new');
$("#sp_kelompok").val('listkodespesimen');
$('#ModalSpecimen').modal('show');
});
$("#btnAddMB").click(function(){
var set01 = document.getElementById('mb_name').value;
@@ -791,6 +848,68 @@
});
}
});
$("#btnAddSP").click(function(){
var set01 = document.getElementById('sp_name').value;
var set02 = document.getElementById('sp_kategori').value;
var set03 = document.getElementById('sp_kelompok').value;
var set04 = document.getElementById('sp_id').value;
var set05 = document.getElementById('sp_satuan').value;
var set06 = document.getElementById('sp_nilai').value;
if (set01 == '' || set02 == '' || set03 == '' || set04 == '' || set05 == '' || set06 == ''){
swal({
title : 'Mohon diLengkapi',
text : 'Data Dasar Wajib di Isi',
type : 'warning',
});
} else {
$('#ModalSpecimen').modal('hide');
var form_data = new FormData();
form_data.append('name', set01);
form_data.append('category', set02);
form_data.append('kelompok', set03);
form_data.append('id', set04);
form_data.append('satuan', set05);
form_data.append('nilai', set06);
form_data.append('tabel', 'Speciment');
form_data.append('_token', '{{csrf_token()}}');
$.ajax({
url : '{{ route("exSIRAb") }}',
data : form_data,
type : 'POST',
contentType : false,
processData : false,
success : function (data) {
var status = data.status;
var message = data.message;
var icon = data.icon;
var warna = data.warna;
$("html, body").animate({ scrollTop: 0 }, "slow");
$.toast({
heading : status,
text : message,
position : 'top-right',
loaderBg : warna,
icon : icon,
hideAfter : 3000,
stack : 1
});
$("#gridbakteri").jqxGrid('updatebounddata', 'filter');
$("#gridmikroorganisme").jqxGrid('updatebounddata', 'filter');
return false;
},
error : function (xhr, status, error) {
var response = xhr.responseJSON || {};
var traceText = response.trace ? JSON.stringify(response.trace) : null;
swal({
title : response,
text : traceText,
type : 'error',
})
}
});
}
});
$("#btnAddPoli").click(function(){
var poli = document.getElementById('add_poli').value;
var subpoli = document.getElementById('add_subpoli').value;
@@ -37,9 +37,9 @@
<th>bhp_antibiotiktambahan</th>
<th>id_esbl</th>
<th>id_mrsa</th>
@if(isset($jsonantibiotik) && !empty($jsonantibiotik))
@foreach($jsonantibiotik->first() as $antibiotic)
<th>{{ $antibiotic->antibiotic }}</th>
@if(isset($masterAntibioticList))
@foreach($masterAntibioticList as $antibioticName)
<th>{{ strtoupper($antibioticName) }}</th>
@endforeach
@endif
</tr>
@@ -72,12 +72,16 @@
<td>{{ $data->bhp_antibiotiktambahan}} </td>
<td>{{ $data->id_esbl}} </td>
<td>{{ $data->id_mrsa}} </td>
@if(isset($jsonantibiotik[$data->id]) && !empty($jsonantibiotik[$data->id]))
@foreach($jsonantibiotik[$data->id] as $antibiotic)
<td>{{ $antibiotic->interpretation }}</td>
@php
$patientResults = $jsonantibiotik->get($data->id);
@endphp
@if(isset($masterAntibioticList))
@foreach($masterAntibioticList as $antibioticName)
<td>
{{ $patientResults[$antibioticName] ?? '-' }}
</td>
@endforeach
@else
<td>&nbsp;</td>
@endif
</tr>
@endforeach
@@ -2069,6 +2069,7 @@
@push('script')
<script type="text/javascript">
var hakaksess = '{{ Session("previlage") }}';
function openlamanekpertise( jQuery ){
var dlp = document.getElementById('dlp').value;
var nofoto = document.getElementById('nofoto').value;
@@ -2662,18 +2663,10 @@
type : 'warning',
})
} else if (statuse == 'Selesai' || statuse == 'Arsip') {
if (hakaksess == 'supervisor'){
$('#divreadonly').hide();
$('#divperiksa').show();
$('#divawal').hide();
openlamanekpertise();
} else {
swal({
title : 'Ekspertise Final',
text : 'Hanya Akun SPV yang diperkenankan mengubah data Arsip',
type : 'warning',
})
}
$('#divreadonly').hide();
$('#divperiksa').show();
$('#divawal').hide();
openlamanekpertise();
} else {
$('#divreadonly').hide();
$('#divperiksa').show();
+6 -12
View File
@@ -2136,6 +2136,8 @@
@endsection
@push('script')
<script type="text/javascript">
var hakaksess = '{{ Session("previlage") }}';
function openlamanekpertise( jQuery ){
var dlp = document.getElementById('dlp').value;
var nofoto = document.getElementById('nofoto').value;
@@ -2729,18 +2731,10 @@
type : 'warning',
})
} else if (statuse == 'Selesai' || statuse == 'Arsip') {
if (hakaksess == 'supervisor'){
$('#divreadonly').hide();
$('#divperiksa').show();
$('#divawal').hide();
openlamanekpertise();
} else {
swal({
title : 'Ekspertise Final',
text : 'Hanya Akun SPV yang diperkenankan mengubah data Arsip',
type : 'warning',
})
}
$('#divreadonly').hide();
$('#divperiksa').show();
$('#divawal').hide();
openlamanekpertise();
} else {
$('#divreadonly').hide();
$('#divperiksa').show();
+21
View File
@@ -100,6 +100,27 @@
@push('script')
<script type="text/javascript">
function btnisiRating(id_periksa, rating_value){
var rating_container = $('.rating-stars[data-id="' + id_periksa + '"]');
$.post('{{ route("exCekAksess") }}', { nofoto: 'isirating',id: id_periksa, rating: rating_value, _token: '{{ csrf_token() }}' }, function(data){
rating_container.html('<small class="text-success">Terima kasih atas penilaian Anda!</small>');
var stars_html = '';
for (var i = 1; i <= 5; i++) {
if (i <= rating_value) {
stars_html += '<i class="fa fa-star" style="font-size:18px; color:orange;"></i>';
} else {
stars_html += '<i class="fa fa-star-o" style="font-size:18px; color:orange;"></i>';
}
}
rating_container.html('<small class="text-muted">Rating Anda:</small><br>' + stars_html);
}).fail(function() {
swal({
title : 'Warning',
text : 'Gagal mengirim rating. Silakan coba lagi.',
type : 'error',
});
});
}
$(document).ready(function() {
$("#tgllahir").datepicker({
format: 'yyyy-mm-dd'
+76 -98
View File
@@ -283,14 +283,12 @@
<button type="button" class="btn btn-success waves-effect waves-light pull-right" id="btnsimpan">Daftar</button>
</div>
</div>
<!--
<div class="form-group account-btn text-center m-t-10" id="divpembatalan">
<div class="col-12">
<input type="text" id="alasan" name="alasan" placeholder="Tulis Alasan Pembatalannya di Sini" class="form-control">
<button type="button" class="btn btn-success waves-effect waves-light pull-right" id="btnbatalkan">Batalkan</button>
</div>
<div class="form-group account-btn text-center m-t-10" id="divpembatalan">
<div class="col-12">
<input type="text" id="alasan" name="alasan" placeholder="Tulis Alasan Pembatalannya di Sini" class="form-control">
<button type="button" class="btn btn-success waves-effect waves-light pull-right" id="btnbatalkan">Batalkan</button>
</div>
-->
</div>
</div>
</div>
<div class="col-lg-12" id="modalawal">
@@ -590,68 +588,6 @@
// called when the Grid is loaded. Call methods or set properties here.
},
columns: [
/*
{ text: 'Barcode', filterable: false, columntype: 'button', align: 'center', width: 80, cellsrenderer: function () {
return "View";
}, buttonclick: function (row) {
editrow = row;
var offset = $("#gridpemeriksaan").offset();
var dataRecord = $("#gridpemeriksaan").jqxGrid('getrowdata', editrow);
$("#view_nama").val(dataRecord.nama);
$("#nofoto").val(dataRecord.nofoto);
$("#view_noregister").val(dataRecord.noregister);
$("#view_noloket").val(dataRecord.noloket);
$("#view_klinisi").val(dataRecord.klinisi);
$("#view_klinis").val(dataRecord.klinis);
$("#view_kd_spesimen").val(dataRecord.kd_spesimen);
$("#view_nm_spesimen").val(dataRecord.nm_spesimen);
var isidataString = dataRecord.modality;
var noloket = dataRecord.noloket;
var nofoto = dataRecord.nofoto;
var noregister = dataRecord.noregister;
var kd_spesimen = dataRecord.kd_spesimen;
var nama = dataRecord.nama;
var itemParts = nofoto.split('-');
var tahunpendek = itemParts[0].trim();
var daftar = dataRecord.daftar;
var arrmulai = daftar.split(' ');
var tangggal = arrmulai[0].trim();
var itemPartsThn = tangggal.split('-');
var tahun = itemPartsThn[0].trim();
var bulan = itemPartsThn.length > 1 ? itemPartsThn[1].trim() : "00";
var tanggal = itemPartsThn.length > 2 ? itemPartsThn[2].trim() : "00";
$("#view_tanggal").val(tangggal);
$("#view_tahun").val(tahunpendek);
var tableBody = $("#tableModality tbody");
tableBody.empty();
var isidataArray = JSON.parse(isidataString);
if (isidataArray && Array.isArray(isidataArray)) {
$("#view_modality").val(isidataArray).select2().trigger('change');
isidataArray.forEach(function (item, index) {
if (item == 'Vitek 1' || item == 'Vitek 2'){
var barcodeunik = tanggal+bulan+tahun+'-'+noloket;
} else if (item == 'BD Bachtect' || item == 'BD MGIT'){
var barcodeunik = tahunpendek+'-'+noloket;
} else if (item == 'abbotm2000' || item == 'abbotm2000rt'){
var barcodeunik = tahun+bulan+tanggal+'-'+noloket;
} else {
var barcodeunik = nofoto;
}
var row = `<tr>
<td>${index + 1}</td>
<td>${item}</td>
<td>${barcodeunik}</td>
<td><button class="btn btn-primary btn-sm" onClick="jQueryOpenBarCode('${item}<>${tahunpendek}<>${noloket}<>${tangggal}<>${nofoto}<>${noregister}<>${kd_spesimen}<>${nama}')">Print Barcode</button></td></tr>`;
tableBody.append(row);
});
} else {
$("#view_modality").val([]).select2().trigger('change');
}
$('#modalawal').removeClass('col-lg-12').addClass('col-lg-8');
$('#modalkirimkealat').show();
}
},
*/
{ text: 'Form', filterable: false, columntype: 'button', align: 'center', width: 50, cellsrenderer: function () {
return "Print";
}, buttonclick: function (row) {
@@ -680,17 +616,6 @@
});
}
},
{ text: 'Result', filterable: false, columntype: 'button', align: 'center', width: 50, cellsrenderer: function () {
return "Print";
}, buttonclick: function (row) {
editrowjabatan = row;
var offset = $("#gridpemeriksaan").offset();
var dataRecord = $("#gridpemeriksaan").jqxGrid('getrowdata', editrowjabatan);
var home = '{{URL::to("/")}}';
var alamat = home+'/hasil/'+dataRecord.nofoto;
window.open(alamat,'_blank');
}
},
{ text: 'Edit', filterable: false, columntype: 'button', align: 'center', width: 50, cellsrenderer: function () {
return "Edit";
}, buttonclick: function (row) {
@@ -765,6 +690,41 @@
$('#modalawal').removeClass('col-lg-12').addClass('col-lg-8');
}
},
{ text: 'Ulang', filterable: false, columntype: 'button', align: 'center', width: 50, cellsrenderer: function () {
return "Ulang";
}, buttonclick: function (row) {
editrowjabatan = row;
var offset = $("#gridpemeriksaan").offset();
var dataRecord = $("#gridpemeriksaan").jqxGrid('getrowdata', editrowjabatan);
swal({
title: 'Apakah anda yakin ?',
text: 'Data Pemeriksaan '+dataRecord.tlsreques+' an '+dataRecord.tlsnama+' akan kami buatkan order baru di LIS.?',
type: 'warning',
showCancelButton: true,
confirmButtonClass: 'btn btn-confirm mt-2',
cancelButtonClass: 'btn btn-cancel ml-2 mt-2',
confirmButtonText: 'Yes, Buatkan Ulang'
}).then(function () {
$.post('{{ route("deleteList") }}', { val01: 'buatulang', val02: dataRecord.id, val03: '', _token: '{{csrf_token()}}' },
function(data){
var status = data.status;
var message = data.message;
$.toast({
heading: status,
text: message,
position: 'top-right',
loaderBg: '#bf441d',
icon: 'info',
hideAfter: 5000,
stack: 1
});
openedpage();
return false;
});
});
}
},
{ text: 'No', filterable: false, datafield: 'noloket', width: 70, cellsalign: 'center', align: 'center' },
{ text: 'Status', filtertype: 'checkedlist', datafield: 'tlsstatus', width: 75, cellsalign: 'left', align: 'center' },
{ text: 'AccNumber', datafield: 'nofoto', width: 100, cellsalign: 'left', align: 'center' },
@@ -1194,25 +1154,43 @@
var periksa_id = document.getElementById('jeniskerja').value;
var alasan = document.getElementById('alasan').value;
var tabel = 'aktif';
$("html, body").animate({ scrollTop: 0 }, "slow");
$('#modalbaru').hide();
$('#modalawal').removeClass('col-lg-8').addClass('col-lg-12');
$.post('{{ route("deleteList") }}', { val01: periksa_id, val02: alasan, val03: tabel, _token: '{{csrf_token()}}' },
function(data){
var status = data.status;
var message = data.message;
$.toast({
heading: status,
text: message,
position: 'top-right',
loaderBg: '#bf441d',
icon: 'info',
hideAfter: 5000,
stack: 1
if (periksa_id == '' || alasan == ''){
swal({
title : 'Info',
text : 'Alasan tidak boleh dikosongi',
type : 'warning',
})
} else {
swal({
title: 'Apakah anda yakin ?',
text: 'Data Yang sudah dibatalkan tidak bisa dikembalikan lagi, apakah anda yakin.!',
type: 'warning',
showCancelButton: true,
confirmButtonClass: 'btn btn-confirm mt-2',
cancelButtonClass: 'btn btn-cancel ml-2 mt-2',
confirmButtonText: 'Yes'
}).then(function () {
$("html, body").animate({ scrollTop: 0 }, "slow");
$('#modalbaru').hide();
$('#modalawal').removeClass('col-lg-8').addClass('col-lg-12');
$.post('{{ route("deleteList") }}', { val01: periksa_id, val02: alasan, val03: tabel, _token: '{{csrf_token()}}' },
function(data){
var status = data.status;
var message = data.message;
$.toast({
heading: status,
text: message,
position: 'top-right',
loaderBg: '#bf441d',
icon: 'info',
hideAfter: 5000,
stack: 1
});
openedpage();
return false;
});
});
openedpage();
return false;
});
}
});
$("#btnkirimkealat").click(function(){
$('#modalawal').removeClass('col-lg-8').addClass('col-lg-12');