tz = "+07:00"; $this->is_staging = false; $this->base_url = "https://api-satusehat.kemkes.go.id/fhir-r4/v1"; $this->base_oauth_url = "https://api-satusehat.kemkes.go.id/oauth2/v1"; $this->base_consent_url = "https://api-satusehat.dto.kemkes.go.id/consent/v1"; $CI = &get_instance(); $this->db = $CI->load->database("default", true); $this->dbname = "one_health"; if ($this->is_staging) { $this->base_url = "https://api-satusehat-stg.kemkes.go.id/fhir-r4/v1"; $this->base_oauth_url = "https://api-satusehat-stg.kemkes.go.id/oauth2/v1"; $this->base_consent_url = "https://api-satusehat-stg.dto.kemkes.go.id/consent/v1"; $this->dbname = "one_health_dev"; } $this->get_organization_id(); } function load_clinic() { $this->dbname = "one_health_clinic"; } function ss_organization() { $this->get_organization_id(); $o_resp = $this->ss_get("/Organization/{$this->organizationID}"); $resp = $this->objToArray($o_resp); $id = $resp["id"]; $name = $resp["name"]; $x_type = $resp["type"][0]["coding"][0]; $type = $x_type["display"]; $code = $x_type["code"]; $system = $x_type["system"]; return json_encode([ "ID" => $id, "Name" => $name, "Type" => $type, "CodeSystem" => $code . " | " . $system, ]); } function search_practicioner_by_nik($nik, $debug = "") { $service = "/Practitioner?identifier=https://fhir.kemkes.go.id/id/nik|" . $nik; $o_resp = $this->ss_get($service, $debug); $resp = $this->objToArray($o_resp); if (count($resp["entry"]) > 0) { $rs = $resp["entry"][0]["resource"]; return json_encode([ "status" => "OK", "ihsID" => $rs["id"], "name" => $rs["name"][0]["text"] ]); } return json_encode([ "status" => "ERR", "message" => "Practitioner not found [$nik]" ]); } function search_patient_by_nik($nik, $debug = "") { $service = "/Patient?identifier=https://fhir.kemkes.go.id/id/nik|" . $nik; $resp = $this->ss_get($service); if ($debug != "") { echo "resp : "; print_r($resp); } $a_resp = $this->objToArray($resp); if (isset($a_resp["entry"][0]["resource"]["id"])) { return $a_resp["entry"][0]["resource"]["id"]; } return ""; } function location_by_organization($organizationIhsID, $debug = "") { $service = "/Location?organization=" . $organizationIhsID; $resp = $this->ss_get($service); if ($debug != "") { echo "resp : "; print_r($resp); } $a_resp = $this->objToArray($resp); return $a_resp; } function location_create( $code, $name, $description, $address, $city, $kodePos, $administrativeCode, $rt, $rw, $phone, $type, $partOf = "", $email = "", $fax = "", $url = "", $long = "", $lat = "" ) { $this->get_organization_id(); $organizationID = $this->organizationID; list($type_code, $type_display) = explode("^", $type); $telecom = []; $telecom[] = ["system" => "phone", "value" => "$phone", "use" => "work"]; if ($fax != "") $telecom[] = ["system" => "fax", "value" => "$fax", "use" => "work"]; if ($email != "") $telecom[] = ["system" => "email", "value" => "$email"]; if ($url != "") $telecom[] = ["system" => "url", "value" => "$url"]; $provCode = substr($administrativeCode, 0, 2); $cityCode = substr($administrativeCode, 0, 4); $districtCode = substr($administrativeCode, 0, 7); $villageCode = substr($administrativeCode, 0, 10); $data = [ "resourceType" => "Location", "identifier" => [ [ "system" => "http://sys-ids.kemkes.go.id/location/{$organizationID}", "value" => "$code", ], ], "status" => "active", "name" => "$name", "description" => "$description", "mode" => "instance", "telecom" => $telecom, "address" => [ "use" => "work", "line" => [ $address, ], "city" => "$city", "postalCode" => "$kodePos", "country" => "ID", "extension" => [ [ "url" => "https://fhir.kemkes.go.id/r4/StructureDefinition/administrativeCode", "extension" => [ ["url" => "province", "valueCode" => $provCode], ["url" => "city", "valueCode" => $cityCode], ["url" => "district", "valueCode" => "$districtCode"], ["url" => "village", "valueCode" => "$villageCode"], ["url" => "rt", "valueCode" => "$rt"], ["url" => "rw", "valueCode" => "$rw"], ], ], ], ], "physicalType" => [ "coding" => [ [ "system" => "http://terminology.hl7.org/CodeSystem/location-physical-type", "code" => "$type_code", "display" => "$type_display", ], ], ], "position" => [ "longitude" => intval($long), "latitude" => intval($lat), "altitude" => 0, ], "managingOrganization" => ["reference" => "Organization/{$organizationID}"], ]; if ($partOf != "") { $data["partOf"] = [ "reference" => "Location/$partOf" ]; } $service = "/Location"; $resp = $this->ss_post($service, $data); $oresp = $this->objToArray($resp); if (!isset($oresp["id"])) { header("Content-Type: text/plain"); print_r($data); print_r($resp); } return $oresp; } function location_nonactive( $ihsID ) { $this->get_organization_id(); $data = [ [ "op" => "replace", "path" => "/status", "value" => "inactive" ] ]; $service = "/Location/$ihsID"; $resp = $this->ss_patch($service, $data); return $this->objToArray($resp); } function get_location($locationID) { } function encounter_by_id($encounterID) { $this->get_organization_id(); $service = "/Encounter/$"; $resp = $this->ss_get($service); return $this->objToArray($resp); } function encounter_by_subject($patientIhsID) { $this->get_organization_id(); $service = "/Encounter?subject=$patientIhsID"; $resp = $this->ss_get($service); return $this->objToArray($resp); } function encounter( $orderDate, $patientIhsID, $patientName, $doctorIhsID, $doctorName, $locationID, $locationName, $labNumber, $tz = "+07:00", $payload_only = false ) { $service = "/Encounter"; $xdate = substr($orderDate, 0, 10) . "T" . substr($orderDate, 11) . $tz; $this->get_organization_id(); $param = $this->encounter_param( $patientIhsID, $patientName, $doctorIhsID, $doctorName, $locationID, $locationName, $this->organizationID, $labNumber, $xdate ); $payload = json_encode($param); if ($payload_only) { return ["", "", $payload, ""]; } $jresp = $this->ss_post($service, $param); $resp = $this->objToArray($jresp); $response = json_encode($resp); if (is_array($resp) && isset($resp["id"])) { $encounterResponseID = $resp["id"]; return [$encounterResponseID, "", $payload, $response]; } else { return ["", $response, $payload, $response]; } } function encounter_param( $patientIhs, $patientName, $dpjpIhs, $dpjpName, $locationIhs, $locationName, $organizationID, $orderHeaderNumber, $dateTime // 2022-06-14T07:00:00+07:00 ) { if ($this->is_staging) { $dpjpIhs = "N10000001"; $dpjpName = "Dokter Bronsig"; } $encounterParam = [ "resourceType" => "Encounter", "status" => "arrived", "class" => [ "system" => "http://terminology.hl7.org/CodeSystem/v3-ActCode", "code" => "AMB", "display" => "ambulatory" ], "subject" => [ "reference" => "Patient/{$patientIhs}", "display" => "$patientName" ], "participant" => [ [ "type" => [ [ "coding" => [ [ "system" => "http://terminology.hl7.org/CodeSystem/v3-ParticipationType", "code" => "ATND", "display" => "attender" ] ] ] ], "individual" => [ "reference" => "Practitioner/{$dpjpIhs}", "display" => "$dpjpName" ] ] ], "period" => [ "start" => "$dateTime", ], "location" => [ [ "location" => [ "reference" => "Location/$locationIhs", "display" => "$locationName" ] ] ], "statusHistory" => [ [ "status" => "arrived", "period" => [ "start" => $dateTime ] ] ], "serviceProvider" => [ "reference" => "Organization/{$organizationID}" ], "identifier" => [ [ "system" => "http://sys-ids.kemkes.go.id/encounter/{$organizationID}", "value" => "$orderHeaderNumber" ] ] ]; return $encounterParam; } // helper function get_organization_id() { $sql = "SELECT organizationID FROM {$this->dbname}.organization JOIN m_branch ON organizationM_BranchID = M_BranchID AND M_BranchIsDefault = 'Y' AND M_BranchIsActive = 'Y' WHERE organizationIsActive = 'Y'"; $qry = $this->db->query($sql); if (!$qry) { return; } $rows = $qry->result_array(); if (count($rows) > 0) { $this->organizationID = $rows[0]["organizationID"]; } } function ss_patch($service, $data) { $token = $this->get_token(); $authorization = "Authorization: Bearer " . $token; $xbase_url = $this->base_url; $url = $xbase_url . "$service"; $ch = curl_init($url); # Setup request to send json via POST. $payload = json_encode($data); curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH"); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json-patch+json', $authorization)); # Return response instead of printing. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); # Send request. $result = curl_exec($ch); curl_close($ch); # Print response. $data_rst = json_decode($result); return $data_rst; } function get_client_key($debug = "") { $sql = "select * from {$this->dbname}.client where clientIsActive = 'Y'"; $qry = $this->db->query($sql); if (!$qry) { return [false, "", ""]; } $rows = $qry->result_array(); if (count($rows) == 0) { if ($debug != "") { print_r([false, "", ""]); } return [false, "", ""]; } if ($debug != "") { print_r([true, $rows[0]["clientKey"], $rows[0]["clientSecret"]]); } return [true, $rows[0]["clientKey"], $rows[0]["clientSecret"]]; } function reset_token() { $sql = "delete from {$this->dbname}.token "; $qry = $this->db->query($sql); if (!$qry) { echo "ERR : " . $this->db->error()["message"]; echo " " . $this->db->last_query(); exit; } } function put_token() { $auth_url = $this->base_oauth_url; $url = $auth_url . "/accesstoken?grant_type=client_credentials"; list($status, $key, $secret) = $this->get_client_key(); $data = [ "client_id" => $key, "client_secret" => $secret ]; $ch = curl_init($url); $post_data = http_build_query($data); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($ch); curl_close($ch); if ($result) { $token_rst = json_decode($result); $sql = "select count(*) as xcount, tokenID from {$this->dbname}.token where tokenIsActive = 'y' "; $qry = $this->db->query($sql); if (!$qry) { echo "get count token error"; exit; } $rst_count = $qry->row_array(); // print_r($token_rst); if ($rst_count['xcount'] > 0) { $sql = "update {$this->dbname}.token set tokenValue = ?, tokenExpired = date_add(now(), interval 50 minute) where tokenID = ?"; $qry = $this->db->query($sql, [$token_rst->access_token, $rst_count['tokenID']]); if (!$qry) { $this->sys_error_db("refresh token error", $this->db->last_query()); exit; } } else { $sql = "update {$this->dbname}.token set tokenIsActive = 'N' where tokenIsActive = 'Y'"; $qry = $this->db->query($sql); if (!$qry) { echo "nonactive token error"; exit; } $sql = "insert into {$this->dbname}.token(tokenValue,tokenExpired) values(?,date_add(now(), interval 50 minute))"; $qry = $this->db->query($sql, [$token_rst->access_token]); if (!$qry) { echo "insert token error"; exit; } } $sql = "select tokenValue from {$this->dbname}.token where tokenIsActive = 'Y' limit 1 "; $qry = $this->db->query($sql); if (!$qry) { echo "get token error"; exit; } return $qry->row()->tokenValue; } } function get_token() { $sql = "SELECT COUNT(*) as xcount, tokenValue FROM {$this->dbname}.token WHERE tokenIsActive = 'Y' AND NOW() < tokenExpired AND tokenValue IS NOT NULL "; $qry = $this->db->query($sql); $this->check_error($qry, "select token"); $data_token = $qry->row_array(); //print_r($data_token); if ($data_token['xcount'] > 0) { return $data_token['tokenValue']; } else { return $this->put_token(); } } function ss_post($service, $data) { $token = $this->get_token(); $authorization = "Authorization: Bearer " . $token; $xbase_url = $this->base_url; $url = $xbase_url . "$service"; $ch = curl_init($url); # Setup request to send json via POST. $payload = json_encode($data); curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', $authorization)); # Return response instead of printing. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); # Send request. $result = curl_exec($ch); curl_close($ch); # Print response. $data_rst = json_decode($result); return $data_rst; } function ss_get($service, $debug = "") { $token = $this->get_token(); $authorization = "Authorization: Bearer " . $token; $xbase_url = $this->base_url; $url = $xbase_url . "$service"; $ch = curl_init($url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET"); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', $authorization)); # Return response instead of printing. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); # Send request. $result = curl_exec($ch); curl_close($ch); # Print response. if ($debug != "") { echo "url : $url \n"; print_r($result); } $data_rst = json_decode($result); return $data_rst; } protected function objToArray($obj) { if (!is_object($obj) && !is_array($obj)) { return $obj; } foreach ($obj as $key => $value) { $arr[$key] = $this->objToArray($value); } return $arr; } function check_error($qry, $stage) { if (!$qry) { echo json_encode([ "status" => "ERR", "message" => $this->db->error(), "sql" => $this->db->last_query() ]); exit; } } }