Initial import
This commit is contained in:
575
application/libraries/Satu_sehat.php
Normal file
575
application/libraries/Satu_sehat.php
Normal file
@@ -0,0 +1,575 @@
|
||||
<?php
|
||||
class Satu_sehat
|
||||
{
|
||||
var $base_url, $base_consent_url, $base_oauth_url;
|
||||
var $is_staging, $organizationID;
|
||||
var $key, $secret;
|
||||
var $tz;
|
||||
var $db, $dbname;
|
||||
function __construct()
|
||||
{
|
||||
$this->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 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);
|
||||
return $this->objToArray($resp);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user