Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: #46

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public IGenericClient getFhirClient() throws Exception {
configureFhirHttpClient(client);
}

fhirContext.getRestfulClientFactory().setSocketTimeout(config.getFhirClientTimeout());

IGenericClient fhirClient = fhirContext.newRestfulGenericClient(config.getLisUrl());
if (config.getAuthType().equals(AuthType.BASIC)) {
BasicAuthInterceptor authInterceptor = new BasicAuthInterceptor(config.getLisUserName(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class LabOnFhirActivator extends BaseModuleActivator implements ApplicationContextAware, DaemonTokenAware {

private static final Logger log = LoggerFactory.getLogger(LabOnFhirActivator.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Component
@Configuration
public class LabOnFhirConfig implements ApplicationContextAware {

private static final String LAB_ORDERING_SITE_CONCEPT_UUID = "labonfhir.labOrderLocationConceptUuid";

public static final String GP_LIS_URL = "labonfhir.lisUrl";

public static final String GP_LIS_USER_UUID = "labonfhir.lisUserUuid";
Expand Down Expand Up @@ -68,6 +68,8 @@ public class LabOnFhirConfig implements ApplicationContextAware {

public static final String GP_FILTER_ORDER_BY_TEST_UUIDS = "labonfhir.filterOrderBytestUuids";

public static final String GP_FHIR_CLIENT_TIMEOUT = "labonfhir.clientTimeout";

public enum AuthType{
SSL,
BASIC
Expand Down Expand Up @@ -231,4 +233,14 @@ private KeyStore loadKeystore(String filePath) {
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}

public int getFhirClientTimeout() {
String fhirClientTimeout = administrationService.getGlobalProperty(GP_FHIR_CLIENT_TIMEOUT, "180000");
return Integer.valueOf(fhirClientTimeout);
}

public Object getLabOrderingSiteConceptUuid() {
String labOrderingSiteConceptUuid = administrationService.getGlobalProperty(LAB_ORDERING_SITE_CONCEPT_UUID);
return labOrderingSiteConceptUuid;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

Expand All @@ -27,9 +26,7 @@
import org.openmrs.module.labonfhir.LabOnFhirConfig;
import org.openmrs.module.labonfhir.api.fhir.OrderCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class LabOrderHandler {

@Autowired
Expand Down Expand Up @@ -88,22 +85,22 @@ public Task createOrder(Order order) throws OrderCreationException {

Reference forReference = newReference(order.getPatient().getUuid(), FhirConstants.PATIENT);

Reference ownerRef = newReference(config.getLisUserUuid(), FhirConstants.PRACTITIONER);
// Reference ownerRef = newReference(config.getLisUserUuid(), FhirConstants.PRACTITIONER);
Reference ownerRef = newReference(order.getEncounter().getLocation().getUuid(), FhirConstants.ORGANIZATION);

Reference encounterRef = newReference(order.getEncounter().getUuid(), FhirConstants.ENCOUNTER);

Optional<EncounterProvider> requesterProvider = order.getEncounter().getActiveEncounterProviders().stream()
.findFirst();
Reference locationRef = getLocatonRef(order.getEncounter());

Reference requesterRef = requesterProvider.map(
encounterProvider -> newReference(encounterProvider.getUuid(), FhirConstants.PRACTITIONER)).orElse(null);
Reference requesterRef = getRequesterRef(order.getEncounter());

//if (order.getEncounter().getLocation() != null) {
// requesterRef = newReference(order.getEncounter().getLocation().getUuid(), FhirConstants.ORGANIZATION);
// locationRef = newReference(order.getEncounter().getLocation().getUuid(), FhirConstants.LOCATION);
//}

// Create Task Resource for given Order
Task newTask = createTask(basedOnRefs, forReference, ownerRef, encounterRef ,taskInputs);

if (order.getEncounter().getActiveEncounterProviders().isEmpty()) {
newTask.setRequester(requesterRef);
}
Task newTask = createTask(basedOnRefs, forReference, ownerRef, encounterRef, locationRef,requesterRef ,taskInputs);

// Save the new Task Resource
try {
Expand All @@ -116,14 +113,16 @@ public Task createOrder(Order order) throws OrderCreationException {
}

private Task createTask(List<Reference> basedOnRefs, Reference forReference, Reference ownerRef,
Reference encounterRef ,List<Task.ParameterComponent> taskInputs) {
Reference encounterRef , Reference locationRef,Reference requesterRef, List<Task.ParameterComponent> taskInputs) {
Task newTask = new Task();
newTask.setStatus(Task.TaskStatus.REQUESTED);
newTask.setIntent(Task.TaskIntent.ORDER);
newTask.setBasedOn(basedOnRefs);
newTask.setFor(forReference);
newTask.setOwner(ownerRef);
newTask.setEncounter(encounterRef);
newTask.setRequester(requesterRef);
newTask.setLocation(locationRef);
if (taskInputs != null) {
newTask.setInput(taskInputs);
}
Expand All @@ -148,17 +147,19 @@ public Task createOrder(Encounter encounter) throws OrderCreationException {

Reference forReference = newReference(encounter.getPatient().getUuid(), FhirConstants.PATIENT);

Reference ownerRef = newReference(config.getLisUserUuid(), FhirConstants.PRACTITIONER);
// Reference ownerRef = newReference(config.getLisUserUuid(), FhirConstants.PRACTITIONER);

Reference encounterRef = newReference(encounter.getUuid(), FhirConstants.ENCOUNTER);

Reference locationRef = newReference(encounter.getLocation().getUuid(), FhirConstants.LOCATION);
// get ordering site location from the encounter obs
Reference locationRef = getLocatonRef(encounter);

Optional<EncounterProvider> requesterProvider = encounter.getActiveEncounterProviders().stream().findFirst();
// Reference locationRef = newReference(encounter.getLocation().getUuid(), FhirConstants.LOCATION);

Reference requesterRef = requesterProvider.isPresent() ?
newReference(requesterProvider.get().getUuid(), FhirConstants.PRACTITIONER) :
null;
// Optional<EncounterProvider> requesterProvider = encounter.getActiveEncounterProviders().stream().findFirst();
Reference requesterRef = getRequesterRef(encounter);

Reference ownerRef = newReference(encounter.getLocation().getUuid(), FhirConstants.ORGANIZATION);

List<Task.ParameterComponent> taskInputs = null;
if (config.addObsAsTaskInput()) {
Expand All @@ -173,12 +174,9 @@ public Task createOrder(Encounter encounter) throws OrderCreationException {
}

// Create Task Resource for given Order
Task newTask = createTask(basedOnRefs, forReference, ownerRef, encounterRef ,taskInputs);
Task newTask = createTask(basedOnRefs, forReference, ownerRef, encounterRef,locationRef, requesterRef, taskInputs);
newTask.setLocation(locationRef);

if (!encounter.getActiveEncounterProviders().isEmpty()) {
newTask.setRequester(requesterRef);
}
newTask.setRequester(requesterRef);

// Save the new Task Resource
try {
Expand All @@ -194,4 +192,25 @@ private Reference newReference(String uuid, String type) {
return new Reference().setReference(type + "/" + uuid).setType(type);
}

private Reference getLocatonRef(Encounter encounter) {
final AtomicReference<Reference> locationRef = new AtomicReference<>(null);
encounter.getAllObs().stream().filter(obs -> obs.getConcept().getUuid().equals(config.getLabOrderingSiteConceptUuid()))
.findFirst().ifPresent(obs -> {
locationRef.set(newReference(obs.getValueText(), FhirConstants.LOCATION));
});
return locationRef.get();
}

private Reference getRequesterRef(Encounter encounter) {
EncounterProvider requesterProvider = encounter.getActiveEncounterProviders().stream()
.findFirst().orElse(null);
Reference requesterRef = null; // Initialize the variable with null
if (requesterProvider != null) {
requesterRef = newReference(requesterProvider.getProvider().getUuid(), FhirConstants.PRACTITIONER);
}

return requesterRef;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class LabOrderManager implements GlobalPropertyListener {

private static final Logger log = LoggerFactory.getLogger(LabOrderManager.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.openmrs.module.labonfhir.api.event;

import javax.jms.Message;

import java.util.HashSet;
import java.util.List;

Expand All @@ -10,13 +11,20 @@
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.param.TokenAndListParam;
import ca.uhn.fhir.rest.param.TokenParam;

import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Identifier;
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.Resource;
import org.hl7.fhir.r4.model.Task;
import org.openmrs.LocationAttribute;
import org.openmrs.LocationAttributeType;
import org.openmrs.api.LocationService;
import org.openmrs.api.context.Daemon;
import org.openmrs.event.EventListener;
import org.openmrs.module.DaemonToken;
import org.openmrs.module.fhir2.FhirConstants;
import org.openmrs.module.fhir2.api.FhirLocationService;
import org.openmrs.module.fhir2.api.FhirTaskService;
import org.openmrs.module.fhir2.api.util.FhirUtils;
Expand All @@ -27,12 +35,17 @@
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import org.openmrs.module.fhir2.api.search.param.TaskSearchParams;

public abstract class LabCreationListener implements EventListener {

private static final Logger log = LoggerFactory.getLogger(EncounterCreationListener.class);

protected static final String MFL_LOCATION_IDENTIFIER_URI = "http://moh.bw.org/ext/location/identifier/mfl-code";

protected static final String MFL_LOCATION_ATTRIBUTE_TYPE_UUID = "8a845a89-6aa5-4111-81d3-0af31c45c002";

private DaemonToken daemonToken;

@Autowired
Expand All @@ -55,6 +68,9 @@ public abstract class LabCreationListener implements EventListener {
@Autowired
private LabOnFhirService labOnFhirService ;

@Autowired
private LocationService locationService;

public DaemonToken getDaemonToken() {
return daemonToken;
}
Expand Down Expand Up @@ -86,15 +102,17 @@ public Bundle createLabBundle(Task task) {
includes.add(new Include("Task:owner"));
includes.add(new Include("Task:encounter"));
includes.add(new Include("Task:based-on"));
includes.add(new Include("Task:location"));
includes.add(new Include("Task:practitioner"));


IBundleProvider labBundle = fhirTaskService.searchForTasks(new TaskSearchParams(null, null, null, uuid, null, null, includes));

Bundle transactionBundle = new Bundle();
transactionBundle.setType(Bundle.BundleType.TRANSACTION);
List<IBaseResource> labResources = labBundle.getAllResources();
if (!task.getLocation().isEmpty() && config.getLabUpdateTriggerObject().equals("Encounter")) {
labResources.add(fhirLocationService.get(FhirUtils.referenceToId(task.getLocation().getReference()).get()));
}
updateMflCodeToLocationAndOrganizationResourceBundle(task, labResources);

for (IBaseResource r : labResources) {
Resource resource = (Resource) r;
Bundle.BundleEntryComponent component = transactionBundle.addEntry();
Expand All @@ -106,6 +124,57 @@ public Bundle createLabBundle(Task task) {
return transactionBundle;
}

protected void updateMflCodeToLocationAndOrganizationResourceBundle(Task task, List<IBaseResource> labResources) {
if (task.getOwner() != null) {
String mflCode = getMflCode(task.getOwner().getReference(), FhirConstants.ORGANIZATION);
if (mflCode != null) {
Identifier mflIdentifier = new Identifier()
.setSystem(MFL_LOCATION_IDENTIFIER_URI)
.setValue(mflCode);
Reference ownerRef = new Reference();
ownerRef.setIdentifier(mflIdentifier);
ownerRef.setType(FhirConstants.ORGANIZATION);
task.setOwner(ownerRef);
}

}

if (task.getLocation() != null) {
String mflCode = getMflCode(task.getLocation().getReference(), FhirConstants.LOCATION);
if (mflCode != null) {
Identifier mflIdentifier = new Identifier()
.setSystem(MFL_LOCATION_IDENTIFIER_URI)
.setValue(mflCode);
Reference locationRef = new Reference();
locationRef.setIdentifier(mflIdentifier);
locationRef.setType(FhirConstants.LOCATION);
task.setLocation(locationRef);
}
}
labResources.removeIf(r->r.getIdElement().getValue().equals(task.getIdElement().getValue()));
labResources.add(task);
}

private String getMflCode(String reference, String referencePath) {
String locationReferenceId = FhirUtils.referenceToId(reference).orElse(null);
String mflCode = null;
if (locationReferenceId != null) {
String locationUuid = locationReferenceId.replace(referencePath + "/", "");
org.openmrs.Location openmrsLocation = locationService.getLocationByUuid(locationUuid);
if (openmrsLocation != null) {
LocationAttributeType mflLocationAttributeType = locationService.getLocationAttributeTypeByUuid(MFL_LOCATION_ATTRIBUTE_TYPE_UUID);
LocationAttribute mflLocationAttribute = openmrsLocation.getActiveAttributes().stream()
.filter(locationAttribute -> locationAttribute.getAttributeType().equals(mflLocationAttributeType))
.findFirst()
.orElse(null);
if (mflLocationAttribute != null) {
mflCode = (String) mflLocationAttribute.getValue();
}
}
}
return mflCode;
}

protected void sendTask(Task task) {
if (task != null) {
if (config.getActivateFhirPush()) {
Expand Down
Loading