Skip to content

Commit

Permalink
Added License number and Facility ID location attributes.Included the…
Browse files Browse the repository at this point in the history
…se attributes in facility data fetch from HIE, persisting and exposing them for presentation. Re-purposed FacilityStatus task. Cleaned-up code
  • Loading branch information
njorocs committed Jan 17, 2025
1 parent 940e155 commit 067fbb9
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
* <p>
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.kenyaemr.task;
package org.openmrs.module.kenyaemr.dataExchange;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
Expand All @@ -20,14 +20,11 @@
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.openmrs.GlobalProperty;
import org.openmrs.Location;
import org.openmrs.LocationAttribute;
import org.openmrs.LocationAttributeType;
import org.openmrs.api.AdministrationService;
import org.openmrs.api.LocationService;
import org.openmrs.api.context.Context;
import org.openmrs.module.kenyaemr.api.KenyaEmrService;
import org.openmrs.module.kenyaemr.metadata.CommonMetadata;
import org.openmrs.module.kenyaemr.metadata.FacilityMetadata;
import org.openmrs.module.metadatadeploy.MetadataUtils;
Expand All @@ -43,35 +40,32 @@
import java.util.HashMap;
import java.util.Map;

import static org.openmrs.module.kenyaemr.util.EmrUtils.*;
import static org.openmrs.module.kenyaemr.util.EmrUtils.getGlobalPropertyValue;

/**
* A scheduled task that automatically updates the facility status.
*/
public class FacilityStatusTask {
private static final Logger log = LoggerFactory.getLogger(FacilityStatusTask.class);
private static final AdministrationService administrationService = Context.getAdministrationService();
public class FacilityDetailsDataExchange {
private static final Logger log = LoggerFactory.getLogger(FacilityDetailsDataExchange.class);

private static final LocationService locationService = Context.getLocationService();
private static final Integer LOCATION_ID = Integer.parseInt(administrationService.getGlobalProperty("kenyaemr.defaultLocation"));
private static final String GP_MFL_CODE = administrationService.getGlobalProperty("facility.mflcode").trim();
private static final String BASE_URL_KEY = CommonMetadata.GP_SHA_FACILITY_VERIFICATION_GET_END_POINT;
private static final String API_USER_KEY = CommonMetadata.GP_SHA_FACILITY_VERIFICATION_GET_API_USER;
private static final String API_SECRET_KEY = CommonMetadata.GP_SHA_FACILITY_VERIFICATION_GET_API_SECRET;
private static final String DEFAULT_BASE_URL = "https://api.dha.go.ke/v1/";
private static final String DEFAULT_MFL_CODE = Context.getService(KenyaEmrService.class).getDefaultLocationMflCode().trim();

private static final String BASE_URL_KEY = CommonMetadata.GP_HIE_BASE_END_POINT_URL;
private static final String API_USER_KEY = CommonMetadata.GP_HIE_API_USER;
private static final String API_SECRET_KEY = CommonMetadata.GP_SHA_FACILITY_VERIFICATION_GET_API_SECRET;

public static ResponseEntity<String> getFacilityStatus() {
String bearerToken = getBearerToken();

String bearerToken = getBearerToken();
if (bearerToken.isEmpty()) {
log.error("Bearer token is missing");
return ResponseEntity.badRequest().contentType(MediaType.APPLICATION_JSON).body("{\"status\": \"Error\"}");
}

try {
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSslConnectionFactory()).build();
HttpGet getRequest = new HttpGet(getBaseUrl() + "fhir/Organization?identifierType=mfl-code&identifier=" + getMFLCode());

log.warn("----Facility data url {} ", getBaseUrl() + "fhir/Organization?identifierType=mfl-code&identifier=" + getMFLCode());
HttpGet getRequest = new HttpGet(getGlobalPropertyValue(BASE_URL_KEY) + "fhir/Organization?identifierType=mfl-code&identifier=" + getMFLCode());

getRequest.setHeader("Authorization", "Bearer " + bearerToken);

Expand Down Expand Up @@ -99,43 +93,18 @@ private static SSLConnectionSocketFactory createSslConnectionFactory() throws Ex
);
}

private static String getBaseUrl() {
GlobalProperty globalGetUrl = administrationService.getGlobalPropertyObject(BASE_URL_KEY);
return globalGetUrl.getPropertyValue() != null ? globalGetUrl.getPropertyValue().trim() : DEFAULT_BASE_URL.trim();
}

private static String getAPIUserKey() {
GlobalProperty apiUser = administrationService.getGlobalPropertyObject(API_USER_KEY);
return apiUser.getPropertyValue() != null ? apiUser.getPropertyValue().trim() : "";
}

private static String getAPISecret() {
GlobalProperty apiSecret = administrationService.getGlobalPropertyObject(API_SECRET_KEY);
return apiSecret.getPropertyValue() != null ? apiSecret.getPropertyValue().trim() : "";
}

private static String getMFLCode() {
return GP_MFL_CODE != null ? GP_MFL_CODE : DEFAULT_MFL_CODE;
}

private static String getBearerToken() {

String username = getGlobalPropertyValue(API_USER_KEY);
String secret = getGlobalPropertyValue(API_SECRET_KEY);
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpGet getRequest = new HttpGet(getBaseUrl() + "hie-auth?key=" + getAPIUserKey());
HttpGet getRequest = new HttpGet(getGlobalPropertyValue(BASE_URL_KEY) + "hie-auth?key=" + username);
getRequest.setHeader("Content-Type", "application/x-www-form-urlencoded");
getRequest.setHeader("Authorization", createBasicAuthHeader(getAPIUserKey(), getAPISecret()));

log.warn("Authorization Header:-> " + createBasicAuthHeader(getAPIUserKey(), getAPISecret()));

log.warn("URL:-> " + getBaseUrl() + "hie-auth?key=" + getAPIUserKey());
getRequest.setHeader("Authorization", createBasicAuthHeader(username, secret));

try (CloseableHttpResponse response = httpClient.execute(getRequest)) {
log.warn("Response code:-> " + response.getStatusLine().getStatusCode());

if (response.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK) {
String responseString = EntityUtils.toString(response.getEntity()).trim();
log.warn("Response string:-> {} ", responseString);

log.info("Bearer token retrieved successfully...");
return responseString;
} else {
Expand All @@ -159,6 +128,8 @@ private static Map<String, String> extractFacilityStatus(String organizationReso
statusMap.put("kephLevel", "--");
statusMap.put("approved", "--");
statusMap.put("shaFacilityExpiryDate", "--");
statusMap.put("shaFacilityId", "--");
statusMap.put("shaFacilityLicenseNumber", "--");
statusMap.put("shaFacilityReferencePayload", "--");

try {
Expand All @@ -171,13 +142,16 @@ private static Map<String, String> extractFacilityStatus(String organizationReso
if (entries != null && !entries.isEmpty()) {
JSONObject resource = entries.getJSONObject(0).optJSONObject("resource");
if (resource != null && "Organization".equals(resource.optString("resourceType"))) {
// Extract "id"
String resourceId = resource.optString("id", "--");
statusMap.put("shaFacilityId", resourceId);

JSONArray extensions = resource.optJSONArray("extension");
if (extensions != null) {
for (int i = 0; i < extensions.length(); i++) {

JSONObject extension = extensions.optJSONObject(i);
String url = extension.optString("url");
log.debug("Processing extension URL: {}", url);

switch (url) {
case "https://fr-kenyahie/StructureDefinition/license-status":
Expand Down Expand Up @@ -207,6 +181,21 @@ private static Map<String, String> extractFacilityStatus(String organizationReso
if (identifiers != null) {
for (int i = 0; i < identifiers.length(); i++) {
JSONObject identifier = identifiers.getJSONObject(i);

// Check for "license-number"
JSONArray codingArray = identifier.optJSONObject("type")
.optJSONArray("coding");
if (codingArray != null) {
for (int j = 0; j < codingArray.length(); j++) {
JSONObject coding = codingArray.getJSONObject(j);
String code = coding.optString("code");

if ("license-number".equals(code)) {
statusMap.put("shaFacilityLicenseNumber", identifier.optString("value", "--"));
}
}
}
// Check for "end" in "period"
JSONObject period = identifier.optJSONObject("period");
if (period != null) {
String end = period.optString("end", "--");
Expand All @@ -217,9 +206,6 @@ private static Map<String, String> extractFacilityStatus(String organizationReso
}
}
}
for (Map.Entry<String, String> entry : statusMap.entrySet()) {
System.out.println(entry.getKey() + " : " + entry.getValue());
}
return statusMap;

} catch (JSONException e) {
Expand Down Expand Up @@ -261,6 +247,8 @@ public static void saveFacilityStatus() {
String kephLevel = facilityStatus.getOrDefault("kephLevel", "--");
String approved = facilityStatus.getOrDefault("approved", "--");
String shaFacilityExpiryDate = facilityStatus.getOrDefault("shaFacilityExpiryDate", "--");
String shaFacilityLicenseNumber = facilityStatus.getOrDefault("shaFacilityLicenseNumber", "--");
String shaFacilityId = facilityStatus.getOrDefault("shaFacilityId", "--");
String shaFacilityReferencePayload = facilityStatus.getOrDefault("shaFacilityReferencePayload", "--");

final Location location = locationService.getLocation(LOCATION_ID);
Expand All @@ -277,6 +265,12 @@ public static void saveFacilityStatus() {
//Handle SHA facility expiry date
handleSHAFacilityLicenseExpiryDateAttribute(location, shaFacilityExpiryDate);

//Handle SHA facility License number
handleSHAFacilityLicenseNumberAttribute(location, shaFacilityLicenseNumber);

//Handle SHA facility id
handleSHAFacilityIdAttribute(location, shaFacilityId);

// Handle SHA Facility reference payload attribute
handleFacilityReferencePayloadAttribute(location, shaFacilityReferencePayload);
} else {
Expand Down Expand Up @@ -422,4 +416,58 @@ public static void handleSHAFacilityLicenseExpiryDateAttribute(Location location
locationService.saveLocation(location);
log.info("Facility SHA License expiry date for MFL Code {} saved successfully: , License expiry date: {}", getMFLCode(), facilityExpiryDate);
}

public static void handleSHAFacilityIdAttribute(Location location, String facilityId) {
LocationAttributeType facilityIdAttributeType = MetadataUtils.existing(LocationAttributeType.class, FacilityMetadata._LocationAttributeType.FACILITY_REGISTRY_CODE);

LocationAttribute facilityIdAttribute = location.getActiveAttributes(facilityIdAttributeType)
.stream()
.filter(attr -> attr.getAttributeType().equals(facilityIdAttributeType))
.findFirst()
.orElse(null);

if (facilityIdAttribute == null) {
facilityIdAttribute = new LocationAttribute();
facilityIdAttribute.setAttributeType(facilityIdAttributeType);
facilityIdAttribute.setValue(facilityId);
location.addAttribute(facilityIdAttribute);
log.info("Facility Id attribute updated to new value: {}", facilityId);
} else {
if (!facilityId.equals(facilityIdAttribute.getValue())) {
facilityIdAttribute.setValue(facilityId);
log.info("Facility Id updated to new value: {}", facilityId);
} else {
log.info("No update needed. Facility Id is the same: {}", facilityId);
}
}
locationService.saveLocation(location);
log.info("Facility Id for MFL Code {} saved successfully: , Facility Id: {}", getMFLCode(), facilityId);
}

public static void handleSHAFacilityLicenseNumberAttribute(Location location, String facilityLicenseNumber) {
LocationAttributeType facilityLicenseNumberAttributeType = MetadataUtils.existing(LocationAttributeType.class, FacilityMetadata._LocationAttributeType.FACILITY_LICENSE_NUMBER);

LocationAttribute facilityLicenseNumberAttribute = location.getActiveAttributes(facilityLicenseNumberAttributeType)
.stream()
.filter(attr -> attr.getAttributeType().equals(facilityLicenseNumberAttributeType))
.findFirst()
.orElse(null);

if (facilityLicenseNumberAttribute == null) {
facilityLicenseNumberAttribute = new LocationAttribute();
facilityLicenseNumberAttribute.setAttributeType(facilityLicenseNumberAttributeType);
facilityLicenseNumberAttribute.setValue(facilityLicenseNumber);
location.addAttribute(facilityLicenseNumberAttribute);
log.info("License number attribute updated to new value: {}", facilityLicenseNumber);
} else {
if (!facilityLicenseNumber.equals(facilityLicenseNumberAttribute.getValue())) {
facilityLicenseNumberAttribute.setValue(facilityLicenseNumber);
log.info("Facility license number updated to new value: {}", facilityLicenseNumber);
} else {
log.info("No update needed.SHA Facility License number is the same: {}", facilityLicenseNumber);
}
}
locationService.saveLocation(location);
log.info("Facility License number for MFL Code {} saved successfully: , License number: {}", getMFLCode(), facilityLicenseNumber);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ public class CommonMetadata extends AbstractMetadataBundle {
public static final String GP_CLIENT_VERIFICATION_EMR_VERIFICATION_PROXY_URL = "kenyaemr.client.registry.emr.verification.proxy.url";
public static final String GP_CLIENT_VERIFICATION_GET_END_POINT = "kenyaemr.client.registry.get.api";
public static final String GP_SHA_CLIENT_VERIFICATION_GET_END_POINT = "kenyaemr.sha.registry.get.api";
public static final String GP_SHA_FACILITY_VERIFICATION_GET_END_POINT = "kenyaemr.sha.facilityregistry.get.api";
public static final String GP_SHA_FACILITY_VERIFICATION_GET_API_USER = "kenyaemr.sha.facilityregistry.get.api.user";
public static final String GP_HIE_BASE_END_POINT_URL = "kenyaemr.sha.facilityregistry.get.api";
public static final String GP_HIE_API_USER = "kenyaemr.sha.facilityregistry.get.api.user";
public static final String GP_SHA_FACILITY_VERIFICATION_GET_API_SECRET = "kenyaemr.sha.facilityregistry.get.api.secret";
public static final String GP_SHA_HEALTH_WORKER_VERIFICATION_GET_END_POINT = "kenyaemr.sha.healthworker.registry.get.api";
public static final String GP_SHA_HEALTH_WORKER_VERIFICATION_GET_API_USER = "kenyaemr.sha.healthworker.get.api.user";
Expand Down Expand Up @@ -426,11 +426,11 @@ public void install() {
if(administrationService.getGlobalPropertyObject(CommonMetadata.GP_SHA_CLIENT_VERIFICATION_GET_END_POINT) == null) {
install(globalProperty(GP_SHA_CLIENT_VERIFICATION_GET_END_POINT, "A GET API for getting SHA client information from the client registry", "http://127.0.0.1:9342/api/shaPatientResource"));
}
if(administrationService.getGlobalPropertyObject(CommonMetadata.GP_SHA_FACILITY_VERIFICATION_GET_END_POINT) == null) {
install(globalProperty(GP_SHA_FACILITY_VERIFICATION_GET_END_POINT, "A GET API for getting SHA Facility status information from the registry", "https://sandbox.tiberbu.health/api/v4/"));
if(administrationService.getGlobalPropertyObject(CommonMetadata.GP_HIE_BASE_END_POINT_URL) == null) {
install(globalProperty(GP_HIE_BASE_END_POINT_URL, "A GET API for HIE registry", "https://api.dha.go.ke/v1/"));
}
if(administrationService.getGlobalPropertyObject(CommonMetadata.GP_SHA_HEALTH_WORKER_VERIFICATION_GET_END_POINT) == null) {
install(globalProperty(GP_SHA_HEALTH_WORKER_VERIFICATION_GET_END_POINT, "A GET API for getting SHA Health Worker information from Healthcare Worker registry", "https://sandbox.tiberbu.health/api/v4"));
install(globalProperty(GP_SHA_HEALTH_WORKER_VERIFICATION_GET_END_POINT, "A GET API for getting SHA Health Worker information from Healthcare Worker registry", "https://api.dha.go.ke/v1/"));
}
if(administrationService.getGlobalPropertyObject(CommonMetadata.GP_SHA_HEALTH_WORKER_VERIFICATION_GET_API_USER) == null) {
install(globalProperty(GP_SHA_HEALTH_WORKER_VERIFICATION_GET_API_USER, "API user for for connecting to the SHA provider registry", ""));
Expand All @@ -445,8 +445,8 @@ public void install() {
if(administrationService.getGlobalPropertyObject(CommonMetadata.GP_SHA_CLIENT_VERIFICATION_GET_API_SECRET) == null) {
install(globalProperty(GP_SHA_CLIENT_VERIFICATION_GET_API_SECRET, "API secret token for for connecting to the SHA client registry", ""));
}
if(administrationService.getGlobalPropertyObject(CommonMetadata.GP_SHA_FACILITY_VERIFICATION_GET_API_USER) == null) {
install(globalProperty(GP_SHA_FACILITY_VERIFICATION_GET_API_USER, "API user for for connecting to the SHA Facility registry", ""));
if(administrationService.getGlobalPropertyObject(CommonMetadata.GP_HIE_API_USER) == null) {
install(globalProperty(GP_HIE_API_USER, "API user for for connecting to the SHA Facility registry", ""));
}
if(administrationService.getGlobalPropertyObject(CommonMetadata.GP_SHA_FACILITY_VERIFICATION_GET_API_SECRET) == null) {
install(globalProperty(GP_SHA_FACILITY_VERIFICATION_GET_API_SECRET, "API secret token for for connecting to the SHA facility registry", ""));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public static final class _LocationAttributeType {
public static final String SHA_FACILITY_EXPIRY_DATE = "8e1ec5d4-4810-466a-9c90-b801bae9d063";
public static final String FACILITY_KEPH_LEVEL = "0233ba94-22d2-4658-81c3-2cf00fca382d";
public static final String FACILITY_HIE_FHIR_REFERENCE = "682f0a48-a642-491b-aa6d-41084bee0ee0";
public static final String FACILITY_REGISTRY_CODE = "1d1e2531-6a4a-4ed9-ab0a-02663e82379c";
public static final String FACILITY_LICENSE_NUMBER = "5f719dc5-3a70-48e5-8404-90bbcc35b36e";
}

/**
Expand Down Expand Up @@ -95,6 +97,17 @@ public void install() throws Exception {
_LocationAttributeType.FACILITY_HIE_FHIR_REFERENCE
));

install(locationAttributeType(
"Facility License Number", "Facility License Number",
FreeTextDatatype.class, "", 0, 1,
_LocationAttributeType.FACILITY_LICENSE_NUMBER
));

install(locationAttributeType(
"Facility Registry Code", "Facility Registry Code",
FreeTextDatatype.class, "", 0, 1,
_LocationAttributeType.FACILITY_REGISTRY_CODE
));
}

/**
Expand Down
Loading

0 comments on commit 067fbb9

Please sign in to comment.