Skip to content

Commit

Permalink
FM2-479: Support querying by encounter type as a chained parameter (#419
Browse files Browse the repository at this point in the history
)
  • Loading branch information
Muta-Jonathan authored Aug 23, 2022
1 parent 126738b commit 00a3a3b
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ protected void setupSearchParams(Criteria criteria, SearchParameterMap theParams
.forEach(param -> handlePatientReference(criteria, (ReferenceAndListParam) param.getParam()));
break;
case FhirConstants.ENCOUNTER_REFERENCE_SEARCH_HANDLER:
entry.getValue().forEach(e -> handleEncounterReference("e", (ReferenceAndListParam) e.getParam())
.ifPresent(c -> createAlias(criteria, "encounter", "e").add(c)));
entry.getValue()
.forEach(e -> handleEncounterReference(criteria, (ReferenceAndListParam) e.getParam(), "e"));
break;
case FhirConstants.MEDICATION_REQUEST_REFERENCE_SEARCH_HANDLER:
entry.getValue()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.internal.CriteriaImpl;
import org.hl7.fhir.dstu3.model.Encounter;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r4.model.Location;
import org.hl7.fhir.r4.model.Patient;
Expand Down Expand Up @@ -493,14 +494,36 @@ protected Optional<Criterion> handleQuantity(@Nonnull String propertyName, Quant
return handleAndListParam(quantityAndListParam, quantityParam -> handleQuantity(propertyName, quantityParam));
}

protected Optional<Criterion> handleEncounterReference(@Nonnull String encounterAlias,
ReferenceAndListParam encounterReference) {
protected void handleEncounterReference(Criteria criteria, ReferenceAndListParam encounterReference,
@Nonnull String encounterAlias) {
handleEncounterReference(criteria, encounterReference, encounterAlias, "encounter");
}

protected void handleEncounterReference(Criteria criteria, ReferenceAndListParam encounterReference,
@Nonnull String encounterAlias, @Nonnull String associationPath) {
if (encounterReference == null) {
return Optional.empty();
return;
}

return handleAndListParam(encounterReference,
token -> Optional.of(eq(String.format("%s.uuid", encounterAlias), token.getIdPart())));
if (lacksAlias(criteria, encounterAlias)) {
criteria.createAlias(associationPath, encounterAlias);
}

handleAndListParam(encounterReference, token -> {
if (token.getChain() != null) {
switch (token.getChain()) {
case Encounter.SP_TYPE:
if (lacksAlias(criteria, "et")) {
criteria.createAlias(String.format("%s.encounterType", encounterAlias), "et");
}
return propertyLike("et.uuid", new StringParam(token.getValue(), true));
}
} else {
return Optional.of(eq(String.format("%s.uuid", encounterAlias), token.getIdPart()));
}

return Optional.empty();
}).ifPresent(criteria::add);
}

protected Optional<Criterion> handleGender(@Nonnull String propertyName, TokenAndListParam gender) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ protected void setupSearchParams(Criteria criteria, SearchParameterMap theParams
theParams.getParameters().forEach(entry -> {
switch (entry.getKey()) {
case FhirConstants.ENCOUNTER_REFERENCE_SEARCH_HANDLER:
entry.getValue().forEach(param -> handleEncounterReference("e", (ReferenceAndListParam) param.getParam())
.ifPresent(c -> criteria.createAlias("encounter", "e").add(c)));
entry.getValue().forEach(
param -> handleEncounterReference(criteria, (ReferenceAndListParam) param.getParam(), "e"));
break;
case FhirConstants.PATIENT_REFERENCE_SEARCH_HANDLER:
entry.getValue().forEach(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ protected void setupSearchParams(Criteria criteria, SearchParameterMap theParams
theParams.getParameters().forEach(entry -> {
switch (entry.getKey()) {
case FhirConstants.ENCOUNTER_REFERENCE_SEARCH_HANDLER:
entry.getValue().forEach(e -> handleEncounterReference("e", (ReferenceAndListParam) e.getParam())
.ifPresent(c -> criteria.createAlias("encounter", "e").add(c)));
entry.getValue()
.forEach(e -> handleEncounterReference(criteria, (ReferenceAndListParam) e.getParam(), "e"));
break;
case FhirConstants.PATIENT_REFERENCE_SEARCH_HANDLER:
entry.getValue().forEach(patientReference -> handlePatientReference(criteria,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ public class FhirObservationDaoImpl extends BaseFhirDao<Obs> implements FhirObse
@Override
public List<String> getSearchResultUuids(@Nonnull SearchParameterMap theParams) {
if (!theParams.getParameters(FhirConstants.LASTN_OBSERVATION_SEARCH_HANDLER).isEmpty()) {

Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(typeToken.getRawType());

setupSearchParams(criteria, theParams);
Expand Down Expand Up @@ -99,8 +98,8 @@ protected void setupSearchParams(Criteria criteria, SearchParameterMap theParams
theParams.getParameters().forEach(entry -> {
switch (entry.getKey()) {
case FhirConstants.ENCOUNTER_REFERENCE_SEARCH_HANDLER:
entry.getValue().forEach(p -> handleEncounterReference("e", (ReferenceAndListParam) p.getParam())
.ifPresent(c -> criteria.createAlias("encounter", "e").add(c)));
entry.getValue()
.forEach(p -> handleEncounterReference(criteria, (ReferenceAndListParam) p.getParam(), "e"));
break;
case FhirConstants.PATIENT_REFERENCE_SEARCH_HANDLER:
entry.getValue().forEach(patientReference -> handlePatientReference(criteria,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ protected void setupSearchParams(Criteria criteria, SearchParameterMap theParams
theParams.getParameters().forEach(entry -> {
switch (entry.getKey()) {
case FhirConstants.ENCOUNTER_REFERENCE_SEARCH_HANDLER:
entry.getValue().forEach(param -> handleEncounterReference("e", (ReferenceAndListParam) param.getParam())
.ifPresent(c -> criteria.createAlias("encounter", "e").add(c)));
entry.getValue().forEach(
param -> handleEncounterReference(criteria, (ReferenceAndListParam) param.getParam(), "e"));
break;
case FhirConstants.PATIENT_REFERENCE_SEARCH_HANDLER:
entry.getValue().forEach(patientReference -> handlePatientReference(criteria,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.apache.commons.collections.CollectionUtils;
import org.hl7.fhir.convertors.conv30_40.Observation30_40;
import org.hl7.fhir.dstu3.model.DiagnosticReport;
import org.hl7.fhir.dstu3.model.Encounter;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.Observation;
import org.hl7.fhir.dstu3.model.OperationOutcome;
Expand Down Expand Up @@ -94,7 +95,8 @@ public OperationOutcome deleteObservationResource(@IdParam @Nonnull IdType id) {

@Search
public IBundleProvider searchObservations(
@OptionalParam(name = Observation.SP_ENCOUNTER) ReferenceAndListParam encounterReference,
@OptionalParam(name = Observation.SP_ENCOUNTER, chainWhitelist = { "",
Encounter.SP_TYPE }, targetTypes = Encounter.class) ReferenceAndListParam encounterReference,
@OptionalParam(name = Observation.SP_SUBJECT, chainWhitelist = { "", Patient.SP_IDENTIFIER, Patient.SP_GIVEN,
Patient.SP_FAMILY,
Patient.SP_NAME }, targetTypes = Patient.class) ReferenceAndListParam patientReference,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ public OperationOutcome deleteObservationResource(@IdParam @Nonnull IdType id) {

@Search
public IBundleProvider searchObservations(
@OptionalParam(name = Observation.SP_ENCOUNTER, chainWhitelist = {
"" }, targetTypes = Encounter.class) ReferenceAndListParam encounterReference,
@OptionalParam(name = Observation.SP_ENCOUNTER, chainWhitelist = { "",
Encounter.SP_TYPE }, targetTypes = Encounter.class) ReferenceAndListParam encounterReference,
@OptionalParam(name = Observation.SP_SUBJECT, chainWhitelist = { "", Patient.SP_IDENTIFIER, Patient.SP_GIVEN,
Patient.SP_FAMILY,
Patient.SP_NAME }, targetTypes = Patient.class) ReferenceAndListParam patientReference,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ public class ObservationSearchQueryTest extends BaseModuleContextSensitiveTest {

private static final String ENCOUNTER_UUID_TWO = "6519d653-393b-4118-9c83-a3715b82d4ac";

private static final String ENCOUNTER_TYPE_UUID = "07000be2-26b6-4cce-8b40-866d8435b613";

private static final String MEMBER_UUID = "744b91f8-bdbc-4950-833b-002244e9fa2b";

private static final String OBS_SNOMED_CODE = "2332523";
Expand Down Expand Up @@ -667,6 +669,25 @@ public void searchForObs_shouldReturnObsByEncounter() {
assertThat(resultList.size(), equalTo(10));
}

@Test
public void searchForObs_shouldReturnObsByEncounterType() {
ReferenceAndListParam encounterReference = new ReferenceAndListParam()
.addAnd(new ReferenceOrListParam().add(new ReferenceParam().setValue(ENCOUNTER_TYPE_UUID).setChain("type")));

SearchParameterMap theParams = new SearchParameterMap();
theParams.addParameter(FhirConstants.ENCOUNTER_REFERENCE_SEARCH_HANDLER, encounterReference);

IBundleProvider results = search(theParams);

assertThat(results, notNullValue());
assertThat(results.size(), equalTo(14));

List<IBaseResource> resultList = get(results);

assertThat(resultList, notNullValue());
assertThat(resultList.size(), equalTo(10));
}

@Test
public void searchForObs_shouldReturnObsByCategory() {
TokenAndListParam categories = new TokenAndListParam().addAnd(new TokenParam().setValue("laboratory"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.DiagnosticReport;
import org.hl7.fhir.r4.model.Encounter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -175,6 +176,26 @@ public void searchObservations_shouldReturnMatchingObservationsWhenPatientParamI
assertThat(resultList.get(0).getIdElement().getIdPart(), equalTo(OBSERVATION_UUID));
}

@Test
public void searchObservations_shouldReturnMatchingObservationsWhenEncounterParamIsSpecified() {
when(observationService.searchForObservations(any()))
.thenReturn(new MockIBundleProvider<>(Collections.singletonList(observation), 10, 1));

ReferenceAndListParam encounterParam = new ReferenceAndListParam();
encounterParam.addValue(new ReferenceOrListParam().add(new ReferenceParam().setChain(Encounter.SP_TYPE)));

IBundleProvider results = resourceProvider.searchObservations(encounterParam, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null);

List<IBaseResource> resultList = get(results, 1, 5);

assertThat(results, notNullValue());
assertThat(resultList, hasSize(equalTo(1)));
assertThat(resultList.get(0), notNullValue());
assertThat(resultList.get(0).fhirType(), equalTo(FhirConstants.OBSERVATION));
assertThat(resultList.get(0).getIdElement().getIdPart(), equalTo(OBSERVATION_UUID));
}

@Test
public void searchObservations_shouldAddRelatedResourcesWhenIncluded() {
HashSet<Include> includes = new HashSet<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import lombok.Getter;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.DiagnosticReport;
import org.hl7.fhir.r4.model.Encounter;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Observation;
import org.hl7.fhir.r4.model.OperationOutcome;
Expand Down Expand Up @@ -170,6 +171,26 @@ public void searchObservations_shouldReturnMatchingObservationsWhenPatientParamI
assertThat(resultList.get(0).getIdElement().getIdPart(), equalTo(OBSERVATION_UUID));
}

@Test
public void searchObservations_shouldReturnMatchingObservationsWhenEncounterParamIsSpecified() {
when(observationService.searchForObservations(any()))
.thenReturn(new MockIBundleProvider<>(Collections.singletonList(observation), 10, 1));

ReferenceAndListParam encounterParam = new ReferenceAndListParam();
encounterParam.addValue(new ReferenceOrListParam().add(new ReferenceParam().setChain(Encounter.SP_TYPE)));

IBundleProvider results = resourceProvider.searchObservations(encounterParam, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null);

List<IBaseResource> resultList = get(results);

assertThat(results, notNullValue());
assertThat(resultList, hasSize(equalTo(1)));
assertThat(resultList.get(0), notNullValue());
assertThat(resultList.get(0).fhirType(), equalTo(FhirConstants.OBSERVATION));
assertThat(resultList.get(0).getIdElement().getIdPart(), equalTo(OBSERVATION_UUID));
}

@Test
public void searchObservations_shouldAddRelatedResourcesWhenIncluded() {
HashSet<Include> includes = new HashSet<>();
Expand Down

0 comments on commit 00a3a3b

Please sign in to comment.