Skip to content

Commit 319f5a0

Browse files
authored
Merge branch 'develop' into MAT-10263
2 parents 29fd8c5 + 4fe362e commit 319f5a0

11 files changed

Lines changed: 128 additions & 24 deletions

File tree

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@
198198
<dependency>
199199
<groupId>gov.cms.madie</groupId>
200200
<artifactId>madie-java-models</artifactId>
201-
<version>0.10.6-SNAPSHOT</version>
201+
<version>0.10.13-SNAPSHOT</version>
202202
</dependency>
203203
<dependency>
204204
<groupId>com.jayway.jsonpath</groupId>

src/main/java/gov/cms/madie/madiefhirservice/config/HapiFhirConfig.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public IValidationSupport validationSupportChainQiCore600(
106106
npmPackageSupport.loadPackageFromClasspath(
107107
"classpath:packages/hl7.fhir.uv.extensions.r4-5.2.0.tgz");
108108
npmPackageSupport.loadPackageFromClasspath(
109-
"classpath:packages/hl7.fhir.xver-extensions-0.1.0.tgz");
109+
"classpath:packages/hl7.fhir.uv.xver-r5.r4-0.1.0.tgz");
110110

111111
CustomUnknownCodeSystemWarningValidationSupport unknownCodeSystemWarningValidationSupport =
112112
getUnknownCodeSystemValidationSupport(qicore6FhirContext);
@@ -140,7 +140,7 @@ public IValidationSupport uscore6ValidationSupportChain(@Autowired FhirContext u
140140
npmPackageSupport.loadPackageFromClasspath(
141141
"classpath:packages/hl7.fhir.uv.extensions.r4-5.2.0.tgz");
142142
npmPackageSupport.loadPackageFromClasspath(
143-
"classpath:packages/hl7.fhir.xver-extensions-0.1.0.tgz");
143+
"classpath:packages/hl7.fhir.uv.xver-r5.r4-0.1.0.tgz");
144144

145145
CustomUnknownCodeSystemWarningValidationSupport unknownCodeSystemWarningValidationSupport =
146146
getUnknownCodeSystemValidationSupport(uscore6FhirContext);
@@ -156,8 +156,8 @@ public IValidationSupport uscore6ValidationSupportChain(@Autowired FhirContext u
156156
validationConfig);
157157

158158
return new ValidationSupportChain(
159-
npmPackageSupport,
160159
vsesValidationSupport,
160+
npmPackageSupport,
161161
new DefaultProfileValidationSupport(uscore6FhirContext),
162162
new CustomQiCoreInMemoryValidationSupport(uscore6FhirContext, validationConfig),
163163
new CommonCodeSystemsTerminologyService(uscore6FhirContext),
@@ -176,7 +176,7 @@ public IValidationSupport usqualitycore05ValidationSupportChain(
176176
npmPackageSupport.loadPackageFromClasspath(
177177
"classpath:packages/hl7.fhir.uv.extensions.r4-5.2.0.tgz");
178178
npmPackageSupport.loadPackageFromClasspath(
179-
"classpath:packages/hl7.fhir.xver-extensions-0.1.0.tgz");
179+
"classpath:packages/hl7.fhir.uv.xver-r5.r4-0.1.0.tgz");
180180

181181
CustomUnknownCodeSystemWarningValidationSupport unknownCodeSystemWarningValidationSupport =
182182
getUnknownCodeSystemValidationSupport(usqualitycore05FhirContext);
@@ -192,8 +192,8 @@ public IValidationSupport usqualitycore05ValidationSupportChain(
192192
validationConfig);
193193

194194
return new ValidationSupportChain(
195-
npmPackageSupport,
196195
vsesValidationSupport,
196+
npmPackageSupport,
197197
new DefaultProfileValidationSupport(usqualitycore05FhirContext),
198198
new CustomQiCoreInMemoryValidationSupport(usqualitycore05FhirContext, validationConfig),
199199
new CommonCodeSystemsTerminologyService(usqualitycore05FhirContext),

src/main/java/gov/cms/madie/madiefhirservice/constants/UriConstants.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ public static final class CodeSystem {
2525
public static final String IMPROVEMENT_NOTATION_CODE_SYSTEM_URI =
2626
"http://terminology.hl7.org/CodeSystem/measure-improvement-notation";
2727

28-
public static final String CODE_SYSTEM_URI =
28+
public static final String USAGE_CONTEXT_TYPE_SYSTEM_URI =
2929
"http://terminology.hl7.org/CodeSystem/usage-context-type";
30+
public static final String MEASURE_ELIGIBILITY_SYSTEM_URI =
31+
"http://cms.gov/CodeSystem/measure-eligibility";
3032
}
3133

3234
public static final class CqfMeasures {
@@ -106,6 +108,8 @@ public static final class CqfMeasures {
106108
"http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-groupId";
107109
public static final String CQFM_COMPONENT_URI =
108110
"http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-component";
111+
public static final String INTENDED_VENUE_CODES_URI =
112+
"http://hl7.org/fhir/us/cqfmeasures/CodeSystem/intended-venue-codes";
109113
}
110114

111115
public static final class CqfTestCases {

src/main/java/gov/cms/madie/madiefhirservice/services/MeasureTranslatorService.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ private void setUseContext(Measure madieMeasure, org.hl7.fhir.r4.model.Measure m
137137
measure.addUseContext(
138138
buildIntendedVenue(madieMeasure.getMeasureMetaData().getIntendedVenue()));
139139
}
140+
141+
if (Boolean.TRUE.equals(madieMeasure.getMeasureMetaData().getTelehealthEligible())) {
142+
measure.addUseContext(buildTelehealthEligible());
143+
}
140144
}
141145

142146
private void setRelatedArtifact(Measure madieMeasure, org.hl7.fhir.r4.model.Measure measure) {
@@ -236,21 +240,38 @@ && isNotEmpty(madieMeasure.getMeasureMetaData().getEndorsements())
236240
private UsageContext buildIntendedVenue(CodeConcept intendedVenue) {
237241
Coding coding =
238242
new Coding()
239-
.setSystem("http://hl7.org/fhir/us/cqfmeasures/CodeSystem/intended-venue-codes")
243+
.setSystem(UriConstants.CqfMeasures.INTENDED_VENUE_CODES_URI)
240244
.setCode(intendedVenue.getCode())
241245
.setDisplay(intendedVenue.getDisplay());
242246

243247
UsageContext usageContext = new UsageContext();
244248
usageContext.setCode(
245249
new Coding()
246-
.setSystem("http://terminology.hl7.org/CodeSystem/usage-context-type")
250+
.setSystem(UriConstants.CodeSystem.USAGE_CONTEXT_TYPE_SYSTEM_URI)
247251
.setCode("venue")
248252
.setDisplay("Venue"));
249253
usageContext.setValue(new CodeableConcept(coding));
250254

251255
return usageContext;
252256
}
253257

258+
private UsageContext buildTelehealthEligible() {
259+
UsageContext usageContext = new UsageContext();
260+
usageContext.setCode(
261+
new Coding()
262+
.setSystem(UriConstants.CodeSystem.USAGE_CONTEXT_TYPE_SYSTEM_URI)
263+
.setCode("venue")
264+
.setDisplay("Clinical Venue"));
265+
usageContext.setValue(
266+
new CodeableConcept(
267+
new Coding()
268+
.setSystem(UriConstants.CodeSystem.MEASURE_ELIGIBILITY_SYSTEM_URI)
269+
.setCode("tele-health-eligible")
270+
.setDisplay("Telehealth Eligible")));
271+
272+
return usageContext;
273+
}
274+
254275
private String getStewardName(Organization steward) {
255276
return (steward == null || StringUtils.isBlank(steward.getName()))
256277
? UNKNOWN

src/main/java/gov/cms/madie/madiefhirservice/services/StructureDefinitionService.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,21 @@ public class StructureDefinitionService {
3535
* Fetches the structure definition for the given resource
3636
*
3737
* @param modelType the model to fetch the structure definition for
38-
* @param structureDefinitionId ID of the structure definition, as found in the
39-
* StructureDefinitions based on model and version. e.g. Patient, us-core-patient,
40-
* qicore-patient
38+
* @param structureDefinitionId ID of the structure definition, optionally followed by a
39+
* pipe-delimited version, as found in the StructureDefinitions for the model. e.g. Patient,
40+
* us-core-patient, qicore-patient|6.0.0
4141
*/
4242
public StructureDefinitionDto getStructureDefinitionById(
4343
ModelType modelType, String structureDefinitionId) {
4444
IValidationSupport chain = modelAwareFhirFactory.getValidationSupportForModel(modelType);
4545

46+
String unversionedId = structureDefinitionId.split("\\|", 2)[0];
47+
4648
IBaseResource structureDefinition =
4749
Objects.requireNonNull(chain.fetchAllStructureDefinitions()).stream()
48-
.filter(resource -> structureDefinitionId.equals(resource.getIdElement().getIdPart()))
50+
.filter(resource -> unversionedId.equals(resource.getIdElement().getIdPart()))
4951
.findFirst()
50-
.orElseThrow(
51-
() -> new ResourceNotFoundException("StructureDefinition", structureDefinitionId));
52+
.orElseThrow(() -> new ResourceNotFoundException("StructureDefinition", unversionedId));
5253

5354
IParser parser =
5455
chain
11.7 MB
Binary file not shown.
-180 KB
Binary file not shown.

src/test/java/gov/cms/madie/madiefhirservice/services/HumanReadableServiceTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@
1717

1818
import org.hl7.fhir.exceptions.FHIRException;
1919
import org.hl7.fhir.r4.model.Attachment;
20+
import org.hl7.fhir.r4.model.CodeableConcept;
21+
import org.hl7.fhir.r4.model.Coding;
2022
import org.hl7.fhir.r4.model.Identifier;
2123
import org.hl7.fhir.r4.model.Library;
2224
import org.hl7.fhir.r4.model.MarkdownType;
2325
import org.hl7.fhir.r4.model.Period;
2426
import org.hl7.fhir.r4.model.Reference;
2527
import org.hl7.fhir.r4.model.RelatedArtifact;
2628
import org.hl7.fhir.r4.model.RelatedArtifact.RelatedArtifactType;
29+
import org.hl7.fhir.r4.model.UsageContext;
2730
import org.hl7.fhir.r5.context.SimpleWorkerContext;
2831
import org.hl7.fhir.r5.liquid.LiquidEngine;
2932
import org.junit.jupiter.api.BeforeEach;
@@ -170,13 +173,29 @@ public void generateMeasureHumanReadable() {
170173

171174
@Test
172175
public void generateMeasureHumanReadableUsingIncludes() throws IOException {
176+
measure.addUseContext(
177+
new UsageContext()
178+
.setCode(
179+
new Coding()
180+
.setSystem("http://terminology.hl7.org/CodeSystem/usage-context-type")
181+
.setCode("venue")
182+
.setDisplay("Clinical Venue"))
183+
.setValue(
184+
new CodeableConcept(
185+
new Coding()
186+
.setSystem("http://cms.gov/CodeSystem/measure-eligibility")
187+
.setCode("tele-health-eligible")
188+
.setDisplay("Telehealth Eligible"))));
189+
173190
var le = new LiquidEngine(new SimpleWorkerContext.SimpleWorkerContextBuilder().build(), null);
174191
// Set include resolver
175192
le.setIncludeResolver(this);
176193
var hr = new HumanReadableService(le);
177194

178195
var generatedHumanReadable = hr.generateMeasureHumanReadable(measure, madieMeasure.getId());
179196
assertNotNull(generatedHumanReadable);
197+
assertTrue(generatedHumanReadable.contains("Clinical Venue"));
198+
assertTrue(generatedHumanReadable.contains("Telehealth Eligible"));
180199
}
181200

182201
@Test

src/test/java/gov/cms/madie/madiefhirservice/services/MeasureTranslatorServiceTest.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package gov.cms.madie.madiefhirservice.services;
22

33
import static gov.cms.madie.madiefhirservice.constants.UriConstants.CodeSystem.CODE_SYSTEM_IDENTIFIER_TYPE_URI;
4+
import static gov.cms.madie.madiefhirservice.constants.UriConstants.CodeSystem.USAGE_CONTEXT_TYPE_SYSTEM_URI;
5+
import static gov.cms.madie.madiefhirservice.constants.UriConstants.CodeSystem.MEASURE_ELIGIBILITY_SYSTEM_URI;
46
import static gov.cms.madie.madiefhirservice.constants.UriConstants.MadieMeasure.SHORT_NAME;
57
import static gov.cms.madie.madiefhirservice.constants.IdentifierType.CODE_ENDORSER;
68
import static gov.cms.madie.madiefhirservice.constants.IdentifierType.CODE_PUBLISHER;
@@ -409,9 +411,17 @@ public void testCreateFhirMeasureForMadieMeasure() {
409411
"Risk Adjustments example",
410412
measure.getSupplementalData().get(2).getCriteria().getExpression());
411413
assertEquals("Risk Adjustments example", measure.getSupplementalData().get(2).getDescription());
412-
assertThat(measure.getUseContext().size(), is(equalTo(1)));
414+
assertThat(measure.getUseContext().size(), is(equalTo(2)));
413415
assertThat(measure.getUseContext().get(0).getCode().getDisplay(), is(equalTo("Venue")));
414416
assertThat(measure.getUseContext().get(0).hasValue(), is(equalTo(true)));
417+
UsageContext telehealth = measure.getUseContext().get(1);
418+
assertThat(telehealth.getCode().getSystem(), is(equalTo(USAGE_CONTEXT_TYPE_SYSTEM_URI)));
419+
assertThat(telehealth.getCode().getCode(), is(equalTo("venue")));
420+
assertThat(telehealth.getCode().getDisplay(), is(equalTo("Clinical Venue")));
421+
Coding telehealthValue = telehealth.getValueCodeableConcept().getCodingFirstRep();
422+
assertThat(telehealthValue.getSystem(), is(equalTo(MEASURE_ELIGIBILITY_SYSTEM_URI)));
423+
assertThat(telehealthValue.getCode(), is(equalTo("tele-health-eligible")));
424+
assertThat(telehealthValue.getDisplay(), is(equalTo("Telehealth Eligible")));
415425
assertFalse(measure.getSupplementalData().get(2).getUsage().get(0).getCoding().isEmpty());
416426
assertEquals("1.2.003", measure.getVersion());
417427

src/test/java/gov/cms/madie/madiefhirservice/services/StructureDefinitionServiceTest.java

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,14 @@ void testGetStructureDefinitionByIdThrowsNotFoundForNoDefinitions() {
5858
// given
5959
when(mockChain.fetchAllStructureDefinitions()).thenReturn(List.of());
6060

61-
// when / then
62-
assertThrows(
63-
ResourceNotFoundException.class,
61+
// when
62+
Executable action =
6463
() ->
6564
structureDefinitionService.getStructureDefinitionById(
66-
ModelType.QI_CORE_6_0_0, "qicore-practitioner"));
65+
ModelType.QI_CORE_6_0_0, "qicore-practitioner");
66+
67+
// then
68+
assertThrows(ResourceNotFoundException.class, action);
6769
}
6870

6971
@Test
@@ -79,12 +81,35 @@ void testGetStructureDefinitionByIdThrowsNotFoundForNoMatchingDefinitions() {
7981
def3.setId("us-core-practitioner");
8082
when(mockChain.fetchAllStructureDefinitions()).thenReturn(List.of(def1, def3));
8183

82-
// when / then
83-
assertThrows(
84-
ResourceNotFoundException.class,
84+
// when
85+
Executable action =
86+
() ->
87+
structureDefinitionService.getStructureDefinitionById(
88+
ModelType.QI_CORE_6_0_0, "qicore-practitioner");
89+
90+
// then
91+
assertThrows(ResourceNotFoundException.class, action);
92+
}
93+
94+
@Test
95+
void testGetStructureDefinitionByIdThrowsNotFoundForVersionedIdWithNoMatch() {
96+
// given
97+
when(mockChain.fetchAllStructureDefinitions()).thenReturn(List.of());
98+
99+
// when
100+
Executable action =
85101
() ->
86102
structureDefinitionService.getStructureDefinitionById(
87-
ModelType.QI_CORE_6_0_0, "qicore-practitioner"));
103+
ModelType.QI_CORE_6_0_0, "qicore-practitioner|6.0.0");
104+
105+
// then
106+
ResourceNotFoundException exception = assertThrows(ResourceNotFoundException.class, action);
107+
assertThat(
108+
exception.getMessage(),
109+
is(
110+
equalTo(
111+
"Could not find StructureDefinition resource for measure: "
112+
+ "qicore-practitioner")));
88113
}
89114

90115
@Test
@@ -288,6 +313,29 @@ void testGetStructureDefinitionByIdReturnsQiCoreResourceStructureDefinitionDto()
288313
output.getDefinition().contains("\"resourceType\": \"StructureDefinition\""), is(true));
289314
}
290315

316+
@Test
317+
void testGetStructureDefinitionByIdReturnsResourceForVersionedId() {
318+
// given
319+
StructureDefinition definition =
320+
new StructureDefinition()
321+
.setKind(StructureDefinition.StructureDefinitionKind.RESOURCE)
322+
.setTitle("QICore Patient")
323+
.setVersion("6.0.0");
324+
definition.setId("qicore-patient");
325+
when(mockChain.fetchAllStructureDefinitions()).thenReturn(List.of(definition));
326+
when(mockChain.getFhirContext()).thenReturn(fhirContextQiCoreStu600);
327+
328+
// when
329+
StructureDefinitionDto output =
330+
structureDefinitionService.getStructureDefinitionById(
331+
ModelType.QI_CORE_6_0_0, "qicore-patient|6.0.0");
332+
333+
// then
334+
assertThat(output, is(notNullValue()));
335+
assertThat(output.getDefinition().contains("\"id\": \"qicore-patient\""), is(true));
336+
assertThat(output.getDefinition().contains("\"version\": \"6.0.0\""), is(true));
337+
}
338+
291339
@Test
292340
void testGetStructureDefinitionByIdReturnsComplexTypeStructureDefinitionDto() {
293341
// given

0 commit comments

Comments
 (0)