Skip to content

Commit

Permalink
Query the CR to retrieve patient data into OpenELIS
Browse files Browse the repository at this point in the history
  • Loading branch information
mherman22 committed Aug 7, 2024
1 parent 57b7604 commit bb27300
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
package org.openelisglobal.common.rest.provider;

import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.gclient.IOperationUntypedWithInputAndPartialOutput;
import ca.uhn.fhir.rest.gclient.StringClientParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenParam;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.validator.GenericValidator;
import org.hl7.fhir.r4.model.*;
import org.openelisglobal.common.provider.query.PatientSearchResults;
import org.openelisglobal.common.provider.query.PatientSearchResultsForm;
import org.openelisglobal.common.provider.query.workerObjects.PatientSearchLocalAndExternalWorker;
Expand All @@ -15,12 +25,16 @@
import org.openelisglobal.common.rest.util.PatientSearchResultsPaging;
import org.openelisglobal.common.util.ConfigurationProperties;
import org.openelisglobal.common.util.ConfigurationProperties.Property;
import org.openelisglobal.common.util.DateUtil;
import org.openelisglobal.dataexchange.fhir.FhirConfig;
import org.openelisglobal.dataexchange.fhir.FhirUtil;
import org.openelisglobal.internationalization.MessageUtil;
import org.openelisglobal.observationhistory.service.ObservationHistoryService;
import org.openelisglobal.observationhistory.service.ObservationHistoryServiceImpl.ObservationType;
import org.openelisglobal.patient.service.PatientService;
import org.openelisglobal.patient.valueholder.Patient;
import org.openelisglobal.person.service.PersonService;
import org.openelisglobal.person.valueholder.Person;
import org.openelisglobal.sample.service.SampleService;
import org.openelisglobal.sample.valueholder.Sample;
import org.openelisglobal.samplehuman.service.SampleHumanService;
Expand All @@ -37,6 +51,10 @@
@RequestMapping(value = "/rest/")
public class PatientSearchRestController extends BaseRestController {

@Autowired
private FhirConfig fhirConfig;
@Autowired
private FhirUtil fhirUtil;
@Autowired
SampleService sampleService;
@Autowired
Expand Down Expand Up @@ -64,10 +82,10 @@ public PatientSearchResultsForm getPatientResults(HttpServletRequest request,
PatientSearchResultsForm form = new PatientSearchResultsForm();

String requestedPage = request.getParameter("page");
Patient patient = getPatientForLabNumber(labNumber);
if (GenericValidator.isBlankOrNull(requestedPage)) {
List<PatientSearchResults> results = new ArrayList<>();
if (!GenericValidator.isBlankOrNull(labNumber)) {
Patient patient = getPatientForLabNumber(labNumber);
if (patient == null || GenericValidator.isBlankOrNull(patient.getId())) {
form.setPatientSearchResults(results);
return form;
Expand All @@ -85,6 +103,47 @@ public PatientSearchResultsForm getPatientResults(HttpServletRequest request,
form.setPatientSearchResults(results);
return form;
}

if (request.getParameter("crResult").contains("true")) {
if (isClientRegistryConfigInvalid()) {
return null;
}

IGenericClient clientRegistry = fhirUtil.getFhirClient(fhirConfig.getClientRegistryServerUrl(),
fhirConfig.getClientRegistryUserName(), fhirConfig.getClientRegistryPassword());

List<String> targetSystems = new ArrayList<>();
IOperationUntypedWithInputAndPartialOutput<Parameters> identifiersRequest = clientRegistry
.operation().onType("Patient").named("$ihe-pix")
.withSearchParameter(Parameters.class, "sourceIdentifier",
new TokenParam("http://openelis-global.org/pat_uuid",
patient.getFhirUuidAsString()))
.andSearchParameter("targetSystem", new StringParam(String.join(",", targetSystems)));

Parameters crMatchingParams = identifiersRequest.useHttpGet().execute();
List<String> crIdentifiers = crMatchingParams.getParameter().stream()
.filter(param -> Objects.equals(param.getName(), "targetId"))
.map(param -> param.getValue().toString()).collect(Collectors.toList());

if (crIdentifiers.isEmpty()) {
return null;
}

Bundle patientBundle = clientRegistry.search().forResource(org.hl7.fhir.r4.model.Patient.class)
.where(new StringClientParam(org.hl7.fhir.r4.model.Patient.SP_RES_ID).matches()
.values(crIdentifiers))
.returnBundle(Bundle.class).execute();

List<org.hl7.fhir.r4.model.Patient> externalPatients = parseCRPatientSearchResults(patientBundle);

for (org.hl7.fhir.r4.model.Patient externalPatient : externalPatients) {
Patient openElisPatient = transformFhirPatientObjectToOpenElisPatientObject(patient,
externalPatient);
PatientSearchResults searchResult = getSearchResultsForPatient(openElisPatient, null);
searchResult.setDataSourceName(MessageUtil.getMessage("patient.cr.source"));
results.add(searchResult);
}
}
}
paging.setDatabaseResults(request, form, results);
} else {
Expand All @@ -94,6 +153,12 @@ public PatientSearchResultsForm getPatientResults(HttpServletRequest request,
return form;
}

private boolean isClientRegistryConfigInvalid() {
return GenericValidator.isBlankOrNull(fhirConfig.getClientRegistryServerUrl())
|| GenericValidator.isBlankOrNull(fhirConfig.getClientRegistryUserName())
|| GenericValidator.isBlankOrNull(fhirConfig.getClientRegistryPassword());
}

private Patient getPatientForLabNumber(String labNumber) {

Sample sample = sampleService.getSampleByAccessionNumber(labNumber);
Expand Down Expand Up @@ -138,4 +203,75 @@ private PatientSearchWorker getAppropriateWorker(HttpServletRequest request, boo
externalID, patientID, guid, dateOfBirth, gender);
}

private List<org.hl7.fhir.r4.model.Patient> parseCRPatientSearchResults(Bundle patientBundle) {
return patientBundle.getEntry().stream().filter(entry -> entry.hasType("Patient"))
.map(entry -> (org.hl7.fhir.r4.model.Patient) entry.getResource()).collect(Collectors.toList());
}

public Patient transformFhirPatientObjectToOpenElisPatientObject(Patient openELISPatient,
org.hl7.fhir.r4.model.Patient fhirPatient) {
for (org.hl7.fhir.r4.model.Identifier identifier : fhirPatient.getIdentifier()) {
String system = identifier.getSystem();
String value = identifier.getValue();
if ("http://openelis-global.org/pat_nationalId".equals(system)) {
openELISPatient.setNationalId(value);
} else if ("http://openelis-global.org/pat_guid".equals(system)) {
openELISPatient.setExternalId(value);
} else if ("http://openelis-global.org/pat_uuid".equals(system)) {
openELISPatient.setFhirUuid(UUID.fromString(value));
}
}

if (!fhirPatient.getName().isEmpty()) {
HumanName name = fhirPatient.getNameFirstRep();
openELISPatient.setEpiFirstName(name.getGivenAsSingleString());
openELISPatient.setEpiLastName(name.getFamily());
}

if (!fhirPatient.getTelecom().isEmpty()) {
ContactPoint telecom = fhirPatient.getTelecomFirstRep();
if (ContactPoint.ContactPointSystem.PHONE.equals(telecom.getSystem())) {
Person person = openELISPatient.getPerson();
if (person == null) {
person = new Person();
openELISPatient.setPerson(person);
}
person.setPrimaryPhone(telecom.getValue());
}
}

switch (fhirPatient.getGender()) {
case MALE:
openELISPatient.setGender("M");
break;
case FEMALE:
openELISPatient.setGender("F");
break;
default:
openELISPatient.setGender(null);
break;
}

if (fhirPatient.getBirthDate() != null) {
openELISPatient.setBirthDate(new Timestamp(fhirPatient.getBirthDate().getTime()));
openELISPatient.setBirthDateForDisplay(
DateUtil.convertTimestampToStringDate(new Timestamp(fhirPatient.getBirthDate().getTime())));
}

if (!fhirPatient.getAddress().isEmpty()) {
Address fhirAddress = fhirPatient.getAddressFirstRep();
Person person = openELISPatient.getPerson();
if (person == null) {
person = new Person();
openELISPatient.setPerson(person);
}
person.setStreetAddress(fhirAddress.getLine().isEmpty() ? null : fhirAddress.getLine().get(0).toString());
person.setCity(fhirAddress.getCity());
person.setState(fhirAddress.getState());
person.setCountry(fhirAddress.getCountry());
}

return openELISPatient;
}

}
37 changes: 18 additions & 19 deletions src/main/java/org/openelisglobal/dataexchange/fhir/FhirConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.rest.client.apache.ApacheRestfulClientFactory;
import ca.uhn.fhir.rest.client.api.IRestfulClientFactory;
import lombok.Getter;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -14,28 +15,41 @@
@Configuration
public class FhirConfig {

@Getter
@Value("${org.openelisglobal.oe.fhir.system:http://openelis-global.org}")
private String oeFhirSystem;

@Getter
@Value("${org.openelisglobal.fhirstore.uri}")
private String localFhirStorePath;

@Getter
@Value("${org.openelisglobal.remote.source.uri}")
private String[] remoteStorePaths;

@Getter
@Value("${org.openelisglobal.fhirstore.username:}")
private String username;

@Getter
@Value("${org.openelisglobal.fhirstore.password:}")
private String password;

@Getter
@Value("${org.openelisglobal.crserver.uri}")
private String clientRegistryServerUrl;

@Getter
@Value("${org.openelisglobal.crserver.username}")
private String clientRegistryUserName;

@Getter
@Value("${org.openelisglobal.crserver.password}")
private String clientRegistryPassword;

@Autowired
CloseableHttpClient httpClient;

public String getLocalFhirStorePath() {
return localFhirStorePath;
}

@Bean
public FhirContext fhirContext() {
FhirContext fhirContext = new FhirContext(FhirVersionEnum.R4);
Expand All @@ -50,19 +64,4 @@ public void configureFhirHttpClient(FhirContext fhirContext) {
fhirContext.setRestfulClientFactory(clientFactory);
}

public String getOeFhirSystem() {
return oeFhirSystem;
}

public String getUsername() {
return username;
}

public String getPassword() {
return password;
}

public String[] getRemoteStorePaths() {
return remoteStorePaths;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@
import org.openelisglobal.typeofsample.valueholder.TypeOfSample;
import org.openelisglobal.typeoftestresult.service.TypeOfTestResultServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
Expand All @@ -124,13 +123,6 @@
@Service
public class FhirTransformServiceImpl implements FhirTransformService {

@Value("${org.openelisglobal.crserver.uri:}")
private String clientRegistryServerUrl;
@Value("${org.openelisglobal.crserver.username:}")
private String clientRegistryUserName;
@Value("${org.openelisglobal.crserver.password:}")
private String clientRegistryPassword;

@Autowired
private FhirConfig fhirConfig;
@Autowired
Expand Down Expand Up @@ -173,7 +165,6 @@ public class FhirTransformServiceImpl implements FhirTransformService {
private AddressPartService addressPartService;
@Autowired
private OrganizationService organizationService;

@Autowired
private FhirUtil fhirUtil;

Expand Down Expand Up @@ -396,11 +387,11 @@ public void transformPersistPatient(PatientManagementInfo patientInfo, boolean i
org.hl7.fhir.r4.model.Patient patient = transformToFhirPatient(patientInfo.getPatientPK());
this.addToOperations(fhirOperations, tempIdGenerator, patient);

if (!GenericValidator.isBlankOrNull(clientRegistryServerUrl)
&& !GenericValidator.isBlankOrNull(clientRegistryUserName)
&& !GenericValidator.isBlankOrNull(clientRegistryPassword)) {
IGenericClient clientRegistry = fhirUtil.getFhirClient(clientRegistryServerUrl, clientRegistryUserName,
clientRegistryPassword);
if (!GenericValidator.isBlankOrNull(fhirConfig.getClientRegistryServerUrl())
&& !GenericValidator.isBlankOrNull(fhirConfig.getClientRegistryUserName())
&& !GenericValidator.isBlankOrNull(fhirConfig.getClientRegistryPassword())) {
IGenericClient clientRegistry = fhirUtil.getFhirClient(fhirConfig.getClientRegistryServerUrl(),
fhirConfig.getClientRegistryUserName(), fhirConfig.getClientRegistryPassword());
try {
if (isCreate) {
clientRegistry.create().resource(patient).execute();
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/languages/message_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4149,6 +4149,7 @@ patient.information = Patient Information
patient.insuranceNumber = Insurance number
patient.labno.search = Lab No
patient.local.source = OpenElis
patient.cr.source = Open Client Registry
patient.management.title = Add/Modify Patient
patient.maritialStatus = Marital Status
patient.medicaidId = Medicaid
Expand Down

0 comments on commit bb27300

Please sign in to comment.