Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,19 @@ private void gatherDependencies(
rootAdapter.setRelatedArtifact(updatedRelatedArtifacts);
}
}

extractMeasureDirectReferenceCodes(rootAdapter, artifactAdapter);
}
}

private void extractMeasureDirectReferenceCodes(
IKnowledgeArtifactAdapter rootAdapter, IKnowledgeArtifactAdapter artifactAdapter) {
if (artifactAdapter instanceof org.opencds.cqf.fhir.utility.adapter.r4.MeasureAdapter measureAdapter) {
org.opencds.cqf.fhir.cr.visitor.r4.ReleaseVisitor.extractDirectReferenceCodes(
rootAdapter, measureAdapter.get());
} else if (artifactAdapter instanceof org.opencds.cqf.fhir.utility.adapter.r5.MeasureAdapter measureAdapter) {
org.opencds.cqf.fhir.cr.visitor.r5.ReleaseVisitor.extractDirectReferenceCodes(
rootAdapter, measureAdapter.get());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r4.model.Extension;
import org.hl7.fhir.r4.model.Library;
import org.hl7.fhir.r4.model.Measure;
import org.hl7.fhir.r4.model.MetadataResource;
import org.hl7.fhir.r4.model.Period;
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.ResourceType;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.ValueSet;
import org.opencds.cqf.fhir.api.Repository;
import org.opencds.cqf.fhir.cr.visitor.r4.CRMIReleaseExperimentalBehavior.CRMIReleaseExperimentalBehaviorCodes;
import org.opencds.cqf.fhir.cr.visitor.r4.CRMIReleaseVersionBehavior.CRMIReleaseVersionBehaviorCodes;
import org.opencds.cqf.fhir.utility.Constants;
import org.opencds.cqf.fhir.utility.PackageHelper;
import org.opencds.cqf.fhir.utility.SearchHelper;
import org.opencds.cqf.fhir.utility.adapter.IKnowledgeArtifactAdapter;
Expand Down Expand Up @@ -156,4 +160,20 @@ public static List<BundleEntryComponent> findArtifactCommentsToUpdate(
});
return returnEntries;
}

public static void extractDirectReferenceCodes(IKnowledgeArtifactAdapter rootAdapter, Measure measure) {
Optional<Extension> effectiveDataRequirementsExt = measure.getExtension().stream()
.filter(ext -> ext.getUrl().equals(Constants.CQFM_EFFECTIVE_DATA_REQUIREMENTS))
.findFirst();
if (effectiveDataRequirementsExt.isPresent()) {
Reference ref = (Reference) effectiveDataRequirementsExt.get().getValue();
Library effectiveDataRequirementsLib = (Library) measure.getContained("#" + ref.getReference());
if (effectiveDataRequirementsLib != null) {
effectiveDataRequirementsLib.getExtension().stream()
.filter(ext -> ext.getUrl().equals(Constants.CQFM_DIRECT_REFERENCE_EXTENSION))
.map(ext -> ext.setUrl(Constants.CQF_DIRECT_REFERENCE_EXTENSION))
.forEach(rootAdapter::addExtension);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,19 @@
import org.hl7.fhir.r5.model.Bundle;
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r5.model.Extension;
import org.hl7.fhir.r5.model.Library;
import org.hl7.fhir.r5.model.Measure;
import org.hl7.fhir.r5.model.MetadataResource;
import org.hl7.fhir.r5.model.Period;
import org.hl7.fhir.r5.model.Reference;
import org.hl7.fhir.r5.model.RelatedArtifact.RelatedArtifactType;
import org.hl7.fhir.r5.model.ResourceType;
import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.ValueSet;
import org.opencds.cqf.fhir.api.Repository;
import org.opencds.cqf.fhir.cr.visitor.r5.CRMIReleaseExperimentalBehavior.CRMIReleaseExperimentalBehaviorCodes;
import org.opencds.cqf.fhir.cr.visitor.r5.CRMIReleaseVersionBehavior.CRMIReleaseVersionBehaviorCodes;
import org.opencds.cqf.fhir.utility.Constants;
import org.opencds.cqf.fhir.utility.PackageHelper;
import org.opencds.cqf.fhir.utility.SearchHelper;
import org.opencds.cqf.fhir.utility.adapter.IKnowledgeArtifactAdapter;
Expand Down Expand Up @@ -143,4 +147,19 @@ public static List<BundleEntryComponent> findArtifactCommentsToUpdate(
});
return returnEntries;
}

public static void extractDirectReferenceCodes(IKnowledgeArtifactAdapter rootAdapter, Measure measure) {
Optional<Extension> effectiveDataRequirementsExt = measure.getExtension().stream()
.filter(ext -> ext.getUrl().equals(Constants.CQFM_EFFECTIVE_DATA_REQUIREMENTS))
.findFirst();
if (effectiveDataRequirementsExt.isPresent()) {
Reference ref = effectiveDataRequirementsExt.get().getValueReference();
Library effectiveDataRequirementsLib = (Library) measure.getContained("#" + ref.getReference());
if (effectiveDataRequirementsLib != null) {
effectiveDataRequirementsLib.getExtension().stream()
.filter(ext -> ext.getUrl().equals(Constants.CQF_DIRECT_REFERENCE_EXTENSION))
.forEach(rootAdapter::addExtension);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,40 @@ void bothCRMIandCQFMEffectiveDataRequirementsTest() {
assertEquals(2, componentsOnReleasedArtifact.size());
}

@Test
void measureDirectReferenceCodesIncludedInReleaseTest() {
Bundle bundle = (Bundle) jsonParser.parseResource(
ReleaseVisitorTests.class.getResourceAsStream("Bundle-ecqm-qicore-2024-simplified.json"));
repo.transaction(bundle);
Library library = repo.read(Library.class, new IdType("Library/ecqm-update-2024-05-02"))
.copy();
ILibraryAdapter libraryAdapter = new AdapterFactory().createLibrary(library);
Parameters params = new Parameters();
params.addParameter("version", "1.0.0");
params.addParameter("versionBehavior", new CodeType("default"));
var crmiEDRId = "exp-params-crmi-test";
var crmiEDRExtension = new Extension();
crmiEDRExtension.setUrl(Constants.CRMI_EFFECTIVE_DATA_REQUIREMENTS);
crmiEDRExtension.setValue(new CanonicalType("#" + crmiEDRId));
ReleaseVisitor releaseVisitor = new ReleaseVisitor(repo);
// Approval date is required to release an artifact
library.setApprovalDateElement(new DateType("2024-04-23"));

Bundle returnResource = (Bundle) libraryAdapter.accept(releaseVisitor, params);
assertNotNull(returnResource);
Optional<BundleEntryComponent> maybeLib = returnResource.getEntry().stream()
.filter(entry -> entry.getResponse().getLocation().contains("Library"))
.findFirst();
assertTrue(maybeLib.isPresent());
Library releasedLibrary =
repo.read(Library.class, new IdType(maybeLib.get().getResponse().getLocation()));
var directReferenceExtensions = releasedLibrary.getExtension().stream()
.filter(ext -> ext.getUrl().equals(Constants.CQF_DIRECT_REFERENCE_EXTENSION))
.toList();

assertEquals(18, directReferenceExtensions.size());
}

@Test
void visitLibraryTest() {
Bundle bundle = (Bundle) jsonParser.parseResource(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,41 @@ void bothCRMIandCQFMEffectiveDataRequirementsTest() {
assertEquals(2, componentsOnReleasedArtifact.size());
}

@Test
void measureDirectReferenceCodesIncludedInReleaseTest() {
Bundle bundle = (Bundle) jsonParser.parseResource(
org.opencds.cqf.fhir.cr.visitor.r5.ReleaseVisitorTests.class.getResourceAsStream(
"Bundle-ecqm-qicore-2024-simplified.json"));
repo.transaction(bundle);
Library library = repo.read(Library.class, new IdType("Library/ecqm-update-2024-05-02"))
.copy();
ILibraryAdapter libraryAdapter = new AdapterFactory().createLibrary(library);
Parameters params = new Parameters();
params.addParameter("version", "1.0.0");
params.addParameter("versionBehavior", new CodeType("default"));
var crmiEDRId = "exp-params-crmi-test";
var crmiEDRExtension = new Extension();
crmiEDRExtension.setUrl(Constants.CRMI_EFFECTIVE_DATA_REQUIREMENTS);
crmiEDRExtension.setValue(new CanonicalType("#" + crmiEDRId));
ReleaseVisitor releaseVisitor = new ReleaseVisitor(repo);
// Approval date is required to release an artifact
library.setApprovalDateElement(new DateType("2024-04-23"));

Bundle returnResource = (Bundle) libraryAdapter.accept(releaseVisitor, params);
assertNotNull(returnResource);
Optional<Bundle.BundleEntryComponent> maybeLib = returnResource.getEntry().stream()
.filter(entry -> entry.getResponse().getLocation().contains("Library"))
.findFirst();
assertTrue(maybeLib.isPresent());
Library releasedLibrary =
repo.read(Library.class, new IdType(maybeLib.get().getResponse().getLocation()));
var directReferenceExtensions = releasedLibrary.getExtension().stream()
.filter(ext -> ext.getUrl().equals(Constants.CQF_DIRECT_REFERENCE_EXTENSION))
.toList();

assertEquals(18, directReferenceExtensions.size());
}

@Test
void visitLibraryTest() {
Bundle bundle = (Bundle) jsonParser.parseResource(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,55 +209,55 @@
"id": "effective-data-requirements",
"extension": [
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "laboratory",
"display": "laboratory"
}
},
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://snomed.info/sct",
"code": "428361000124107",
"display": "Discharge to home for hospice care (procedure)"
}
},
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://snomed.info/sct",
"code": "428371000124100",
"display": "Discharge to healthcare facility for hospice care (procedure)"
}
},
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "survey",
"display": "survey"
}
},
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://snomed.info/sct",
"code": "373066001",
"display": "Yes (qualifier value)"
}
},
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://loinc.org",
"code": "45755-6",
"display": "Hospice care [Minimum Data Set]"
}
},
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://loinc.org",
"code": "71007-9",
Expand Down Expand Up @@ -2145,87 +2145,87 @@
"id": "effective-data-requirements",
"extension": [
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://snomed.info/sct",
"code": "428361000124107",
"display": "Discharge to home for hospice care (procedure)"
}
},
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://snomed.info/sct",
"code": "428371000124100",
"display": "Discharge to healthcare facility for hospice care (procedure)"
}
},
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "survey",
"display": "survey"
}
},
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://snomed.info/sct",
"code": "373066001",
"display": "Yes (qualifier value)"
}
},
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://loinc.org",
"code": "45755-6",
"display": "Hospice care [Minimum Data Set]"
}
},
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://snomed.info/sct",
"code": "24028007",
"display": "Right (qualifier value)"
}
},
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://snomed.info/sct",
"code": "7771000",
"display": "Left (qualifier value)"
}
},
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://loinc.org",
"code": "98181-1",
"display": "Medical equipment used"
}
},
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://loinc.org",
"code": "71802-3",
"display": "Housing status"
}
},
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://snomed.info/sct",
"code": "160734000",
"display": "Lives in a nursing home (finding)"
}
},
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
"valueCoding": {
"system": "http://loinc.org",
"code": "71007-9",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ public enum CqfApplicabilityBehavior {
public static final String CQF_LIBRARY = "http://hl7.org/fhir/StructureDefinition/cqf-library";
public static final String CQF_CALCULATED_VALUE = "http://hl7.org/fhir/StructureDefinition/cqf-calculatedValue";
public static final String CQF_FHIR_QUERY_PATTERN = "http://hl7.org/fhir/StructureDefinition/cqf-fhirQueryPattern";
public static final String CQF_DIRECT_REFERENCE_EXTENSION =
"http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode";

public static final String CQFM_EFFECTIVE_DATA_REQUIREMENTS =
"http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-effectiveDataRequirements";
Expand All @@ -98,7 +100,8 @@ public enum CqfApplicabilityBehavior {
public static final String CQFM_INPUT_PARAMETERS =
"http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-inputParameters";
public static final String CQFM_COMPONENT = "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-component";

public static final String CQFM_DIRECT_REFERENCE_EXTENSION =
"http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode";
public static final String CRMI_EFFECTIVE_DATA_REQUIREMENTS =
"http://hl7.org/fhir/uv/crmi/StructureDefinition/crmi-effectiveDataRequirements";

Expand Down