url_resultSBY = 'http://10.10.4.123:8001/api/webhook/lis?tenant=PadmaSurabaya'; $this->url_resultDPS = 'http://10.10.4.123:8001/api/webhook/lis?tenant=PadmaBali'; $this->url_masterSBY = "http://10.10.4.123:8001/api/webhook/lis-new-master?tenant=PadmaSurabaya"; $this->url_masterDPS = "http://10.10.4.123:8001/api/webhook/lis-new-master?tenant=PadmaBali"; } public function sendHL7Message($host, $port, $message, $timeout = 5) { try { // Create a TCP/IP socket $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($socket === false) { throw new Exception("socket_create() failed: " . socket_strerror(socket_last_error())); } // Set socket options (timeout) socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => $timeout, "usec" => 0)); socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array("sec" => $timeout, "usec" => 0)); // Connect to the remote host $result = socket_connect($socket, $host, $port); if ($result === false) { throw new Exception("socket_connect() failed: " . socket_strerror(socket_last_error($socket))); } // Add MLLP framing (Minimal Lower Layer Protocol) $mllpMessage = chr(0x0B) . $message . chr(0x1C) . chr(0x0D); // Send the message $bytesSent = socket_write($socket, $mllpMessage, strlen($mllpMessage)); if ($bytesSent === false) { throw new Exception("socket_write() failed: " . socket_strerror(socket_last_error($socket))); } if($bytesSent != strlen($mllpMessage)){ throw new Exception("socket_write() only sent $bytesSent bytes out of ". strlen($mllpMessage)); } // Read the acknowledgement (optional but recommended) $ack = socket_read($socket, 8192); // Adjust buffer size as needed if ($ack === false) { // Handle cases where no ACK is received within the timeout throw new Exception("socket_read() failed or timed out: " . socket_strerror(socket_last_error($socket))); } //Close the socket socket_close($socket); //Basic ACK check. More robust parsing is recommended. if (strpos($ack, "MSA") !== false) { return true; // Success (basic ACK check) } else { error_log("Unexpected ACK: " . $ack); // Log the unexpected ACK return false; // Failure (unexpected ACK) } } catch (Exception $e) { error_log("HL7 Sending Error: " . $e->getMessage()); // Log the error if(isset($socket)){ socket_close($socket); // Ensure socket closure on error } return false; // Indicate failure } } public function requests() { $db = \Config\Database::connect(); $raw = $this->request->getVar(); // log to cm_tm_logs $data = str_replace("'","''",json_encode($raw)); $sql = "INSERT INTO cmod.dbo.CM_TM_LOGS (URL, METHOD, BODY, LOGDATE) VALUES ('API/REQUESTS', 'POST', '$data', GETDATE())"; $db->query($sql); $data = array(); $qdata = (array)$raw; $qpat = (array)$qdata['patient']; //patdata $rm = $qpat['rm_number']; $firstname = str_replace("'","''",$qpat['patient_first_name']); $lastname = str_replace("'","''",$qpat['patient_last_name']); $dob = $qpat['patient_dob']; $dob = str_replace("-","",$dob); $sex = $qpat['patient_sex']; $phone = $qpat['patient_phone']; //reqdata $reffid = $qdata['reference_id']; $company = $qdata['company_name']; $loc = $qdata['branch']; $status = $qdata['status']; if($status == 'order') { $reqstatus = '0'; } else { $reqstatus = '1'; } $visitnum = $qpat['visit_number']; $visitdesc = $qpat['visit_description']; $visittype = $qpat['visit_type']; $visitdt = $qpat['visit_date_time']; $agentname = str_replace("'","''",$qpat['agent_name']); $doc = str_replace("'","''",$qpat['treating_doctor']); $createdt = $qdata['created']; $qant = (array)$qpat['anthropometry']; $bw = $qant['weight']; $bh = $qant['height']; // Check if visitnumber / patnumber beda dari yang lama /* $sql = "select cr.REQNUMBER, cp.PATNUMBER from cmod.dbo.CM_TM_REQUESTS cr left join cmod.dbo.CM_TM_PATIENTS cp on cr.PATID=cp.PATID where REFFID='$reffid'"; $query = $db->query($sql); $results = $query->getResultArray(); if(!isset($results[0])) { $qvisit = $results[0]['REQNUMBER']; $qpatnum = $results[0]['PATNUMBER']; if($qvisit != $visitnum) { $response = [ 'errors' => 'visit number is not the same', 'message' => 'Visit# is not the same with existing reffid' ]; return $this->fail($response , 409); } if($qpatnum != $rm) { $response = [ 'errors' => 'rm number is not the same', 'message' => 'RM# is not the same with existing reffid' ]; return $this->fail($response , 409); } } */ $sql = "select PATID from cmod.dbo.CM_TM_PATIENTS where PATNUMBER='$rm'"; $query = $db->query($sql); $results = $query->getResultArray(); if(!isset($results[0])) { $sql = "INSERT INTO cmod.dbo.CM_TM_PATIENTS (PATNUMBER, FIRSTNAME, LASTNAME, BIRTHDATE, SEX, PHONE ) VALUES ('$rm', '$firstname', '$lastname', '$dob', '$sex', '$phone' )"; $db->query($sql); $patid = $db->insertID(); } else { $patid = $results[0]['PATID']; $sql = "UPDATE cmod.dbo.CM_TM_PATIENTS SET FIRSTNAME='$firstname', LASTNAME='$lastname', BIRTHDATE='$dob', SEX='$sex', PHONE='$phone' where PATID='$patid'"; $db->query($sql); } /* $time = Time::createFromFormat('Y-m-d\TH:i:s.u\Z', $utcdt, 'UTC'); //2024-10-19T00:47:06.424654Z $time = $time->setTimezone('Asia/Shanghai'); $orderdt = $time->toDateTimeString(); */ $sql = "select REQID from cmod.dbo.CM_TM_REQUESTS where REFFID='$reffid'"; $query = $db->query($sql); $results = $query->getResultArray(); if(!isset($results[0])) { $sql = "INSERT INTO cmod.dbo.CM_TM_REQUESTS (REFFID, REQNUMBER, REQDATE, AGENT, DOC, LOC, PATID, COMPANY, LOGDATE, BW, BH, VISITDESC, VISITTYPE, REQSTATUS) VALUES ('$reffid', '$visitnum', '$visitdt', '$agentname', '$doc', '$loc', '$patid', '$company', '$createdt', '$bw', '$bh', '$visitdesc', '$visittype', '' )"; $db->query($sql); $reqid = $db->insertID(); } else { $reqid = $results[0]['REQID']; $sql = "UPDATE cmod.dbo.CM_TM_REQUESTS SET REQNUMBER='$visitnum', REQDATE='$visitdt', AGENT='$agentname', DOC='$doc', LOC='$loc', PATID='$patid', COMPANY='$company',LOGDATE='$createdt', BW='$bw', BH='$bh', VISITDESC='$visitdesc', VISITTYPE='$visittype', REQSTATUS='$reqstatus' where REQID='$reqid'"; $db->query($sql); } // tests $tests = json_decode(json_encode($qpat['tests']), true);; $string = ''; if($status=='order') { $teststatus = 0;} else { $teststatus = 1; } foreach($tests as $test) { $testcode = $test['service_id']; $testreffid = $test['test_ref_id']; $string .= "( '$testreffid', '$reqid', '$testcode', '$teststatus' ),"; } $string = rtrim($string, ','); //$sql = "INSERT INTO cmod.dbo.CM_TM_TESTS(REFFID, REQID, HISCODE) VALUES $string"; $sql = "INSERT INTO cmod.dbo.CM_TM_TESTS (REFFTESTID, REQID, HISCODE, TESTSTATUS) SELECT S.REFFTESTID, S.REQID, S.HISCODE, S.TESTSTATUS FROM ( VALUES $string ) AS S (REFFTESTID, REQID, HISCODE, TESTSTATUS) WHERE NOT EXISTS ( SELECT 1 FROM cmod.dbo.CM_TM_TESTS T WHERE T.REQID = S.REQID AND T.HISCODE = S.HISCODE );"; $db->query($sql); $sql = "UPDATE cmod.dbo.CM_TM_TESTS SET TESTSTATUS = S.TESTSTATUS FROM cmod.dbo.CM_TM_TESTS T INNER JOIN ( VALUES $string ) AS S (REFFTESTID, REQID, HISCODE, TESTSTATUS) ON T.REQID = S.REQID AND T.HISCODE = S.HISCODE;"; $db->query($sql); //sendORM $this->orm($reqid); return $this->respond(201); /* if( $db->query($sql) ) { return $this->respond(201); } else { $response = [ 'errors' => $db->errors(), 'message' => 'Invalid Messages' ]; return $this->fail($response , 409); } */ } public function orm($reqid) { $db = \Config\Database::connect(); $sql = "select r.REFFID, r.LOC, p.PATNUMBER, p.FIRSTNAME, p.LASTNAME, p.BIRTHDATE, p.SEX, p.PHONE, r.REQNUMBER, r.REQDATE, r.AGENT, r.DOC, r.BW, r.BH from cmod.dbo.CM_TM_REQUESTS r left join cmod.dbo.CM_TM_PATIENTS p on p.PATID=r.PATID where r.REQID='$reqid'"; $query = $db->query($sql); $results = $query->getResultArray(); $res = $results[0]; $reffid = $res['REFFID']; $patnumber = $res['PATNUMBER']; $loc = $res['LOC']; $doc = $res['DOC']; $firstname = $res['FIRSTNAME']; $lastname = $res['LASTNAME']; $dob = $res['BIRTHDATE']; $sex = substr($res['SEX'],0,1); $hosp = $res['REQNUMBER']; $reqdate = $res['REQDATE']; $time = Time::createFromFormat('Y-m-d\TH:i:s.u\Z', $reqdate, 'UTC'); //2024-10-19T00:47:06.424654Z $agent = $res['AGENT']; $bw = $res['BW']; $bh = $res['BH']; $phone = $res['PHONE']; // LOC //if($loc == "PBMC Bali") { if($loc == "PMG Bali" || $loc == "PBMC Bali") { $loc = "PADMA"; $doc = "PBDPS"; $time = $time->setTimezone('Asia/Shanghai'); $reqdate= date_format($time, 'YmdHi'); $port = "8101"; } else { $loc = "PBSBY"; $doc = "PBSBY"; $time = $time->setTimezone('Asia/Jakarta'); $reqdate= date_format($time, 'YmdHi'); $port = "8201"; } $orm = "MSH|^~\&|PBMC|TM|TDNL||||ORM^O01^|||2.3||||\r"; $orm .= "PID|1||$patnumber^^^^PATNUMBER||$lastname^$firstname^^^^^L||$dob|$sex||^|^^||$phone^^TELEPHON||||^||||||||||||||||\r"; //$orm .= "PV1|||$loc^^^||||$doc|$doc|||||||||||$hosp|||||||||||||||||||||||||$reqdate||||||||||\r"; $orm .= "PV1|||$loc^^^||||$doc|$doc||||||||||||||||||||||||||||||||||||$reqdate||||||||||\r"; $sql = "select t.TESTSTATUS, m.LISCODE from cmod.dbo.CM_TM_TESTS t left join cmod.dbo.CM_DICT_MAPPINGS m on m.HISCODE=t.HISCODE where t.REQID='$reqid'"; $query = $db->query($sql); $results = $query->getResultArray(); $i = 1; foreach($results as $qdata) { $liscode = $qdata['LISCODE']; $status = $qdata['TESTSTATUS']; if($liscode != '') { if($status!=1 || $status !=2) {$status="NW";} else {$status="CA";} //if($status!='CANCEL') {$status="NW";} else {$status="CA";} $orm .= "ORC|$status|$reffid||$reffid|||^^^$reqdate|||||$doc|$loc||$reqdate|||||||||\r"; if($i==1) { $orm .= "NTE|1||$hosp|\r"; } $orm .= "OBR|$i|||$liscode|||||||R|||||$doc|||||||||||||||||||||||||\r"; $i++; if($liscode=="EGFR") { $orm .= "OBX||NM|BW||$bw|\r"; } } } //echo "$orm"; //sendHL7Message($host, $port, $message, $timeout = 5); $this->sendHL7Message( "localhost", $port, $orm, $timeout = 5); //$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); } public function create_result_json($accessnumber) { $db = \Config\Database::connect(); $sql = "select r.HOSTORDERNUMBER, r.SP_HOSPNUMBER, cr.REQNUMBER, cr.LOC, cr.COMPANY, cr.AGENT, cr.VISITDESC, cr.VISITTYPE, p.PATNUMBER, cp.LASTNAME, cp.FIRSTNAME, p.BIRTHDATE, p.SEX, p.TELEPHON, r.COLLECTIONDATE, cr.AGENT, cr.DOC, cr.BW, cr.BH from SP_REQUESTS r left join cmod.dbo.CM_TM_REQUESTS cr on cr.REFFID=r.HOSTORDERNUMBER left join PATIENTS p on p.PATID=r.PATID left join cmod.dbo.CM_TM_PATIENTS cp on cp.PATNUMBER=right(p.PATNUMBER,8) where r.SP_ACCESSNUMBER='$accessnumber'"; $query = $db->query($sql); $results = $query->getResultArray(); $visitnumber = $results[0]['REQNUMBER']; $reffid = $results[0]['HOSTORDERNUMBER']; $location = $results[0]['LOC']; $payer_name = $results[0]['AGENT']; $company = $results[0]['COMPANY']; $createdt = gmdate('Y-m-d\TH:i:s.v\Z'); $patnumber = substr($results[0]['PATNUMBER'],-9); $firstname = $results[0]['FIRSTNAME']; $lastname = $results[0]['LASTNAME']; $dob = $results[0]['BIRTHDATE']; $sex = $results[0]['SEX']; $phone = $results[0]['TELEPHON']; $visitdesc = $results[0]['VISITDESC']; $visittype = $results[0]['VISITTYPE']; $visitdt = $results[0]['COLLECTIONDATE']; $agent = $results[0]['AGENT']; if($agent != '') {$bagent = true;} else {$bagent=false;} $doctor = $results[0]['DOC']; $bw = $results[0]['BW']; $bh = $results[0]['BH']; $json = [ "reference_id" => "$reffid", "created" => "$createdt", "company_name" => $company, "branch" => $location, "visit_number" => $visitnumber, "patient" => [ "rm_number" => $patnumber, "patient_first_name" => $firstname, "patient_last_name" => $lastname, "patient_dob" => $dob, "patient_sex" => $sex, "patient_phone" => $phone, "visit_number" => $visitnumber, "visit_description"=> $visitdesc, "visit_date_time" => $visitdt, "agent_name" => $agent, "agent" => $bagent, "treating_doctor" => $doctor, "visit_type" => $visittype, "anthropometry" => [ "weight" => $bw, "height" => $bh, ], ], "test_results" => [], "collects" => [], "receives" => [] ]; $sql = "select dc.CHAPID, t.DEPTH as depth_test, dc.FULLTEXT as chap_eng, dc.FULLTEXT as chap_ind, st.FULLTEXT as serum_type, cdt.TEXT1 as test_eng, cdt.TEXT2 as test_ind, cdt.UNIT as UNITTEXT, cdt.REFFTEXT, t.NOTPRINTABLE, cr.RESSTATUS, t.TESTORDER, t.RESTYPE as code_type, t.VALIDATIONINITIALS as validator, dt.SHORTTEXT, RESULT = case when t.RESVALUE is null then tx.FULLTEXT else t.RESVALUE end, ct.REFFTESTID, m.HISCODE, m.LISCODE, tub.TUBENAME, cr.REFRANGE, dt.TESTCODE, t.TESTORDER, dt.UNITS, cr.RESDATE, cr.USERVAL, u.USERNAME from REQUESTS r left join TESTS t on t.REQUESTID = r.REQUESTID left join DICT_TESTS dt on dt.ENDVALIDDATE is null and t.TESTID=dt.TESTID left join DICT_TEXTS tx on tx.TEXTID=t.CODEDRESULTID left join DICT_CHAPTERS dc on dc.CHAPID=dt.CHAPID and dc.ENDVALIDDATE is null left join DICT_TEST_SAMPLES ts on ts.TESTID=t.TESTID and dt.TESTID=ts.TESTID left join DICT_SAMPLES_TYPES st on st.SAMPTYPEID=ts.SAMPTYPEID left join cmod.dbo.CM_DICT_TESTS cdt on dt.TESTCODE=cdt.TESTCODE left join cmod.dbo.CM_RESULTS cr on cr.ACCESSNUMBER=r.ACCESSNUMBER and cr.TESTCODE=cdt.TESTCODE and cr.TESTCODE=dt.TESTCODE and t.RESUPDDATE=cr.RESDATE left join cmod.dbo.CM_TM_REQUESTS cq on cq.REFFID=r.EXTERNALORDERNUMBER left join cmod.dbo.CM_TM_TESTS ct on ct.REQID=cq.REQID left join cmod.dbo.CM_DICT_MAPPINGS m on m.LISCODE=cr.TESTCODE and m.HISCODE=ct.HISCODE left join cmod.dbo.CM_DICT_TUBES tub on tub.TUBEID=m.TUBEID left join USERS u on u.USERINITIALS=cr.USERVAL where r.ACCESSNUMBER='$accessnumber' and t.NOTPRINTABLE is null ORDER BY t.TESTORDER"; $query = $db->query($sql); $test_results = $query->getResultArray(); $d0=-1; $d1=-1; $d2=-1; $d3=-1; foreach ($test_results as $result) { $refftestid = trim($result['REFFTESTID']); $testorder = $result['TESTORDER']; if($refftestid == '') { $refftestid = $accessnumber . str_pad($testorder,3,0, STR_PAD_LEFT); } $hiscode = $result['HISCODE']; $tubename = $result['TUBENAME']; $depth = $result['depth_test']; $liscode = $result['LISCODE']; $testcode = $result['TESTCODE']; $testname = $result['test_eng']; $sampletype = $result['serum_type']; $chapter = $result['chap_eng']; $testresult = $result['RESULT']; $unit = $result['UNITS']; $unittext = $result['UNITTEXT']; $testunit = $unit; if($unittext != '') { $testunit = $unittext; } $refrange = $result['REFRANGE']; $refftext = $result['REFFTEXT']; $resstatus = $result['RESSTATUS']; if($resstatus == 'F') { $testsum = 'APPROVE'; } elseif($resstatus == 'C') { $testsum = 'PENDING'; } else { $testsum = null; } if($refftext != '') { $testreff = $refftext; } else { $testreff = $refrange; } if($liscode == '') {$liscode = $testcode;} $resdate = $result['RESDATE']; if($resdate == "1900-01-01 00:00:00.000") { $resdate =''; } $userval = $result['USERVAL']; $username = $result['USERNAME']; $data = [ "test_ref_id"=> "$refftestid", "hiscode"=> "$hiscode", "liscode"=> "$liscode", "service_name"=> "$testname", "test_medium"=> "$sampletype", "test_container"=> "$tubename", "chapter_type"=> "$chapter", "test_result"=> "$testresult", "test_unit"=> "$testunit", "test_reff" => "$testreff", "test_summary"=> "$testsum", "resdate"=> "$resdate", "userval"=> "$userval", "username"=> "$username", ]; if ( $depth == 0 || $depth == '' ) { // depth 0 $d0++; $d1=-1; $json['test_results'][] = $data; } else if ($depth == 1) { // depth 1 $d1++; $d2=-1; $json['test_results'][$d0]['subtest_results'][] = $data; } else if ($depth == 2) { // depth 2 $d2++; $d3=-1; $json['test_results'][$d0]['subtest_results'][$d1]['subtest_results'][] = $data; } } $sql = "SELECT ds.SHORTTEXT, FORMAT(tu.COLLECTIONDATE, 'dd-MM-yyyy') AS RECVDATE, FORMAT(tu.COLLECTIONDATE, 'HH:mm') AS RECVTIME, FORMAT(ct.COLLECTIONDATE, 'dd-MM-yyyy') AS COLLDATE, FORMAT(ct.COLLECTIONDATE, 'HH:mm') AS COLLTIME FROM SP_TUBES tu LEFT JOIN DICT_SAMPLES_TYPES ds ON ds.SAMPCODE = tu.SAMPLETYPE LEFT JOIN cmod.dbo.CM_TUBES ct ON ct.SAMPLETYPE = tu.SAMPLETYPE AND ct.ACCESSNUMBER = tu.SP_ACCESSNUMBER WHERE tu.SP_ACCESSNUMBER = '$accessnumber';"; $query = $db->query($sql); $samples = $query->getResultArray(); foreach ($samples as $data) { $sample = $data['SHORTTEXT']; $recvdate = $data['RECVDATE']; $recvtime = $data['RECVTIME']; $colldate = $data['COLLDATE']; $colltime = $data['COLLTIME']; $json['collects'][] = [ "sample" => "$sample", "colldate" => "$colldate", "colltime" => "$colltime" ]; $json['receives'][] = [ "sample" => "$sample", "recvdate" => "$recvdate", "recvtime" => "$recvtime" ]; } return $json; } public function sendjson( $method, $url, $message ) { $client = \Config\Services::curlrequest(); try { $response = $client->request($method, $url, $message); if ($response->getStatusCode() == 200) { print_r($response); } else { print_r($response); } } catch (\Exception $e) { //echo "
 \n".json_encode($json)."\n";
            echo "Error: " . $e->getMessage();
            log_message('error', 'API request exception: ' . $e->getMessage());
        }
	}
	public function results_send($accessnumber) {
		//$TMBali_bearerToken = file_get_contents('tokens/pbmc_dps.txt');
		//$TMSby_bearerToken = file_get_contents('tokens/pbmc_sby.txt');
		
		$json = $this->create_result_json($accessnumber);
		$location = $json['branch'];
		$headers = [ "Content-Type" => "application/json" ];
		if($location == 'PBMC Surabaya') { 
			//$token = $TMSby_bearerToken; 
			$url = $this->url_resultSBY;
		} else { 
			//$token = $TMBali_bearerToken;
			$url = $this->url_resultDPS;
		}
		
		$method = "POST";
		
		$message = [
			"headers" => $headers,
			"body" => json_encode($json),
			"verify" => false
		];
		echo "
";
		//print_r($message);
		$this->sendjson($method, $url, $message);
    }
	
	public function results_preview($accessnumber) {
		$json = $this->create_result_json($accessnumber);
		return $this->respond($json);
	}
	
	public function oc ($hon, $test) {
		$db = \Config\Database::connect();
		$sql = "select r.*, p.*, t.* from cmod.dbo.CM_TM_REQUESTS r 
			left join cmod.dbo.CM_TM_PATIENTS p on r.PATID=p.PATID 
			left join cmod.dbo.CM_DICT_MAPPINGS m on m.LISCODE='$test'
			left join cmod.dbo.CM_TM_TESTS t on t.REQID=r.REQID and t.HISCODE=m.HISCODE
			where r.REFFID='$hon' ";
		$query = $db->query($sql);
		$results = $query->getResultArray();
		$visitnumber = $results[0]['REQNUMBER'];
		$location = $results[0]['LOC'];
		$patnumber = $results[0]['PATNUMBER'];
		$firstname = $results[0]['FIRSTNAME'];
		$lastname = $results[0]['LASTNAME'];
		$hiscode = $results[0]['HISCODE'];
		$refftestid = $results[0]['REFFTESTID'];
		
		$method = "POST";
		if($location == "PBMC Bali") { $url = $this->url_resultDPS; }
		else { $url = $this->url_resultSBY; }
		
		$headers = [ "Content-Type" => "application/json" ];
		$json = [
			"reference_id" => "$hon",
			"company_name" => "Padma Medical Group",
			"branch" => "$location",
			"status" => "cancel",
			"patient" => [
				"rm_number" => "$patnumber",
				"patient_first_name" => "$firstname",
				"patient_last_name" => "$lastname",
				"visit_number" => "$visitnumber"
			],
			"tests" => [
				"test_ref_id" => trim($refftestid),
				"service_id" => "$hiscode"
			]
		];
		
		//return $this->respond($json);
		$message = [
			"headers" => $headers,
			"body" => json_encode($json),
			"verify" => false
		];
		
		$this->sendjson($method, $url, $message);
	}
}