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();
+ }
}