diff --git a/engine/src/androidTest/java/com/google/android/fhir/db/impl/DatabaseImplTest.kt b/engine/src/androidTest/java/com/google/android/fhir/db/impl/DatabaseImplTest.kt index 25efca3a2d..315791acf0 100644 --- a/engine/src/androidTest/java/com/google/android/fhir/db/impl/DatabaseImplTest.kt +++ b/engine/src/androidTest/java/com/google/android/fhir/db/impl/DatabaseImplTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2023-2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/engine/src/main/java/com/google/android/fhir/FhirEngine.kt b/engine/src/main/java/com/google/android/fhir/FhirEngine.kt index a006ab2c29..0bec8f3e2b 100644 --- a/engine/src/main/java/com/google/android/fhir/FhirEngine.kt +++ b/engine/src/main/java/com/google/android/fhir/FhirEngine.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2023-2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/engine/src/main/java/com/google/android/fhir/db/Database.kt b/engine/src/main/java/com/google/android/fhir/db/Database.kt index ddbd3a9401..83157a35ba 100644 --- a/engine/src/main/java/com/google/android/fhir/db/Database.kt +++ b/engine/src/main/java/com/google/android/fhir/db/Database.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2023-2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/engine/src/main/java/com/google/android/fhir/db/impl/DatabaseImpl.kt b/engine/src/main/java/com/google/android/fhir/db/impl/DatabaseImpl.kt index 59fe65a8e1..af044b4f63 100644 --- a/engine/src/main/java/com/google/android/fhir/db/impl/DatabaseImpl.kt +++ b/engine/src/main/java/com/google/android/fhir/db/impl/DatabaseImpl.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2023-2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/engine/src/main/java/com/google/android/fhir/db/impl/dao/ResourceDao.kt b/engine/src/main/java/com/google/android/fhir/db/impl/dao/ResourceDao.kt index bae8f3f6b9..45786270bb 100644 --- a/engine/src/main/java/com/google/android/fhir/db/impl/dao/ResourceDao.kt +++ b/engine/src/main/java/com/google/android/fhir/db/impl/dao/ResourceDao.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2023-2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/engine/src/main/java/com/google/android/fhir/search/MoreSearch.kt b/engine/src/main/java/com/google/android/fhir/search/MoreSearch.kt index 0075d6facf..d2b42c3f1a 100644 --- a/engine/src/main/java/com/google/android/fhir/search/MoreSearch.kt +++ b/engine/src/main/java/com/google/android/fhir/search/MoreSearch.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2023-2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/engine/src/main/java/com/google/android/fhir/search/NestedSearch.kt b/engine/src/main/java/com/google/android/fhir/search/NestedSearch.kt index 1f63ed63bd..4818680ec5 100644 --- a/engine/src/main/java/com/google/android/fhir/search/NestedSearch.kt +++ b/engine/src/main/java/com/google/android/fhir/search/NestedSearch.kt @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 Google LLC + * Copyright 2022-2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/engine/src/test/java/com/google/android/fhir/search/NumberSearchParameterizedTest.kt b/engine/src/test/java/com/google/android/fhir/search/NumberSearchParameterizedTest.kt index c00ff7dbc5..7dcb4e177d 100644 --- a/engine/src/test/java/com/google/android/fhir/search/NumberSearchParameterizedTest.kt +++ b/engine/src/test/java/com/google/android/fhir/search/NumberSearchParameterizedTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2021-2023 Google LLC + * Copyright 2021-2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/engine/src/test/java/com/google/android/fhir/search/SearchTest.kt b/engine/src/test/java/com/google/android/fhir/search/SearchTest.kt index c9da480147..11f9c93a8f 100644 --- a/engine/src/test/java/com/google/android/fhir/search/SearchTest.kt +++ b/engine/src/test/java/com/google/android/fhir/search/SearchTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 Google LLC + * Copyright 2022-2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/workflow-testing/src/main/java/com/google/android/fhir/workflow/testing/CqlBuilder.kt b/workflow-testing/src/main/java/com/google/android/fhir/workflow/testing/CqlBuilder.kt index 648d28a873..93085ec0e5 100644 --- a/workflow-testing/src/main/java/com/google/android/fhir/workflow/testing/CqlBuilder.kt +++ b/workflow-testing/src/main/java/com/google/android/fhir/workflow/testing/CqlBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 Google LLC + * Copyright 2022-2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ object CqlBuilder : Loadable() { /** * Compiles a CQL InputStream to ELM * - * @param cqlText the CQL Library + * @param cqlText the CQL Library's input stream * @return a [CqlTranslator] object that contains the elm representation of the library inside it. */ fun compile(cqlText: InputStream): CqlTranslator { diff --git a/workflow/src/main/java/com/google/android/fhir/workflow/FhirOperator.kt b/workflow/src/main/java/com/google/android/fhir/workflow/FhirOperator.kt index 8c595e22b7..fb3e0a6c75 100644 --- a/workflow/src/main/java/com/google/android/fhir/workflow/FhirOperator.kt +++ b/workflow/src/main/java/com/google/android/fhir/workflow/FhirOperator.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2023-2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,16 +25,20 @@ import com.google.android.fhir.FhirEngineProvider import com.google.android.fhir.knowledge.KnowledgeManager import com.google.android.fhir.workflow.repositories.FhirEngineRepository import com.google.android.fhir.workflow.repositories.KnowledgeRepository +import org.hl7.fhir.instance.model.api.IBaseBundle +import org.hl7.fhir.instance.model.api.IBaseDatatype import org.hl7.fhir.instance.model.api.IBaseParameters import org.hl7.fhir.instance.model.api.IBaseResource import org.hl7.fhir.r4.model.CanonicalType import org.hl7.fhir.r4.model.IdType -import org.hl7.fhir.r4.model.Measure import org.hl7.fhir.r4.model.MeasureReport import org.hl7.fhir.r4.model.Parameters +import org.hl7.fhir.r4.model.PlanDefinition +import org.hl7.fhir.r4.model.Reference import org.opencds.cqf.fhir.cql.EvaluationSettings import org.opencds.cqf.fhir.cql.LibraryEngine import org.opencds.cqf.fhir.cr.measure.MeasureEvaluationOptions +import org.opencds.cqf.fhir.cr.measure.common.MeasureReportType import org.opencds.cqf.fhir.cr.measure.r4.R4MeasureProcessor import org.opencds.cqf.fhir.cr.plandefinition.r4.PlanDefinitionProcessor import org.opencds.cqf.fhir.utility.monad.Eithers @@ -162,20 +166,35 @@ internal constructor( start: String, end: String, reportType: String, - subjectId: String?, - practitioner: String?, + subjectId: String? = null, + practitioner: String? = null, + additionalData: IBaseBundle? = null, ): MeasureReport { - val measure = Eithers.forLeft3(CanonicalType(measureUrl)) - return measureProcessor.evaluateMeasure( - /* measure = */ measure, - /* periodStart = */ start, - /* periodEnd = */ end, - /* reportType = */ reportType, - /* subjectIds = */ listOf( - subjectId, - ), // https://github.com/cqframework/clinical-reasoning/issues/358 - /* additionalData = */ null, - ) + val subject = + if (!practitioner.isNullOrBlank()) { + checkAndAddType(practitioner, "Practitioner") + } else if (!subjectId.isNullOrBlank()) { + checkAndAddType(subjectId, "Patient") + } else { + // List of null is required to run population-level measures + null + } + + val report = + measureProcessor.evaluateMeasure( + /* measure = */ Eithers.forLeft3(CanonicalType(measureUrl)), + /* periodStart = */ start, + /* periodEnd = */ end, + /* reportType = */ reportType, + /* subjectIds = */ listOf(subject), + /* additionalData = */ additionalData, + ) + + // add subject reference for non-individual reportTypes + if (report.type.name == MeasureReportType.SUMMARY.name && !subject.isNullOrBlank()) { + report.setSubject(Reference(subject)) + } + return report } /** @@ -193,11 +212,6 @@ internal constructor( return generateCarePlan(planDefinitionId, subject, encounterId = null) } - @WorkerThread - fun generateCarePlan(planDefinition: CanonicalType, subject: String): IBaseResource { - return generateCarePlan(planDefinition, subject, encounterId = null) - } - /** * Generates a [CarePlan] based on the provided inputs. * @@ -239,7 +253,18 @@ internal constructor( fun generateCarePlan( planDefinition: CanonicalType, subject: String, - encounterId: String?, + encounterId: String? = null, + practitionerId: String? = null, + organizationId: String? = null, + userType: IBaseDatatype? = null, + userLanguage: IBaseDatatype? = null, + userTaskContext: IBaseDatatype? = null, + setting: IBaseDatatype? = null, + settingContext: IBaseDatatype? = null, + parameters: IBaseParameters? = null, + useServerData: Boolean? = null, + bundle: IBaseBundle? = null, + prefetchData: IBaseParameters? = null, ): IBaseResource { return planDefinitionProcessor.apply( /* id = */ null, @@ -247,21 +272,64 @@ internal constructor( /* planDefinition = */ null, /* subject = */ subject, /* encounterId = */ encounterId, - /* practitionerId = */ null, - /* organizationId = */ null, - /* userType = */ null, - /* userLanguage = */ null, - /* userTaskContext = */ null, - /* setting = */ null, - /* settingContext = */ null, - /* parameters = */ null, - /* useServerData = */ null, - /* bundle = */ null, - /* prefetchData = */ null, + /* practitionerId = */ practitionerId, + /* organizationId = */ organizationId, + /* userType = */ userType, + /* userLanguage = */ userLanguage, + /* userTaskContext = */ userTaskContext, + /* setting = */ setting, + /* settingContext = */ settingContext, + /* parameters = */ parameters, + /* useServerData = */ useServerData, + /* bundle = */ bundle, + /* prefetchData = */ prefetchData, libraryProcessor, ) as IBaseResource } + @WorkerThread + fun generateCarePlan( + planDefinition: PlanDefinition, + subject: String, + encounterId: String? = null, + practitionerId: String? = null, + organizationId: String? = null, + userType: IBaseDatatype? = null, + userLanguage: IBaseDatatype? = null, + userTaskContext: IBaseDatatype? = null, + setting: IBaseDatatype? = null, + settingContext: IBaseDatatype? = null, + parameters: IBaseParameters? = null, + useServerData: Boolean? = null, + bundle: IBaseBundle? = null, + prefetchData: IBaseParameters? = null, + ): IBaseResource { + return planDefinitionProcessor.apply( + /* id = */ null, + /* canonical = */ null, + /* planDefinition = */ planDefinition, + /* subject = */ subject, + /* encounterId = */ encounterId, + /* practitionerId = */ practitionerId, + /* organizationId = */ organizationId, + /* userType = */ userType, + /* userLanguage = */ userLanguage, + /* userTaskContext = */ userTaskContext, + /* setting = */ setting, + /* settingContext = */ settingContext, + /* parameters = */ parameters, + /* useServerData = */ useServerData, + /* bundle = */ bundle, + /* prefetchData = */ prefetchData, + libraryProcessor, + ) as IBaseResource + } + + /** Checks if the Resource ID contains a type and if not, adds a default type */ + fun checkAndAddType(id: String, defaultType: String): String { + return if (id.indexOf("/") == -1) "$defaultType/$id" else id + } + class Builder(private val applicationContext: Context) { private var fhirContext: FhirContext? = null private var fhirEngine: FhirEngine? = null