4. ss_location_in_org untuk menampilkan seluruh location dalam organisasi curl http://ngagel/one-api/satu_sehat/ssresource/ss_location_in_org 5. ss_submit_encounter di gunakan untuk submit encounter ke satu sehat pada tanggal yang bersangkutan max 10 record sekali proses curl http://ngagel/one-api/satu_sehat/ss_submit_encounter/// 6. ss_encounter_by_id get encounter by satu sehat encounter id curl http://ngagel/one-api/satu_sehat/ss_encounter_by_id/ 7. ss_encounter_by_subject get encounter by satu sehat patient ihs number curl http://ngagel/one-api/satu_sehat/ss_encounter_by_subject/ 8. ss_submit_service_request di gunakan untuk submit service request ke satu sehat pada tanggal order header curl http://ngagel/one-api/satu_sehat/ss_submit_service_request/// 9. ss_service_request_by_od_id di gunakan untuk get service request ke satu sehat by T_OrderDetailID curl http://ngagel/one-api/satu_sehat/ss_service_request_by_od_id/ 10. ss_specimen_submit */ function __construct() { parent::__construct(); $this->tz = "+07:00"; $this->is_staging = true; $this->db_onedev = $this->load->database("default", true); $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"; $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(); } //specimen function ss_specimen_param( $specimenID, $specimen_code, $specimen_display, $collectedDate, $receivedDate, $patientID, $arr_serviceRequestID ) { $collectedDate = substr($collectedDate, 0, 10) . "T" . substr($collectedDate, 11) . $this->tz; $receivedDate = substr($receivedDate, 0, 10) . "T" . substr($receivedDate, 11) . $this->tz; $param = [ "resourceType" => "Specimen", "identifier" => [ [ "system" => "http://sys-ids.kemkes.go.id/specimen/{$this->organizationID}", "value" => "$specimenID", "assigner" => [ "reference" => "Organization/{$this->organizationID}" ] ] ], "status" => "available", "type" => [ "coding" => [ [ "system" => "http://snomed.info/sct", "code" => "$specimen_code", "display" => "$specimen_display" ] ] ], "collection" => [ "collectedDateTime" => "$collectedDate", "extension" => [ [ "url" => "https://fhir.kemkes.go.id/r4/StructureDefinition/CollectorOrganization", "valueReference" => [ "reference" => "Organization/{$this->organizationID}" ] ] ] ], "subject" => [ "reference" => "Patient/$patientID", ], "receivedTime" => "$receivedDate", ]; $param["request"] = []; foreach ($arr_serviceRequestID as $svc) { $param["request"][] = [ "reference" => "ServiceRequest/$svc" ]; } return $param; } function ss_specimen_submit($date = "", $start = 0, $limit = 1) { if ($date == "") $date = date("Y-m-d"); $sdate = $date . " 00:00:01"; $edate = $date . " 23:59:59"; //get service_request_id $sql = "select T_OrderDetailID, T_OrderHeaderID, OHPatientMapIhsNumber patientID, ServiceRequestResponID, T_TestT_SampleTypeID, OHSpecimenMapTypeCode, OHSpecimenMapTypeDisplay, max(T_OrderSampleID) T_OrderSampleID, max( concat(T_OrderSampleSamplingDate, ' ', T_OrderSampleSamplingTime) ) CollectedDateTime, max( concat(T_OrderSampleReceiveDate, ' ', T_OrderSampleReceiveTime) ) ReceivedDateTime from t_orderheader join {$this->dbname}.encounter on T_OrderHeaderID = EncounterT_OrderHeaderID and T_OrderHeaderDate >= ? and T_OrderHeaderDate <= ? and T_OrderHeaderIsActive = 'Y' join {$this->dbname}.service_request on T_OrderHeaderID = ServiceRequestT_OrderHeaderID join t_orderdetail on T_OrderDetailID = ServiceRequestT_OrderDetailID join {$this->dbname}.oh_patient_map on T_OrderHeaderM_PatientID = OHPatientMapM_PatientID join t_test on T_OrderDetailT_TestID = T_TestID join t_ordersample on T_OrderHeaderID = T_OrderSampleT_OrderHeaderID and ( T_OrderSampleT_SampleTypeID = T_TestT_SampleTypeID or T_OrderSampleT_SampleTypeID = fn_sampletype_from_local(T_TestNat_TestID) ) and T_OrderSampleIsActive = 'Y' left join {$this->dbname}.oh_specimen_map on T_TestT_SampleTypeID = OhSpecimenMapT_SampleTypeID left join {$this->dbname}.specimen on T_OrderHeaderID = SpecimenT_OrderHeaderID and T_OrderSampleID = SpecimenT_OrderSampleID where SpecimenID is null group by T_OrderDetailID order by T_OrderSampleID limit $start,$limit"; $qry = $this->db->query($sql, [$sdate, $edate]); if (!$qry) { echo "Error get ServiceRequest : " . $this->db->error()["message"]; exit; } $rows = $qry->result_array(); echo $this->db->last_query(); print_r($rows); exit; if (count($rows) == 0) { echo "No Pending Encounter.\n"; exit; } $arr_specimen = []; foreach ($rows as $r) { $orderSampleID = $r["T_OrderSampleID"]; $headerID = $r["T_OrderHeaderID"]; $specimenCode = $r["OHSpecimenMapTypeCode"]; $xid = $headerID . "-" . $specimenCode; if (!in_array($xid, array_keys($arr_specimen))) { $arr_specimen[$xid] = [ "sampleID" => $orderSampleID, "headerID" => $headerID, "patientID" => $r["patientID"], "specimenCode" => $r["OHSpecimenMapTypeCode"], "specimenDisplay" => $r["OHSpecimenMapTypeDisplay"], "serviceRequestID" => $r["ServiceRequestResponID"], "specimenDisplay" => $r["OHSpecimenMapTypeDisplay"], "collectedDateTime" => $r["CollectedDateTime"], "receivedDateTime" => $r["ReceivedDateTime"] ]; $arr_specimen[$xid]["service"] = []; } $arr_specimen[$xid]["service"][] = $r["ServiceRequestResponID"]; } $sql_i = "insert into {$this->dbname}.specimen(SpecimenResponseID, SpecimenT_OrderHeaderID, SpecimenT_OrderSampleID, SpecimenJSON,SpecimenStatus) values(?,?,?,?,'available')"; foreach ($arr_specimen as $sp) { $param = $this->ss_specimen_param( $sp["sampleID"], $sp["specimenCode"], $sp["specimenDisplay"], $sp["collectedDateTime"], $sp["receivedDateTime"], $sp["patientID"], $sp["service"] ); echo "Processing Specimen {$sp["specimenDisplay"]} : {$sp["specimenCode"]} \n"; $service = "/Specimen"; $o_resp = $this->ss_post($service, $param); $resp = $this->objToArray($o_resp); print_r($resp); if (in_array("id", array_keys($resp))) { echo "Success : Specimen ID {$resp["id"]} \n"; $id = $resp["id"]; $param["id"] = $id; $qry = $this->db->query($sql_i, [ $id, $sp["headerID"], $sp["sampleID"], json_encode($param) ]); if (!$qry) { echo "ERR : " . $this->db->error()["message"] . "\n"; echo $this->db->last_query(); exit; } echo " [Inserted to specimen]\n"; } } } //service_request function ss_service_request_submit($date = "", $start = 0, $limit = 1) { $tz = $this->tz; if ($date == "") $date = date("Y-m-d"); $sdate = $date . " 00:00:01"; $edate = $date . " 23:59:59"; //get the encounterID 1st $sql = "select EncounterID from t_orderheader join {$this->dbname}.encounter on T_OrderHeaderID = EncounterT_OrderHeaderID and T_OrderHeaderDate >= ? and T_OrderHeaderDate <= ? and T_OrderHeaderIsActive = 'Y' limit $start,$limit"; $qry = $this->db->query($sql, [$sdate, $edate]); if (!$qry) { echo "Error get ServiceRequest : " . $this->db->error()["message"]; exit; } $rows = $qry->result_array(); if (count($rows) == 0) { echo "No Pending Encounter.\n"; exit; } $ids = []; foreach ($rows as $r) { $ids[] = $r["EncounterID"]; } $s_ids = implode(",", $ids); $sql = "select T_OrderHeaderID, T_OrderHeaderLabNumber, EncounterResponseID, concat('Kunjungan ', M_PatientName, ' pada tanggal ', date(T_OrderHeaderDate)) EncounterName, OHDoctorMapIHSNumber, M_PatientName, OHPatientMapIhsNumber, fn_get_doctor_fullname(T_OrderHeaderPjM_DoctorID) M_DoctorName, ifnull(Nat_TestLoincCode, 'x-x') Nat_TestLoincCode, ifnull(Nat_TestLoincDisplay,'x-x') Nat_TestLoincDisplay, Nat_TestCode, Nat_TestName, T_OrderDetailID, T_OrderDetailCreated from t_orderheader join {$this->dbname}.encounter on T_OrderHeaderID = EncounterT_OrderHeaderID and EncounterID in ($s_ids) join {$this->dbname}.oh_patient_map on OHPatientMapM_PatientID = T_OrderHeaderM_PatientID join {$this->dbname}.oh_doctor_map on T_OrderHeaderPjM_DoctorID = OHDoctorMapM_DoctorID join t_orderdetail on T_OrderHeaderID = T_OrderDetailT_OrderHeaderID and T_OrderDetailIsActive = 'Y' and T_OrderDetailT_TestIsPrice = 'Y' join m_patient on T_OrderHeaderM_PatientID = M_PatientID join t_test on T_OrderDetailT_TestID = T_TestID join nat_test on T_TestNat_TestID = Nat_TestID left join {$this->dbname}.service_request on T_OrderHeaderID = ServiceRequestT_OrderHeaderID and T_OrderDetailID = ServiceRequestT_OrderDetailID left join nat_test_loinc on Nat_TestID = Nat_TestLoincNat_TestID where ServiceRequestID is null "; $qry = $this->db->query($sql, [$sdate, $edate]); if (!$qry) { echo "Error get ServiceRequest : " . $this->db->error()["message"]; exit; } $rows = $qry->result_array(); $in_complete_order = []; foreach ($rows as $r) { $id = $r["T_OrderDetailID"]; $labNo = $r["T_OrderHeaderLabNumber"]; $loincCode = $r["Nat_TestLoincCode"]; $loincName = $r["Nat_TestLoincDisplay"]; $natTestName = $r["Nat_TestName"]; $patientID = $r["OHPatientMapIhsNumber"]; $patientName = $r["M_PatientName"]; $encounterID = $r["EncounterResponseID"]; $encounterName = $r["EncounterName"]; $occurrenceDate = $r["T_OrderDetailCreated"]; $occurrenceDate = substr($occurrenceDate, 0, 10) . "T" . substr($occurrenceDate, 11) . "$tz"; $authoredOnDate = $occurrenceDate; $practitionerID = $r["OHDoctorMapIHSNumber"]; $practitionerName = $r["M_DoctorName"]; list($staffID, $staffName) = $this->get_staff_service_request($r["T_OrderHeaderID"]); if ($staffID == "") { echo "\t\tStaff belum ter-mapping : $labNo - $staffName\n"; continue; } if ($loincCode == "x-x") { echo "\t\tTest belum ter-mapping : $labNo - $natTestName\n"; continue; } $in_complete_order[] = $labNo; } $sql_i = "INSERT INTO {$this->dbname}.service_request (`ServiceRequestT_OrderHeaderID`, `ServiceRequestT_OrderDetailID`, `ServiceRequestJSON`, `ServiceRequestResponID` ) VALUES (?, ?, ?, ?)"; foreach ($rows as $r) { $oh_id = $r["T_OrderHeaderID"]; $id = $r["T_OrderDetailID"]; $labNo = $r["T_OrderHeaderLabNumber"]; $loincCode = $r["Nat_TestLoincCode"]; $loincName = $r["Nat_TestLoincDisplay"]; $natTestName = $r["Nat_TestName"]; $patientID = $r["OHPatientMapIhsNumber"]; $patientName = $r["M_PatientName"]; $encounterID = $r["EncounterResponseID"]; $encounterName = $r["EncounterName"]; $occurrenceDate = $r["T_OrderDetailCreated"]; $occurrenceDate = substr($occurrenceDate, 0, 10) . "T" . substr($occurrenceDate, 11) . "$tz"; $authoredOnDate = $occurrenceDate; $practitionerID = $r["OHDoctorMapIHSNumber"]; $practitionerName = $r["M_DoctorName"]; list($staffID, $staffName) = $this->get_staff_service_request($r["T_OrderHeaderID"]); if ($this->is_staging) { $practitionerID = "N10000001"; $practitionerName = "Dokter Bronsig"; $staffID = "N10000005"; $staffName = "Fatma"; } if (!in_array($labNo, $in_complete_order)) { echo "Processing [$id] $labNo | $natTestName | $loincCode \n"; $svc_param = $this->ss_service_request_param( $id, $loincCode, $loincName, $natTestName, $patientID, $encounterID, $encounterName, $occurrenceDate, $authoredOnDate, $practitionerID, $practitionerName, $staffID, $staffName ); $o = $this->ss_service_request_by_od_id($id); if (isset($o["total"]) && $o["total"] > 0) { $svc_id = $o["entry"][0]["resource"]["id"]; echo "Service Request ID : $svc_id \n"; $svc_param["id"] = $svc_id; $qry = $this->db->query($sql_i, [$oh_id, $id, json_encode($svc_param), $svc_id]); if (!$qry) { echo "Error insert service_request : " . $this->db->error()["message"]; exit; } } $o_resp = $this->ss_post("/ServiceRequest", $svc_param); $resp = $this->objToArray($o_resp); if (isset($resp["id"])) { $svc_id = $resp["id"]; $svc_param["id"] = $svc_id; $qry = $this->db->query($sql_i, [$oh_id, $id, json_encode($svc_param), $svc_id]); if (!$qry) { echo "Error insert service_request $svc_id : " . $this->db->error()["message"]; exit; } } } } } function ss_service_request_by_od_id($od_id) { $service = "/ServiceRequest?identifier=http://sys-ids.kemkes.go.id/servicerequest/{$this->organizationID}|$od_id"; $o_resp = $this->ss_get($service); $resp = $this->objToArray($o_resp); return $resp; } function ss_service_request_by_encounter($encounterID) { $service = "/ServiceRequest?encounter=$encounterID"; $o_resp = $this->ss_get($service); $resp = $this->objToArray($o_resp); return $resp; } function get_staff_service_request($ohID) { $sql = "select OHStaffMapIhsNumber, M_StaffName from fo_status join m_user on FO_StatusT_OrderHeaderID = ? and FO_StatusM_StatusID = 1 and FO_StatusM_UserID = M_UserID join m_staff on M_UserM_StaffID = M_StaffID left join {$this->dbname}.oh_staff_map on M_StaffIDNumber = OHStaffMapM_StaffNIK order by Fo_StatusID desc limit 0,1 "; $qry = $this->db->query($sql, [$ohID]); if (!$qry) { echo "Err : " . $this->db->error()["message"]; exit; } $rows = $qry->result_array(); if (count($rows) == 0) { return [false, ""]; } return [$rows[0]["OHStaffMapIhsNumber"], $rows[0]["M_StaffName"]]; } /* */ function ss_service_request_param( $orderDetailID, $natTestLoinc, $natTestLoincName, $natTestName, $patientID, $encounterID, $encounterName, $occurrenceDate, $authoredOnDate, $practitionerID, $practitionerName, $staffID, $staffName, $reasonCode = "" ) { $param = [ "resourceType" => "ServiceRequest", "identifier" => [ [ "system" => "http://sys-ids.kemkes.go.id/servicerequest/{$this->organizationID}", "value" => "$orderDetailID" ] ], "status" => "active", "intent" => "original-order", "priority" => "routine", "category" => [ [ "coding" => [ [ "system" => "http://snomed.info/sct", "code" => "108252007", "display" => "Laboratory procedure" ] ] ] ], "code" => [ "coding" => [ [ "system" => "http://loinc.org", "code" => "$natTestLoinc", "display" => "$natTestLoincName" ] ], "text" => "$natTestName" ], "subject" => [ "reference" => "Patient/$patientID" ], "encounter" => [ "reference" => "Encounter/{$encounterID}", "display" => "$encounterName" ], "occurrenceDateTime" => "$occurrenceDate", "authoredOn" => "$authoredOnDate", "requester" => [ "reference" => "Practitioner/$practitionerID", "display" => "$practitionerName" ], "performer" => [ [ "reference" => "Practitioner/$staffID", "display" => "$staffName" ] ], ]; if ($reasonCode != "") { $param["reasonCode"] = [ [ "text" => "$reasonCode" ] ]; } return $param; } //encounter function ss_encounter_by_id($id) { $service = "/Encounter/$id"; $resp = $this->ss_get($service); print_r($resp); } function ss_encounter_by_subject($ihs) { $service = "/Encounter?subject=$ihs"; $resp = $this->ss_get($service); print_r($resp); } function ss_submit_encounter($date = "", $start = 0, $limit = 20) { if ($date == "") $date = date("Y-m-d"); $sdate = $date . " 00:00:01"; $edate = $date . " 23:59:59"; list($locationID, $locationName) = $this->get_location_encounter(); $sql = "select T_OrderHeaderID,OHDoctorMapIHSNumber, M_DoctorName, T_OrderHeaderLabNumberExt, T_OrderHeaderDate, OHPatientMapIhsNumber, M_PatientName from t_orderheader join {$this->dbname}.oh_doctor_map on T_OrderHeaderPjM_DoctorID = OHDoctorMapM_DoctorID and T_OrderHeaderDate >= ? and T_OrderHeaderDate <= ? join m_doctor on T_OrderHeaderPjM_DoctorID = M_DoctorID join {$this->dbname}.oh_patient_map on T_OrderHeaderM_PatientID = OHPatientMapM_PatientID join m_patient on T_OrderHeaderM_PatientID = M_PatientID left join {$this->dbname}.encounter on T_OrderHeaderID = EncounterT_OrderHeaderID where EncounterID is null limit $start,$limit "; $qry = $this->db->query($sql, [$sdate, $edate]); if (!$qry) { echo "ERR : " . $this->db->error()["message"]; echo $this->db->last_query(); exit; } $rows = $qry->result_array(); $service = "/Encounter"; $sql = "insert into {$this->dbname}.encounter (EncounterJSON, EncounterT_OrderHeaderID,EncounterResponseID,EncounterStatus) values(?,?,?,?)"; foreach ($rows as $r) { $odate = $r["T_OrderHeaderDate"]; $xdate = substr($odate, 0, 10) . "T" . substr($odate, 11) . "+07:00"; $param = $this->ss_encounter_param( $r["OHPatientMapIhsNumber"], $r["M_PatientName"], $r["OHDoctorMapIHSNumber"], $r["M_DoctorName"], $locationID, $locationName, $this->organizationID, $r["T_OrderHeaderLabNumberExt"], $xdate ); echo "Processing " . $r["T_OrderHeaderLabNumberExt"] . "|" . $r["OHPatientMapIhsNumber"] . "\n"; $jresp = $this->ss_post($service, $param); $resp = $this->objToArray($jresp); if (is_array($resp) && isset($resp["id"])) { print_r($resp); $encounterResponseID = $resp["id"]; $qry = $this->db->query($sql, [ json_encode($param), $r["T_OrderHeaderID"], $encounterResponseID, "arrived" ]); if (!$qry) { echo "ERR : " . $this->db->error()["message"] . "\n"; echo $this->db->last_query(); exit; } } else { echo "ERR : \n"; print_r($resp); } } } function get_location_encounter() { $sql = "select LocationID, LocationName from {$this->dbname}.location where LocationIsActive='Y' and LocationType = 'ENCOUNTER_LAB' limit 0,1"; $qry = $this->db->query($sql); if (!$qry) { return ["", ""]; } $rows = $qry->result_array(); if (count($rows) == 0) { return ["", ""]; } return [$rows[0]["LocationID"], $rows[0]["LocationName"]]; } //create location function get_env() { if ($this->is_staging) { echo "Environment is Staging \n"; } else { echo "Environment is Production \n"; } } function change_env() { $this->reset_token(); $this->put_token(); } function ss_location_in_org() { $service = "/Location/?organization=$this->organizationID"; $resp = $this->ss_get($service); print_r($this->objToArray($resp)); } function ss_location_by_id($id) { $service = "/Location/$id"; $resp = $this->ss_get($service); print_r($this->objToArray($resp)); } function ss_register_all_location() { $sql = "select l.*, case when LocationPhysicalTypeCode = 'si' then 1 when LocationPhysicalTypeCode = 'bu' then 2 when LocationPhysicalTypeCode = 'lvl' then 3 when LocationPhysicalTypeCode = 'ro' then 4 end xid from {$this->dbname}.location l where trim(LocationID) = '' order by xid"; $qry = $this->db->query($sql); if (!$qry) { echo "ERR : " . $this->db->error()["message"]; exit; } $rows = $qry->result_array(); foreach ($rows as $r) { $code = $r["LocationCode"]; $name = $r["LocationName"]; $description = $r["LocationDescription"]; $type = $r["LocationPhysicalTypeCode"] . "^" . $r["LocationPhysicalTypeDisplay"]; $lat = $r["LocationLatitude"]; $long = $r["LocationLongitude"]; $parentID = $r["LocationParentLocalID"]; $partOf = $this->get_parent_id($parentID); // echo "$code | $name | $description | $type | $lat | $long | $parentID | $partOf \n"; list($phone, $fax, $email, $url) = $this->get_phone_email($r["LocationLocalID"]); // echo "$phone | $fax | $email | $url \n"; list($line, $city, $admCode, $postalCode, $rt, $rw) = $this->get_address($r["LocationLocalID"]); // echo "$line | $city | $admCode | $postalCode| $rt | $rw \n"; // register location $resp = $this->ss_location_create( "$code", $name, "$description", "$line", "$city", "$postalCode", "$admCode", "$rt", "$rw", "$phone", "$type", $partOf, $email, $fax, $url, $long, $lat ); echo "\nid : " . $resp["id"]; echo "\nname : " . $resp["name"]; if (isset($resp["id"]) && $resp["id"] != "") { $sql = "update {$this->dbname}.location set LocationID = ? where LocationLocalID = ?"; $qry = $this->db->query($sql, [$resp["id"], $r["LocationLocalID"]]); if (!$qry) { echo "\nERR update location " . $this->db->error()["message"]; exit; } } else { echo "\nError register location : \n"; print_r($resp); exit; } } } function get_parent_id($parentID) { if ($parentID == 0) return ""; $sql = "select l.* from {$this->dbname}.location l where LocationLocalID = ?"; $qry = $this->db->query($sql, [$parentID]); if (!$qry) { return ""; } $rows = $qry->result_array(); if (count($rows) == 0) { return ""; } return $rows[0]["LocationID"]; } function get_address($localID) { $sql = "select * from {$this->dbname}.location_address where LocationAddressLocationLocalID = ? and LocationAddresIsActive = 'Y'"; $qry = $this->db->query($sql, [$localID]); if (!$qry) { echo "ERR : " . $this->db->error()["message"]; exit; } $rows = $qry->result_array(); $line = ""; $city = ""; $code = ""; $postalCode = ""; $rt = ""; $rw = ""; foreach ($rows as $r) { $line = $r["LocationAddresLine"]; $city = $r["LocationAddresCityName"]; $code = $r["LocationAddresVillage"]; $postalCode = $r["LocationAddresPostalCode"]; $rt = $r["LocationAddresRT"]; $rw = $r["LocationAddresRW"]; } return [$line, $city, $code, $postalCode, $rt, $rw]; } function get_phone_email($localID) { $sql = "select * from {$this->dbname}.location_telecom where LocationTelecomLocationID = ? and LocationIsActive = 'Y'"; $qry = $this->db->query($sql, [$localID]); if (!$qry) { echo "ERR : " . $this->db->error()["message"]; exit; } $rows = $qry->result_array(); $email = ""; $fax = ""; $url = ""; $phone = ""; foreach ($rows as $r) { $system = $r["LocationSystem"]; switch ($system) { case "phone": $phone = $r["LocationValue"]; break; case "fax": $fax = $r["LocationValue"]; break; case "email": $email = $r["LocationValue"]; break; case "url": $url = $r["LocationValue"]; break; } } return [$phone, $fax, $email, $url]; } function ss_location_create( $code, $name, $description, $address, $city, $kodePos, $administrativeCode, $rt, $rw, $phone, $type, $partOf = "", $email = "", $fax = "", $url = "", $long = -6.23115426275766, $lat = 106.83239885393944 ) { $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 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; } function ss_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; } //analys_patient function ss_analyze_patient($date = "", $limit = 20) { if ($date == "") $date = date("Y-m-d"); $sql = "select M_PatientID, M_PatientIdNumber from t_orderheader join m_patient on T_OrderHeaderDate >= ? and T_OrderHeaderIsActive = 'Y' and T_OrderHeaderDate <= ? and T_OrderHeaderDate + interval 30 minute < now() and T_OrderHeaderM_PatientID = M_PatientID and M_PatientM_IdTypeID = 1 left join {$this->dbname}.oh_patient_map on M_PatientID = OHPatientMapM_PatientID where OHPatientMapM_PatientID is null limit 0,$limit "; $sdate = "$date 00:00:01"; $edate = "$date 23:59:59"; $qry = $this->db->query($sql, [$sdate, $edate]); if (!$qry) { echo $this->db->error()["message"]; return []; } $rows = $qry->result_array(); foreach ($rows as $r) { $nik = $r["M_PatientIdNumber"]; $patient_id = $r["M_PatientID"]; echo "processing [M_PatientID : $patient_id] : $nik => "; if (strlen($nik) != 16) { echo " *invalid nik* len : " . strlen($nik) . "\n"; continue; } $ihsNumber = $this->populate_patient_nik($nik); if (strlen($ihsNumber) > 4) { echo " $ihsNumber \n"; $rec = ["OHPatientMapM_PatientID" => $patient_id, "OHPatientMapIhsNumber" => $ihsNumber]; $this->insert_or_update("{$this->dbname}.oh_patient_map", $rec, "OHPatientMapM_PatientID"); } else { echo " *Invalid* $ihsNumber \n"; } } } function insert_or_update($table, $rec, $id_field) { $sql = "select count(*) as tot from $table where $id_field = ?"; $qry = $this->db->query($sql, [$rec[$id_field]]); if (!$qry) { echo "Error : " . $this->db->error()["message"]; exit; } $rows = $qry->result_array(); if ($rows[0]["tot"] == 0) { //insert $sql = "insert into $table ("; $fields = implode(", ", array_keys($rec)); $sql .= $fields . ") values("; $vals = []; foreach (array_keys($rec) as $f) { if (count($vals) > 0) { $sql .= ", "; } $sql .= "?"; $vals[] = $rec[$f]; } $sql .= ")"; } else { $sql = "update $table set "; $vals = []; foreach (array_keys($rec) as $f) { if (count($vals) > 0) { $sql .= ", "; } $sql .= "$f = ? "; $vals[] = $rec[$f]; } $sql .= " where $id_field = " . $rec[$id_field]; } $qry = $this->db->query($sql, $vals); echo $this->db->last_query() . "\n"; } // Poppulate function populate_staff($debug = "") { $sql = "select * from {$this->dbname}.oh_staff_map where OHStaffMapIhsNumber= '' "; $qry = $this->db->query($sql); if (!$qry) { echo "Error get staff map: " . $this->db->error()["message"]; exit; } $rows = $qry->result_array(); $sqlu = "update {$this->dbname}.oh_staff_map set OHStaffMapIhsNumber = ? where OHStaffMapM_StaffNIK=?"; foreach ($rows as $r) { $nik = trim($r["OHStaffMapM_StaffNIK"]); $result = $this->search_practicioner_by_nik($nik, $debug); $ihsNumber = $this->parse_nakes_ihs_number($result); echo "Processing NIK $nik => $ihsNumber"; $qry = $this->db->query($sqlu, [$ihsNumber, $nik]); if (!$qry) { echo "\nError update oh_staff_map : " . $this->db->error()["message"]; exit; } echo " updated [OK]\n"; } } //populate patient function populate_patient_nik($nik) { $result = $this->search_patient_by_nik($nik); $patientIhsNumber = $this->parse_nakes_ihs_number($result); return $patientIhsNumber; } //populate dokter function populate_dokter_nik($nik) { $result = $this->search_practicioner_by_nik($nik); $nakesIhsNumber = $this->parse_nakes_ihs_number($result); echo "Nakes IHS : $nakesIhsNumber"; } function parse_nakes_ihs_number($result, $debug = "") { if (count($result) == 0) return ""; $a_result = $this->objToArray($result); return $a_result["entry"][0]["resource"]["id"]; } function search_practicioner_by_nik($nik, $debug = "") { $service = "/Practitioner?identifier=https://fhir.kemkes.go.id/id/nik|" . $nik; $resp = $this->ss_get($service, $debug); if ($debug != "") { print_r($resp); } return $resp; } function search_practicioner_by_nik_old($nik) { $token = $this->get_token(); $authorization = "Authorization: Bearer " . $token; $xbase_url = $this->base_url; //API URL $url = $xbase_url . "/Practitioner?identifier=https://fhir.kemkes.go.id/id/nik|" . $nik; //echo $url; $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, "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. $data_rst = json_decode($result); return $data_rst; } 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 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; //api 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); # setup request to send json via post. $post_data = http_build_query($data); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); // suppress return header // curl_setopt( // $ch, // CURLOPT_HEADER, // array( // 'content-type: application/x-www-form-urlencoded' // ) // ); # return response instead of printing. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); # send request. $result = curl_exec($ch); curl_close($ch); # print response. //echo $token_rst->access_token; if ($result) { $token_rst = json_decode($result); $sql = "select count(*) as xcount, tokenID from {$this->dbname}.token where tokenIsActive = 'y' "; $qry = $this->db_onedev->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_onedev->query($sql, [$token_rst->access_token, $rst_count['tokenID']]); if (!$qry) { $this->sys_error_db("refresh token error", $this->db_onedev->last_query()); exit; } } else { $sql = "update {$this->dbname}.token set tokenIsActive = 'N' where tokenIsActive = 'Y'"; $qry = $this->db_onedev->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_onedev->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_onedev->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_onedev->query($sql); if (!$qry) { echo "select token error"; exit; } $data_token = $qry->row_array(); //print_r($data_token); if ($data_token['xcount'] > 0) { return $data_token['tokenValue']; } else { return $this->put_token(); } } 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); } return $resp; } function send_bundle($orderID) { $sql = "SELECT * FROM {$this->dbname}.bundle WHERE BundleT_orderHeaderID = {$orderID} AND BundleIsActive = 'Y' LIMIT 1 "; $qry = $this->db_onedev->query($sql); if (!$qry) { echo "select bundle error"; exit; } $data_blundle = $qry->row_array(); // print_r($data_blundle); $json_data = json_decode($data_blundle['BundleJSON']); $json_payload = json_encode($json_data); $token = $this->get_token(); $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => 'https://api-satusehat-dev.dto.kemkes.go.id/fhir-r4/v1', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => $json_payload, CURLOPT_HTTPHEADER => array( 'Content-Type: application/json', 'Authorization: Bearer ' . $token ), )); $response = curl_exec($curl); curl_close($curl); //echo $response; //$json_response = json_encode(json_decode($response)); //echo $json_response; $sql = "UPDATE {$this->dbname}.bundle SET BundleResponseJSON = '{$response}' WHERE BundleT_orderHeaderID = {$orderID} AND BundleIsActive = 'Y' "; $qry = $this->db_onedev->query($sql); //echo $sql; if (!$qry) { echo "update bundle error"; exit; } echo $response; } protected function objToArray($obj) { // Not an object or array if (!is_object($obj) && !is_array($obj)) { return $obj; } // Parse array foreach ($obj as $key => $value) { $arr[$key] = $this->objToArray($value); } // Return parsed array return $arr; } }