diff --git a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/common/BaseMeasureEvaluation.java b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/common/BaseMeasureEvaluation.java index d2eb82753..e7ae51cca 100644 --- a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/common/BaseMeasureEvaluation.java +++ b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/common/BaseMeasureEvaluation.java @@ -3,7 +3,6 @@ import java.util.List; import java.util.Objects; import org.hl7.elm.r1.VersionedIdentifier; -import org.hl7.fhir.instance.model.api.IBaseParameters; import org.opencds.cqf.cql.engine.execution.CqlEngine; import org.opencds.cqf.cql.engine.runtime.Interval; import org.opencds.cqf.fhir.cql.LibraryEngine; @@ -17,7 +16,6 @@ public abstract class BaseMeasureEvaluation protected MeasureT measure; protected LibraryEngine libraryEngine; protected String measurementPeriodParameterName; - protected IBaseParameters parameters; protected VersionedIdentifier versionIdentifier; protected BaseMeasureEvaluation( @@ -26,8 +24,7 @@ protected BaseMeasureEvaluation( MeasureDefBuilder measureDefBuilder, MeasureReportBuilder measureReportBuilder, LibraryEngine libraryEngine, - VersionedIdentifier versionIdentifier, - IBaseParameters parameters) { + VersionedIdentifier versionIdentifier) { this( context, measure, @@ -35,8 +32,7 @@ protected BaseMeasureEvaluation( measureReportBuilder, MeasureConstants.MEASUREMENT_PERIOD_PARAMETER_NAME, libraryEngine, - versionIdentifier, - parameters); + versionIdentifier); } protected BaseMeasureEvaluation( @@ -46,8 +42,7 @@ protected BaseMeasureEvaluation( MeasureReportBuilder measureReportBuilder, String measurementPeriodParameterName, LibraryEngine libraryEngine, - VersionedIdentifier versionIdentifier, - IBaseParameters parameters) { + VersionedIdentifier versionIdentifier) { this.context = Objects.requireNonNull(context, "context is a required argument"); this.measure = Objects.requireNonNull(measure, "measure is a required argument"); this.measureDefBuilder = Objects.requireNonNull(measureDefBuilder, "measureDefBuilder is a required argument"); @@ -56,7 +51,6 @@ protected BaseMeasureEvaluation( this.measurementPeriodParameterName = Objects.requireNonNull( measurementPeriodParameterName, "measurementPeriodParameterName is a required argument"); this.libraryEngine = libraryEngine; - this.parameters = parameters; this.versionIdentifier = versionIdentifier; } @@ -64,9 +58,8 @@ public MeasureReportT evaluate( MeasureEvalType measureEvalType, List subjectIds, LibraryEngine libraryEngine, - VersionedIdentifier id, - IBaseParameters parameters) { - return this.evaluate(measureEvalType, subjectIds, null, libraryEngine, id, parameters); + VersionedIdentifier id) { + return this.evaluate(measureEvalType, subjectIds, null, libraryEngine, id); } public MeasureReportT evaluate( @@ -74,16 +67,14 @@ public MeasureReportT evaluate( List subjectIds, Interval measurementPeriod, LibraryEngine libraryEngine, - VersionedIdentifier id, - IBaseParameters parameters) { + VersionedIdentifier id) { Objects.requireNonNull(subjectIds, "subjectIds is a required parameter"); Objects.requireNonNull(measureEvalType, "measureEvalType is a required parameter"); MeasureDef measureDef = this.measureDefBuilder.build(measure); MeasureEvaluator measureEvaluation = new MeasureEvaluator(context, this.measurementPeriodParameterName, libraryEngine); - measureDef = - measureEvaluation.evaluate(measureDef, measureEvalType, subjectIds, measurementPeriod, parameters, id); + measureDef = measureEvaluation.evaluate(measureDef, measureEvalType, subjectIds, measurementPeriod, id); Interval measurementPeriodInterval; if (measurementPeriod == null) { diff --git a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/common/MeasureEvaluator.java b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/common/MeasureEvaluator.java index 7f5f865d6..3716b08a2 100644 --- a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/common/MeasureEvaluator.java +++ b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/common/MeasureEvaluator.java @@ -30,7 +30,6 @@ import org.hl7.elm.r1.NamedTypeSpecifier; import org.hl7.elm.r1.ParameterDef; import org.hl7.elm.r1.VersionedIdentifier; -import org.hl7.fhir.instance.model.api.IBaseParameters; import org.opencds.cqf.cql.engine.execution.CqlEngine; import org.opencds.cqf.cql.engine.execution.EvaluationResult; import org.opencds.cqf.cql.engine.execution.ExpressionResult; @@ -83,7 +82,6 @@ public MeasureDef evaluate( MeasureEvalType measureEvalType, List subjectIds, @Nullable Interval measurementPeriod, - IBaseParameters parameters, VersionedIdentifier versionedIdentifier) { Objects.requireNonNull(measureDef, "measureDef is a required argument"); Objects.requireNonNull(subjectIds, "subjectIds is a required argument"); @@ -97,37 +95,17 @@ public MeasureDef evaluate( case PATIENT: case SUBJECT: return this.evaluate( - measureDef, - MeasureReportType.INDIVIDUAL, - subjectIds, - parameters, - versionedIdentifier, - zonedDateTime); + measureDef, MeasureReportType.INDIVIDUAL, subjectIds, versionedIdentifier, zonedDateTime); case SUBJECTLIST: return this.evaluate( - measureDef, - MeasureReportType.SUBJECTLIST, - subjectIds, - parameters, - versionedIdentifier, - zonedDateTime); + measureDef, MeasureReportType.SUBJECTLIST, subjectIds, versionedIdentifier, zonedDateTime); case PATIENTLIST: // DSTU3 Only return this.evaluate( - measureDef, - MeasureReportType.PATIENTLIST, - subjectIds, - parameters, - versionedIdentifier, - zonedDateTime); + measureDef, MeasureReportType.PATIENTLIST, subjectIds, versionedIdentifier, zonedDateTime); case POPULATION: return this.evaluate( - measureDef, - MeasureReportType.SUMMARY, - subjectIds, - parameters, - versionedIdentifier, - zonedDateTime); + measureDef, MeasureReportType.SUMMARY, subjectIds, versionedIdentifier, zonedDateTime); default: // never hit because this value is set upstream throw new IllegalArgumentException( @@ -300,7 +278,6 @@ protected MeasureDef evaluate( MeasureDef measureDef, MeasureReportType type, List subjectIds, - IBaseParameters parameters, VersionedIdentifier id, ZonedDateTime zonedDateTime) { var subjectSize = subjectIds.size(); @@ -321,8 +298,8 @@ protected MeasureDef evaluate( String subjectIdPart = subjectInfo.getRight(); context.getState().setContextValue(subjectTypePart, subjectIdPart); - EvaluationResult result = libraryEngine.getEvaluationResult( - id, subjectId, parameters, null, null, null, zonedDateTime, context); + EvaluationResult result = + libraryEngine.getEvaluationResult(id, subjectId, null, null, null, null, zonedDateTime, context); evaluateSubject(measureDef, subjectTypePart, subjectIdPart, subjectSize, type, result); } diff --git a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureEvaluation.java b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureEvaluation.java index a1887d257..434ef6012 100644 --- a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureEvaluation.java +++ b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureEvaluation.java @@ -4,7 +4,6 @@ import org.hl7.fhir.dstu3.model.DomainResource; import org.hl7.fhir.dstu3.model.Measure; import org.hl7.fhir.dstu3.model.MeasureReport; -import org.hl7.fhir.dstu3.model.Parameters; import org.opencds.cqf.cql.engine.execution.CqlEngine; import org.opencds.cqf.fhir.cql.LibraryEngine; import org.opencds.cqf.fhir.cr.measure.common.BaseMeasureEvaluation; @@ -15,18 +14,13 @@ public class Dstu3MeasureEvaluation extends BaseMeasureEvaluation { public Dstu3MeasureEvaluation( - CqlEngine context, - Measure measure, - LibraryEngine libraryEngine, - VersionedIdentifier versionIdentifier, - Parameters parameters) { + CqlEngine context, Measure measure, LibraryEngine libraryEngine, VersionedIdentifier versionIdentifier) { super( context, measure, new Dstu3MeasureDefBuilder(), new Dstu3MeasureReportBuilder(), libraryEngine, - versionIdentifier, - parameters); + versionIdentifier); } } diff --git a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureProcessor.java b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureProcessor.java index f86be0637..910399d3e 100644 --- a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureProcessor.java +++ b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureProcessor.java @@ -1,7 +1,5 @@ package org.opencds.cqf.fhir.cr.measure.dstu3; -import static org.opencds.cqf.fhir.cr.measure.constant.MeasureConstants.MEASUREMENT_PERIOD_PARAMETER_NAME; - import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -12,13 +10,11 @@ import org.cqframework.cql.cql2elm.CqlIncludeException; import org.cqframework.cql.cql2elm.model.CompiledLibrary; import org.hl7.elm.r1.VersionedIdentifier; -import org.hl7.fhir.dstu3.model.DateTimeType; import org.hl7.fhir.dstu3.model.IdType; import org.hl7.fhir.dstu3.model.Library; import org.hl7.fhir.dstu3.model.Measure; import org.hl7.fhir.dstu3.model.MeasureReport; import org.hl7.fhir.dstu3.model.Parameters; -import org.hl7.fhir.dstu3.model.Period; import org.hl7.fhir.instance.model.api.IBaseBundle; import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.opencds.cqf.cql.engine.fhir.model.Dstu3FhirModelResolver; @@ -138,22 +134,8 @@ protected MeasureReport evaluateMeasure( var subjects = subjectProvider.getSubjects(actualRepo, evalType, subjectIds).collect(Collectors.toList()); var libraryEngine = new LibraryEngine(repository, this.measureEvaluationOptions.getEvaluationSettings()); - var params = makeParameters(measurementPeriod); - Dstu3MeasureEvaluation measureEvaluator = - new Dstu3MeasureEvaluation(context, measure, libraryEngine, id, params); - return measureEvaluator.evaluate(evalType, subjects, measurementPeriod, libraryEngine, id, params); - } - - public Parameters makeParameters(Interval measurementPeriod) { - Parameters parameters = new Parameters(); - if (measurementPeriod != null) { - - Period period = new Period(); - period.setStartElement(new DateTimeType(measurementPeriod.getStart().toString())); - period.setEndElement(new DateTimeType(measurementPeriod.getEnd().toString())); - parameters.addParameter().setName(MEASUREMENT_PERIOD_PARAMETER_NAME).setValue(period); - } - return parameters; + Dstu3MeasureEvaluation measureEvaluator = new Dstu3MeasureEvaluation(context, measure, libraryEngine, id); + return measureEvaluator.evaluate(evalType, subjects, measurementPeriod, libraryEngine, id); } protected MeasureReportType evalTypeToReportType(MeasureEvalType measureEvalType) { diff --git a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/r4/R4MeasureEvaluation.java b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/r4/R4MeasureEvaluation.java index 68e6dbef9..bd0da1d0a 100644 --- a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/r4/R4MeasureEvaluation.java +++ b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/r4/R4MeasureEvaluation.java @@ -4,7 +4,6 @@ import org.hl7.fhir.r4.model.DomainResource; import org.hl7.fhir.r4.model.Measure; import org.hl7.fhir.r4.model.MeasureReport; -import org.hl7.fhir.r4.model.Parameters; import org.opencds.cqf.cql.engine.execution.CqlEngine; import org.opencds.cqf.fhir.cql.LibraryEngine; import org.opencds.cqf.fhir.cr.measure.common.BaseMeasureEvaluation; @@ -15,18 +14,13 @@ public class R4MeasureEvaluation extends BaseMeasureEvaluation { public R4MeasureEvaluation( - CqlEngine context, - Measure measure, - LibraryEngine libraryEngine, - VersionedIdentifier versionIdentifier, - Parameters parameters) { + CqlEngine context, Measure measure, LibraryEngine libraryEngine, VersionedIdentifier versionIdentifier) { super( context, measure, new R4MeasureDefBuilder(), new R4MeasureReportBuilder(), libraryEngine, - versionIdentifier, - parameters); + versionIdentifier); } } diff --git a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/r4/R4MeasureProcessor.java b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/r4/R4MeasureProcessor.java index d24d46759..d7280d3ee 100644 --- a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/r4/R4MeasureProcessor.java +++ b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/r4/R4MeasureProcessor.java @@ -1,7 +1,5 @@ package org.opencds.cqf.fhir.cr.measure.r4; -import static org.opencds.cqf.fhir.cr.measure.constant.MeasureConstants.MEASUREMENT_PERIOD_PARAMETER_NAME; - import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import jakarta.annotation.Nullable; import java.time.ZonedDateTime; @@ -164,19 +162,8 @@ protected MeasureReport evaluateMeasure( } // Library Evaluate var libraryEngine = new LibraryEngine(repository, this.measureEvaluationOptions.getEvaluationSettings()); - var params = makeParameters(measurementPeriod); - R4MeasureEvaluation measureEvaluator = new R4MeasureEvaluation(context, measure, libraryEngine, id, params); - return measureEvaluator.evaluate(evalType, subjectIds, measurementPeriod, libraryEngine, id, params); - } - - public Parameters makeParameters(Interval measurementPeriod) { - Parameters parameters = new Parameters(); - if (measurementPeriod != null) { - var helper = new R4DateHelper(); - parameters.setParameter( - MEASUREMENT_PERIOD_PARAMETER_NAME, helper.buildMeasurementPeriod(measurementPeriod)); - } - return parameters; + R4MeasureEvaluation measureEvaluator = new R4MeasureEvaluation(context, measure, libraryEngine, id); + return measureEvaluator.evaluate(evalType, subjectIds, measurementPeriod, libraryEngine, id); } protected Measure resolveByUrl(CanonicalType url) { diff --git a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/r4/utils/R4DateHelper.java b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/r4/utils/R4DateHelper.java index 2ebbce9d4..620d9405a 100644 --- a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/r4/utils/R4DateHelper.java +++ b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/r4/utils/R4DateHelper.java @@ -6,6 +6,7 @@ import org.opencds.cqf.cql.engine.runtime.Date; import org.opencds.cqf.cql.engine.runtime.DateTime; import org.opencds.cqf.cql.engine.runtime.Interval; +import org.opencds.cqf.cql.engine.runtime.Precision; public class R4DateHelper { @@ -38,6 +39,8 @@ public Period buildMeasurementPeriod(Interval measurementPeriodInterval) { private DateTime convertToDateTime(ZonedDateTime zonedDateTime) { final OffsetDateTime offsetDateTime = zonedDateTime.toOffsetDateTime(); - return new DateTime(offsetDateTime); + final DateTime convertedDateTime = new DateTime(offsetDateTime); + convertedDateTime.setPrecision(Precision.SECOND); + return convertedDateTime; } } diff --git a/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureEvaluationTest.java b/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureEvaluationTest.java index 978972809..04517661c 100644 --- a/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureEvaluationTest.java +++ b/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureEvaluationTest.java @@ -244,14 +244,13 @@ private MeasureReport runTest( var lib = engine.getEnvironment().getLibraryManager().resolveLibrary(id); engine.getState().init(lib.getLibrary()); var libraryEngine = new LibraryEngine(repository, this.evaluationOptions.getEvaluationSettings()); - Dstu3MeasureEvaluation evaluation = new Dstu3MeasureEvaluation(engine, measure, libraryEngine, id, null); + Dstu3MeasureEvaluation evaluation = new Dstu3MeasureEvaluation(engine, measure, libraryEngine, id); MeasureReport report = evaluation.evaluate( subjectIds.size() == 1 ? MeasureEvalType.PATIENT : MeasureEvalType.POPULATION, subjectIds, measurementPeriod, libraryEngine, - id, - null); + id); assertNotNull(report); // Simulate sending it across the wire diff --git a/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/r4/R4DateHelperTest.java b/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/r4/R4DateHelperTest.java index d8f8cfae4..dda535d0f 100644 --- a/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/r4/R4DateHelperTest.java +++ b/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/r4/R4DateHelperTest.java @@ -1,17 +1,27 @@ package org.opencds.cqf.fhir.cr.measure.r4; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.Month; import java.time.OffsetDateTime; +import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; -import org.junit.Test; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.opencds.cqf.cql.engine.runtime.Date; import org.opencds.cqf.cql.engine.runtime.DateTime; import org.opencds.cqf.cql.engine.runtime.Interval; +import org.opencds.cqf.cql.engine.runtime.Precision; import org.opencds.cqf.fhir.cr.measure.r4.utils.R4DateHelper; public class R4DateHelperTest { @@ -65,4 +75,40 @@ public void checkNull() { assertTrue(e.getMessage().contains("Measurement period should be an interval of CQL DateTime or Date")); } } + + public static Stream zonedDateTimesParams() { + return Stream.of( + Arguments.of( + LocalDate.of(2020, Month.JANUARY, 1).atStartOfDay(ZoneId.systemDefault()), Precision.SECOND), + Arguments.of( + LocalDateTime.of(2020, Month.JANUARY, 1, 12, 0, 0).atZone(ZoneId.systemDefault()), + Precision.SECOND), + Arguments.of( + LocalDateTime.of(2020, Month.JANUARY, 1, 12, 23, 0).atZone(ZoneId.systemDefault()), + Precision.SECOND), + Arguments.of( + LocalDateTime.of(2020, Month.JANUARY, 1, 0, 23, 0).atZone(ZoneId.systemDefault()), + Precision.SECOND), + Arguments.of( + LocalDateTime.of(2020, Month.JANUARY, 1, 12, 23, 47).atZone(ZoneId.systemDefault()), + Precision.SECOND), + Arguments.of( + LocalDateTime.of(2020, Month.JANUARY, 1, 12, 0, 47).atZone(ZoneId.systemDefault()), + Precision.SECOND), + Arguments.of( + LocalDateTime.of(2020, Month.JANUARY, 1, 0, 0, 47).atZone(ZoneId.systemDefault()), + Precision.SECOND)); + } + + @ParameterizedTest + @MethodSource("zonedDateTimesParams") + public void zonedDateTimes(ZonedDateTime theZonedDateTime, Precision theExpectedPrecision) { + final Interval interval = new R4DateHelper().buildMeasurementPeriodInterval(theZonedDateTime, theZonedDateTime); + final Object start = interval.getStart(); + final Object end = interval.getEnd(); + assertInstanceOf(DateTime.class, start); + assertInstanceOf(DateTime.class, end); + assertEquals(theExpectedPrecision, ((DateTime) start).getPrecision()); + assertEquals(theExpectedPrecision, ((DateTime) end).getPrecision()); + } } diff --git a/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/r4/R4MeasureEvaluationTest.java b/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/r4/R4MeasureEvaluationTest.java index 15da5b03a..e652677bb 100644 --- a/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/r4/R4MeasureEvaluationTest.java +++ b/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/r4/R4MeasureEvaluationTest.java @@ -373,14 +373,13 @@ private MeasureReport runTest( var libraryEngine = new LibraryEngine(repository, evaluationOptions.getEvaluationSettings()); - R4MeasureEvaluation evaluation = new R4MeasureEvaluation(engine, measure, libraryEngine, id, null); + R4MeasureEvaluation evaluation = new R4MeasureEvaluation(engine, measure, libraryEngine, id); MeasureReport report = evaluation.evaluate( subjectIds.size() == 1 ? MeasureEvalType.SUBJECT : MeasureEvalType.POPULATION, subjectIds, measurementPeriod, libraryEngine, - id, - null); + id); assertNotNull(report); // Simulate sending it across the wire