diff --git a/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/BaseDao.java b/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/BaseDao.java index 7a8c95ec16..9d64ccfaca 100644 --- a/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/BaseDao.java +++ b/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/BaseDao.java @@ -52,17 +52,13 @@ import java.util.stream.Stream; import java.util.stream.StreamSupport; -import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.IQueryParameterAnd; import ca.uhn.fhir.model.api.IQueryParameterOr; import ca.uhn.fhir.model.api.IQueryParameterType; -import ca.uhn.fhir.rest.api.QualifiedParamList; import ca.uhn.fhir.rest.api.SortOrderEnum; import ca.uhn.fhir.rest.api.SortSpec; import ca.uhn.fhir.rest.param.DateParam; import ca.uhn.fhir.rest.param.DateRangeParam; -import ca.uhn.fhir.rest.param.HasAndListParam; -import ca.uhn.fhir.rest.param.HasParam; import ca.uhn.fhir.rest.param.ParamPrefixEnum; import ca.uhn.fhir.rest.param.QuantityAndListParam; import ca.uhn.fhir.rest.param.QuantityParam; @@ -86,7 +82,6 @@ import org.hibernate.internal.CriteriaImpl; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.r4.model.Location; -import org.hl7.fhir.r4.model.Observation; import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Practitioner; import org.hl7.fhir.r4.model.codesystems.AdministrativeGender; @@ -95,7 +90,6 @@ import org.openmrs.module.fhir2.api.util.LocalDateTimeFactory; import org.openmrs.module.fhir2.model.FhirConceptSource; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; /** *

@@ -177,10 +171,6 @@ public abstract class BaseDao { @Autowired private LocalDateTimeFactory localDateTimeFactory; - @Autowired - @Qualifier("fhirR4") - private FhirContext fhirContext; - /** * Converts an {@link Iterable} to a {@link Stream} * @@ -453,49 +443,6 @@ protected Optional handleDate(String propertyName, DateParam datePara return Optional.empty(); } - /** - * A handler for a {@link HasParam} - * - * @param propertyName the name of the property in the query to use - * @param hasParam the {@link HasParam} to handle - * @return a {@link Criterion} to be added to the query for the indicate has param - */ - protected Optional handleHas(String propertyName, HasParam hasParam) { - if (hasParam == null) { - return Optional.empty(); - } - ArrayList orValues = new ArrayList<>(); - String targetResourceType = null; - String paramReference = null; - String parameterName = null; - - String paramName = null; - targetResourceType = hasParam.getTargetResourceType(); - - if (targetResourceType.getClass().equals(Observation.class)) { - paramReference = hasParam.getReferenceFieldName(); - parameterName = hasParam.getParameterName(); - paramName = parameterName.replaceAll("\\..*", ""); - hasParam = new HasParam(targetResourceType, paramReference, parameterName, hasParam.getParameterValue()); - orValues.add(hasParam); - orValues.add( - (IQueryParameterType) QualifiedParamList.singleton(null, hasParam.getValueAsQueryToken(fhirContext))); - } - String qualifier = paramName.substring(4); - hasParam.setValueAsQueryToken(fhirContext, FhirConstants.HAS_PROPERTY, qualifier, - hasParam.getValueAsQueryToken(fhirContext)); - orValues.add(hasParam); - return Optional.of(eq(propertyName, orValues)); - } - - protected Optional handleHasParam(@Nonnull String propertyName, HasAndListParam hasAndListParam) { - if (hasAndListParam == null) { - return Optional.empty(); - } - - return handleAndListParam(hasAndListParam, hasParam -> handleHas(propertyName, hasParam)); - } - protected Optional handleQuantity(String propertyName, QuantityParam quantityParam) { if (quantityParam == null) { return Optional.empty(); diff --git a/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/FhirServiceRequestDaoImpl.java b/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/FhirServiceRequestDaoImpl.java index e05f36ff92..1a833b488d 100644 --- a/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/FhirServiceRequestDaoImpl.java +++ b/api/src/main/java/org/openmrs/module/fhir2/api/dao/impl/FhirServiceRequestDaoImpl.java @@ -11,6 +11,7 @@ import static org.hibernate.criterion.Restrictions.and; import static org.hibernate.criterion.Restrictions.or; +import static org.hibernate.criterion.Restrictions.eq; import java.util.Optional; import java.util.stream.Stream; @@ -18,12 +19,17 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.HasAndListParam; +import ca.uhn.fhir.rest.param.HasOrListParam; +import ca.uhn.fhir.rest.param.HasParam; import ca.uhn.fhir.rest.param.ReferenceAndListParam; import ca.uhn.fhir.rest.param.TokenAndListParam; +import org.hibernate.criterion.Subqueries; import lombok.AccessLevel; import lombok.Setter; import org.hibernate.Criteria; import org.hibernate.criterion.Criterion; +import org.hibernate.criterion.DetachedCriteria; +import org.openmrs.Obs; import org.openmrs.TestOrder; import org.openmrs.module.fhir2.FhirConstants; import org.openmrs.module.fhir2.api.dao.FhirServiceRequestDao; @@ -60,8 +66,8 @@ protected void setupSearchParams(Criteria criteria, SearchParameterMap theParams (ReferenceAndListParam) participantReference.getParam())); break; case FhirConstants.HAS_PROPERTY: - entry.getValue().forEach(hasParameter -> handleHasParam(hasParameter.getPropertyName(), - (HasAndListParam) hasParameter.getParam()).ifPresent(criteria::add)); + entry.getValue().forEach(hasParameter -> handleHasAndParam(criteria, + (HasAndListParam) hasParameter.getParam())); break; case FhirConstants.DATE_RANGE_SEARCH_HANDLER: entry.getValue().forEach(dateRangeParam -> handleDateRange((DateRangeParam) dateRangeParam.getParam()) @@ -95,5 +101,54 @@ private Optional handleDateRange(DateRangeParam dateRangeParam) { Optional.of(or(toCriteriaArray(Stream.of(handleDate("dateStopped", dateRangeParam.getUpperBound()), handleDate("autoExpireDate", dateRangeParam.getUpperBound()))))))))); } + + private void handleHasAndParam(Criteria criteria, HasAndListParam hasAndListParam) { + if (hasAndListParam != null) { + + if (lacksAlias(criteria, "obss")) { + criteria.createAlias("obs", "aliasObss"); + } + + DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Obs.class); + + handleAndListParam(hasAndListParam, param -> { + if ( param.getValueAsQueryToken(fhirContext) != null) { + if (lacksAlias(criteria, "o")) { + criteria.createAlias("aliasObss.category", "o"); + } + } + + return Optional.of(eq("o.category", param.getValueAsQueryToken(fhirContext))); + }).ifPresent(criteria::add); + + hasAndListParam.getValuesAsQueryTokens().stream().map(this::handleHasOrParam).filter(Optional::isPresent) + .flatMap(Optional::get).forEach(detachedCriteria::add); + + + criteria.add(Subqueries.exists(detachedCriteria)); + } + } + private Optional> handleHasOrParam(HasOrListParam hasOrListParam) { + if (hasOrListParam == null) { + return Optional.empty(); + } + + return Optional.of(hasOrListParam.getValuesAsQueryTokens().stream().map(this::handleHasParam).filter( + Optional::isPresent).map(Optional::get)); + } + + private Optional handleHasParam(HasParam hasParam) { + if (hasParam == null) { + return Optional.empty(); + } + + if (!FhirConstants.OBSERVATION.equals(hasParam.getTargetResourceType())) { + return Optional.empty(); + } + if(!(hasParam.getQueryParameterQualifier().equals(":not"))){ + return Optional.empty(); + } + return Optional.empty(); + } }