Skip to content

Commit

Permalink
fix search to query opencr for unavailable patient(s) in openelis
Browse files Browse the repository at this point in the history
  • Loading branch information
mherman22 committed Sep 17, 2024
1 parent 03855ae commit 4540090
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 100 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.openelisglobal.common.rest.provider;

import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.gclient.ICriterion;
import ca.uhn.fhir.rest.gclient.IOperationUntypedWithInputAndPartialOutput;
import ca.uhn.fhir.rest.gclient.IQuery;
import ca.uhn.fhir.rest.gclient.StringClientParam;
Expand All @@ -16,6 +15,7 @@
import org.apache.commons.validator.GenericValidator;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.r4.model.*;
import org.openelisglobal.common.log.LogEvent;
import org.openelisglobal.common.provider.query.PatientSearchResults;
import org.openelisglobal.common.provider.query.PatientSearchResultsForm;
import org.openelisglobal.common.provider.query.workerObjects.PatientSearchLocalAndExternalWorker;
Expand Down Expand Up @@ -114,6 +114,7 @@ public PatientSearchResultsForm getPatientResults(HttpServletRequest request,
if (request.getParameter("crSearch") != null && request.getParameter("crSearch").contains("true")) {
List<PatientSearchResults> fhirResults = searchPatientInClientRegistry(lastName, firstName, STNumber,
subjectNumber, nationalID, null, guid, dateOfBirth, gender);
LogEvent.logWarn("PatientSearchRestController", "getPatientResults()","final results have been added");
results.addAll(fhirResults);
}

Expand Down Expand Up @@ -148,6 +149,17 @@ private PatientSearchResults getSearchResultsForPatient(Patient patient, String
patientService.getPatientId(patient)));
}

// private PatientSearchResults getSearchResultsForExternalPatient(Patient patient, String referringSitePatientId) {
// return new PatientSearchResults(BigDecimal.valueOf(Long.parseLong(patient.getId())),
// patientService.getFirstName(patient), patientService.getLastName(patient),
// patientService.getGender(patient), patientService.getEnteredDOB(patient),
// patientService.getNationalId(patient), patient.getExternalId(), patientService.getSTNumber(patient),
// patientService.getSubjectNumber(patient), patientService.getGUID(patient),
// referringSitePatientId != null ? referringSitePatientId
// : observationHistoryService.getMostRecentValueForPatient(ObservationType.REFERRERS_PATIENT_ID,
// patientService.getPatientId(patient)));
// }

private PatientSearchWorker getAppropriateWorker(HttpServletRequest request, boolean suppressExternalSearch) {

if (ConfigurationProperties.getInstance().isCaseInsensitivePropertyValueEqual(Property.UseExternalPatientInfo,
Expand Down Expand Up @@ -177,123 +189,141 @@ private List<org.hl7.fhir.r4.model.Patient> parseCRPatientSearchResults(Bundle p

private List<PatientSearchResults> searchPatientInClientRegistry(String lastName, String firstName, String STNumber,
String subjectNumber, String nationalID, String patientID, String guid, String dateOfBirth, String gender) {
LogEvent.logWarn("PatientSearchRestController", "searchPatientInClientRegistry()","searchPatientInClientRegistry method has been reached");
if (isClientRegistryConfigInvalid()) {
return new ArrayList<>();
}

IGenericClient clientRegistry = fhirUtil.getFhirClient(fhirConfig.getClientRegistryServerUrl(),
fhirConfig.getClientRegistryUserName(), fhirConfig.getClientRegistryPassword());
LogEvent.logWarn("PatientSearchRestController", "searchPatientInClientRegistry()","ClientRegistry connected successfully");

List<ICriterion<?>> criterions = buildPatientSearchCriteria(lastName, firstName, STNumber, subjectNumber,
IQuery<IBaseBundle> query = buildPatientSearchQuery(clientRegistry, lastName, firstName, STNumber, subjectNumber,
nationalID, patientID, guid, dateOfBirth, gender);

IQuery<IBaseBundle> query = clientRegistry.search().forResource(org.hl7.fhir.r4.model.Patient.class);

for (int i = 0; i < criterions.size(); i++) {
ICriterion<?> criterion = criterions.get(i);
if (i == 0) {
query.where(criterion);
} else {
query.and(criterion);
}
}
log.info("query has been built with the following parameters: {}", query);

Bundle bundle = query.returnBundle(Bundle.class).execute();
List<org.hl7.fhir.r4.model.Patient> externalPatients = new ArrayList<>();
log.info("get the bundle fullurl: {}", bundle.getEntry().get(0).getFullUrl());
if (bundle.hasEntry()) {
for (Bundle.BundleEntryComponent entry : bundle.getEntry()) {
if (entry.getResource() instanceof org.hl7.fhir.r4.model.Patient) {
externalPatients.add((org.hl7.fhir.r4.model.Patient) entry.getResource());
LogEvent.logWarn("PatientSearchRestController", "searchPatientInClientRegistry()","externalPatients have been added");
}
}
}

List<PatientSearchResults> finalResults = new ArrayList<>();

for (org.hl7.fhir.r4.model.Patient externalPatient : externalPatients) {
PatientSearchResults searchResult;
Patient transformedPatient = SpringContext.getBean(FhirTransformService.class)
.transformToOpenElisPatient(null, externalPatient);

searchResult = getSearchResultsForPatient(transformedPatient, null);
log.info("extracted fhir object: {}", externalPatient.getBirthDate());
Patient transformedPatient = SpringContext.getBean(FhirTransformService.class).transformToOpenElisPatient(externalPatient);
log.info("id of the patient: {}", transformedPatient.getId());
log.info("id of the person: {}", transformedPatient.getPerson().getId());
PatientSearchResults searchResult = getSearchResultsForPatient(transformedPatient, null);
log.info("search result openelis: {}", searchResult);
searchResult.setDataSourceName(MessageUtil.getMessage("patient.cr.source"));
finalResults.add(searchResult);
}

return finalResults;
}

private List<String> fetchCRIdentifiers(IGenericClient clientRegistry, PatientSearchResults patientSearchResult) {
List<String> targetSystems = targetSystemsParam == null ? Collections.emptyList()
: targetSystemsParam.getValuesAsQueryTokens().stream().filter(Objects::nonNull)
.map(StringParam::getValue).collect(Collectors.toList());

// Construct request to external FHIR client
IOperationUntypedWithInputAndPartialOutput<Parameters> identifiersRequest = clientRegistry.operation()
.onType("Patient").named("$ihe-pix").withSearchParameter(Parameters.class, "sourceIdentifier",
new TokenParam("http://openelis-global.org/pat_nationalId",
patientSearchResult.getNationalId()));

if (!targetSystems.isEmpty()) {
identifiersRequest.andSearchParameter("targetSystem", new StringParam(String.join(",", targetSystems)));
}

Parameters crMatchingParams = identifiersRequest.useHttpGet().execute();

return crMatchingParams.getParameter().stream().filter(param -> Objects.equals(param.getName(), "targetId"))
.map(param -> ((Reference) param.getValue()).getReference()).collect(Collectors.toList());
}

private List<org.hl7.fhir.r4.model.Patient> fetchExternalPatients(IGenericClient clientRegistry,
List<String> crIdentifiers) {
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();

return parseCRPatientSearchResults(patientBundle);
}

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

public List<ICriterion<?>> buildPatientSearchCriteria(String lastName, String firstName, String STNumber,
String subjectNumber, String nationalID, String patientID, String guid, String dateOfBirth, String gender) {
public IQuery<IBaseBundle> buildPatientSearchQuery(IGenericClient clientRegistry, String lastName, String firstName, String STNumber,
String subjectNumber, String nationalID, String patientID, String guid,
String dateOfBirth, String gender) {
LogEvent.logWarn("PatientSearchRestController", "buildPatientSearchQuery()","build query reached");

List<ICriterion<?>> criteriaList = new ArrayList<>();
IQuery<IBaseBundle> query = clientRegistry.search().forResource(org.hl7.fhir.r4.model.Patient.class);

if (!GenericValidator.isBlankOrNull(lastName)) {
criteriaList.add(org.hl7.fhir.r4.model.Patient.FAMILY.matches().value(lastName));
query = query.where(org.hl7.fhir.r4.model.Patient.FAMILY.matches().value(lastName));
LogEvent.logWarn("PatientSearchRestController", "buildPatientSearchQuery()","lastname added to query");
}

if (!GenericValidator.isBlankOrNull(firstName)) {
criteriaList.add(org.hl7.fhir.r4.model.Patient.GIVEN.matches().value(firstName));
query = query.where(org.hl7.fhir.r4.model.Patient.GIVEN.matches().value(firstName));
LogEvent.logWarn("PatientSearchRestController", "buildPatientSearchQuery()","first name added to query");
}

// Apply patient identifiers (STNumber, SubjectNumber, NationalId, PatientID,
// GUID)
Map<String, String> identifierMappings = Map.of("stnumber", STNumber, "subjectnumber", subjectNumber,
"nationalid", nationalID, "patientid", patientID, "guid", guid);
// Map for identifier-based queries (STNumber, SubjectNumber, NationalId, PatientID, GUID)
Map<String, String> identifierMappings = new HashMap<>();

// Add non-null identifiers to the map
if (STNumber != null) {
identifierMappings.put("stnumber", STNumber);
}
if (subjectNumber != null) {
identifierMappings.put("subjectnumber", subjectNumber);
}
if (nationalID != null) {
identifierMappings.put("nationalid", nationalID);
}
if (patientID != null) {
identifierMappings.put("patientid", patientID);
}
if (guid != null) {
identifierMappings.put("guid", guid);
}

// Loop through identifiers and add them to the query
for (Map.Entry<String, String> entry : identifierMappings.entrySet()) {
String value = entry.getValue();
if (!GenericValidator.isBlankOrNull(value)) {
criteriaList.add(org.hl7.fhir.r4.model.Patient.IDENTIFIER.exactly()
query = query.where(org.hl7.fhir.r4.model.Patient.IDENTIFIER.exactly()
.systemAndCode("http://openelis-global.org/pat_" + entry.getKey(), value));
LogEvent.logInfo("PatientSearchRestController", "buildPatientSearchQuery()",
"Added identifier (" + entry.getKey() + ") to query.");
}
}

if (!GenericValidator.isBlankOrNull(dateOfBirth)) {
criteriaList.add(org.hl7.fhir.r4.model.Patient.BIRTHDATE.exactly().day(dateOfBirth));
query = query.where(org.hl7.fhir.r4.model.Patient.BIRTHDATE.exactly().day(dateOfBirth));
LogEvent.logWarn("PatientSearchRestController", "buildPatientSearchQuery()","dob added to query");
}

if (!GenericValidator.isBlankOrNull(gender)) {
criteriaList.add(org.hl7.fhir.r4.model.Patient.GENDER.exactly().code(gender));
query = query.where(org.hl7.fhir.r4.model.Patient.GENDER.exactly().code(gender));
LogEvent.logWarn("PatientSearchRestController", "buildPatientSearchQuery()","gender added to query");
}

return query;
}

private List<String> getPatientByPIX(IGenericClient clientRegistry, PatientSearchResults patientSearchResult) {
List<String> targetSystems = targetSystemsParam == null ? Collections.emptyList()
: targetSystemsParam.getValuesAsQueryTokens().stream().filter(Objects::nonNull)
.map(StringParam::getValue).collect(Collectors.toList());

// Construct request to external FHIR client
IOperationUntypedWithInputAndPartialOutput<Parameters> identifiersRequest = clientRegistry.operation()
.onType("Patient").named("$ihe-pix").withSearchParameter(Parameters.class, "sourceIdentifier",
new TokenParam("http://openelis-global.org/pat_nationalId",
patientSearchResult.getNationalId()));

if (!targetSystems.isEmpty()) {
identifiersRequest.andSearchParameter("targetSystem", new StringParam(String.join(",", targetSystems)));
}

return criteriaList;
Parameters crMatchingParams = identifiersRequest.useHttpGet().execute();

return crMatchingParams.getParameter().stream().filter(param -> Objects.equals(param.getName(), "targetId"))
.map(param -> ((Reference) param.getValue()).getReference()).collect(Collectors.toList());
}

private List<org.hl7.fhir.r4.model.Patient> getPatientByCRIdentifiers(IGenericClient clientRegistry,
List<String> crIdentifiers) {
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();

return parseCRPatientSearchResults(patientBundle);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,5 @@ void transformPersistResultValidationFhirObjects(List<Result> deletableList, Lis

Provider transformToProvider(Practitioner practitioner);

Patient transformToOpenElisPatient(Patient patient, org.hl7.fhir.r4.model.Patient externalPatient);
Patient transformToOpenElisPatient(org.hl7.fhir.r4.model.Patient externalPatient);
}
Loading

0 comments on commit 4540090

Please sign in to comment.