Skip to content

Commit b35a29a

Browse files
committed
Update $import to preserve 'reporting' intendedUsageContext on relatedArtifact ValueSets
1 parent 0641dff commit b35a29a

2 files changed

Lines changed: 51 additions & 29 deletions

File tree

cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/ecr/r4/R4ImportBundleProducer.java

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -112,27 +112,31 @@ public static List<Bundle.BundleEntryComponent> transformImportBundle(
112112
switch (resource.getResourceType()) {
113113
case ValueSet:
114114
var valueSet = (ValueSet) resource;
115-
List<UsageContext> conditionsList = new ArrayList<>();
115+
List<UsageContext> genericContextList = new ArrayList<>();
116116
List<UsageContext> priorityList = new ArrayList<>();
117117
valueSet.setIdentifier(fixIdentifiers(valueSet.getIdentifier()));
118118
var valueSetCanonicalUrl = adapterFactory
119119
.createKnowledgeArtifactAdapter(valueSet)
120120
.getCanonical();
121-
extractPrioritiesAndConditions(
122-
valueSet.getUseContext(), priorityList, conditionsList, valueSetCanonicalUrl);
121+
extractUsageContexts(
122+
valueSet.getUseContext(), priorityList, genericContextList, valueSetCanonicalUrl);
123123
if (hasGrouperCompose(valueSet)) {
124124
prepareGrouperValueSet(valueSet, appAuthoritativeUrl);
125-
groupers.add(
126-
relatedArtifactFromGrouperUrl(valueSetCanonicalUrl, conditionsList, priorityList));
125+
groupers.add(relatedArtifactFromGrouperUrl(
126+
valueSetCanonicalUrl, genericContextList, priorityList));
127127
} else {
128128
prepareLeafValueSet(valueSet);
129-
leafs.add(relatedArtifactFromLeafUrl(valueSetCanonicalUrl, conditionsList, priorityList));
129+
leafs.add(
130+
relatedArtifactFromLeafUrl(valueSetCanonicalUrl, genericContextList, priorityList));
130131
}
131132
// Remove conditions and priority from useContext of leaf valuesets and groupers
132133
var cleanedContext = valueSet.getUseContext().stream()
133134
.filter(ctx -> ctx.hasCode()
134-
&& !(ctx.getCode().getCode().equals("focus")
135-
|| ctx.getCode().getCode().equals("priority")))
135+
&& !(ctx.getCode().getCode().equals("focus")
136+
|| ctx.getCode()
137+
.getCode()
138+
.equals("priority"))
139+
|| ctx.getCode().getCode().equals("reporting"))
136140
.collect(Collectors.toList());
137141
valueSet.setUseContext(cleanedContext);
138142
// Check if ValueSet already exists
@@ -249,10 +253,10 @@ static List<CanonicalType> removeProfileFromList(List<CanonicalType> profiles, S
249253
.collect(Collectors.toList());
250254
}
251255

252-
static void extractPrioritiesAndConditions(
256+
static void extractUsageContexts(
253257
List<UsageContext> contexts,
254258
List<UsageContext> priorityList,
255-
List<UsageContext> conditionsList,
259+
List<UsageContext> genericContextList,
256260
String valueSetCanonicalUrl) {
257261

258262
if (contexts == null || contexts.isEmpty()) return;
@@ -262,7 +266,7 @@ static void extractPrioritiesAndConditions(
262266
if (!isValidUsageContext) continue;
263267

264268
switch (context.getCode().getCode()) {
265-
case "focus" -> conditionsList.add(context);
269+
case "focus", "reporting" -> genericContextList.add(context);
266270
case "priority" -> handlePriorityContext(context, priorityList, valueSetCanonicalUrl);
267271
default -> {
268272
/* ignore other usage contexts */
@@ -360,16 +364,16 @@ private static void prepareRCTCLibrary(Library rctcLibrary, Set<RelatedArtifact>
360364
}
361365

362366
private static RelatedArtifact relatedArtifactFromGrouperUrl(
363-
String grouperUrl, List<UsageContext> conditions, List<UsageContext> priorities) {
367+
String grouperUrl, List<UsageContext> genericContexts, List<UsageContext> priorities) {
364368
var relatedArtifact = new RelatedArtifact();
365369
relatedArtifact.setType(RelatedArtifact.RelatedArtifactType.COMPOSEDOF);
366370
relatedArtifact.setResource(grouperUrl);
367371
var isOwnedExtension = new Extension();
368372
isOwnedExtension.setUrl(TransformProperties.crmiIsOwned);
369373
isOwnedExtension.setValue(new BooleanType(true));
370374
var extensions = new ArrayList<Extension>();
371-
extensions.addAll(
372-
processUsageContextMapForLibrary(conditions, TransformProperties.CRMI_INTENDED_USAGE_CONTEXT_EXT_URL));
375+
extensions.addAll(processUsageContextMapForLibrary(
376+
genericContexts, TransformProperties.CRMI_INTENDED_USAGE_CONTEXT_EXT_URL));
373377
extensions.addAll(
374378
processUsageContextMapForLibrary(priorities, TransformProperties.CRMI_INTENDED_USAGE_CONTEXT_EXT_URL));
375379
extensions.add(isOwnedExtension);
@@ -378,13 +382,13 @@ private static RelatedArtifact relatedArtifactFromGrouperUrl(
378382
}
379383

380384
private static RelatedArtifact relatedArtifactFromLeafUrl(
381-
String leafUrl, List<UsageContext> conditions, List<UsageContext> priorities) {
385+
String leafUrl, List<UsageContext> genericContexts, List<UsageContext> priorities) {
382386
var relatedArtifact = new RelatedArtifact();
383387
relatedArtifact.setType(RelatedArtifact.RelatedArtifactType.DEPENDSON);
384388
relatedArtifact.setResource(leafUrl);
385389
var extensions = new ArrayList<Extension>();
386-
extensions.addAll(
387-
processUsageContextMapForLibrary(conditions, TransformProperties.CRMI_INTENDED_USAGE_CONTEXT_EXT_URL));
390+
extensions.addAll(processUsageContextMapForLibrary(
391+
genericContexts, TransformProperties.CRMI_INTENDED_USAGE_CONTEXT_EXT_URL));
388392
extensions.addAll(
389393
processUsageContextMapForLibrary(priorities, TransformProperties.CRMI_INTENDED_USAGE_CONTEXT_EXT_URL));
390394
relatedArtifact.setExtension(extensions);

cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/ecr/r4/R4ImportBundleProducerTest.java

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ void testRootLibraryImport() throws FhirResourceExistsException {
147147
conditionUsageContext.getValueCodeableConcept().getText());
148148

149149
UsageContext priorityUsageContext =
150-
(UsageContext) ra.get(0).getExtension().get(1).getValue();
150+
(UsageContext) ra.get(0).getExtension().get(2).getValue();
151151
assertEquals("priority", priorityUsageContext.getCode().getCode());
152152
assertEquals(
153153
"routine",
@@ -248,8 +248,8 @@ void testImportOperation() {
248248
}
249249

250250
@Test
251-
void testExtractPrioritiesAndConditionsPopulatesLists() {
252-
// focus usage context goes to conditions
251+
void testExtractUsageContextsPopulatesLists() {
252+
// focus usage context goes to genericUseContexts
253253
UsageContext context1 = new UsageContext();
254254
context1.setCode(new Coding().setCode("focus"));
255255
context1.setValue(new CodeableConcept().setText("Condition1").addCoding(new Coding().setCode("condition1")));
@@ -259,24 +259,38 @@ void testExtractPrioritiesAndConditionsPopulatesLists() {
259259
context2.setCode(new Coding().setCode("priority"));
260260
context2.setValue(new CodeableConcept().addCoding(new Coding().setCode("routine")));
261261

262+
// reporting usage context goes to genericUseContexts
263+
UsageContext context3 = new UsageContext();
264+
context3.setCode(new Coding().setCode("reporting"));
265+
context3.setValue(new CodeableConcept().addCoding(new Coding().setCode("triggering")));
266+
262267
List<UsageContext> priorities = new ArrayList<>();
263-
List<UsageContext> conditions = new ArrayList<>();
268+
List<UsageContext> genericUseContexts = new ArrayList<>();
264269

265270
// Execute
266-
R4ImportBundleProducer.extractPrioritiesAndConditions(
267-
Arrays.asList(context1, context2), priorities, conditions, "fakeUrl");
271+
R4ImportBundleProducer.extractUsageContexts(
272+
Arrays.asList(context1, context2, context3), priorities, genericUseContexts, "fakeUrl");
268273

269274
// Verify
270275
assertEquals(1, priorities.size());
271276
assertEquals(
272277
"routine",
273278
priorities.get(0).getValueCodeableConcept().getCodingFirstRep().getCode());
274-
assertEquals(1, conditions.size());
275-
assertEquals("Condition1", conditions.get(0).getValueCodeableConcept().getText());
279+
assertEquals(2, genericUseContexts.size());
280+
assertEquals(
281+
"Condition1",
282+
genericUseContexts.get(0).getValueCodeableConcept().getText());
283+
assertEquals(
284+
"triggering",
285+
genericUseContexts
286+
.get(1)
287+
.getValueCodeableConcept()
288+
.getCodingFirstRep()
289+
.getCode());
276290
}
277291

278292
@Test
279-
void testExtractPrioritiesAndConditionsConflictingPrioritiesThrows() {
293+
void testExtractUsageContextsConflictingPrioritiesThrows() {
280294
UsageContext context1 = new UsageContext();
281295
context1.setCode(new Coding().setCode("priority"));
282296
context1.setValue(new CodeableConcept().addCoding(new Coding().setCode("urgent")));
@@ -285,13 +299,17 @@ void testExtractPrioritiesAndConditionsConflictingPrioritiesThrows() {
285299
context2.setCode(new Coding().setCode("priority"));
286300
context2.setValue(new CodeableConcept().addCoding(new Coding().setCode("routine")));
287301

302+
UsageContext context3 = new UsageContext();
303+
context3.setCode(new Coding().setCode("reporting"));
304+
context3.setValue(new CodeableConcept().addCoding(new Coding().setCode("triggering")));
305+
288306
List<UsageContext> priorities = new ArrayList<>();
289-
List<UsageContext> conditions = new ArrayList<>();
307+
List<UsageContext> genericUseContexts = new ArrayList<>();
290308

291309
assertThrows(
292310
UnprocessableEntityException.class,
293-
() -> R4ImportBundleProducer.extractPrioritiesAndConditions(
294-
Arrays.asList(context1, context2), priorities, conditions, "http://example.com/fhir"));
311+
() -> R4ImportBundleProducer.extractUsageContexts(
312+
Arrays.asList(context1, context2), priorities, genericUseContexts, "http://example.com/fhir"));
295313
}
296314

297315
@Test

0 commit comments

Comments
 (0)