Skip to content

Commit 42714d1

Browse files
committed
Use submitted categories for prequal OO
Change pre-qualification OperationOutcome to be built from categories with submit==true instead of unacceptable (acceptable==false). Updated PreQualOperationOutcomeBuilder logic and javadoc, adjusted ReadyForValidationConsumer javadoc, and revised tests to use Category.submit (added helper overloads and updated expectations). This aligns pre-qual behavior with the requirement to include only submitted categories (LEGLINK-425) and updates unit tests accordingly.
1 parent db5a7bf commit 42714d1

4 files changed

Lines changed: 49 additions & 26 deletions

File tree

Java/validation/src/main/java/com/lantanagroup/link/validation/services/PreQualOperationOutcomeBuilder.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
/**
2525
* Builds the single pre-qualification {@link OperationOutcome} written to the patient NDJSON: one issue
26-
* per <em>unacceptable</em> category (a category with {@code acceptable=false}) that has at least one
26+
* per <em>submitted</em> category (a category with {@code submit=true}) that has at least one
2727
* finding. See LEGLINK-425.
2828
*/
2929
@Component
@@ -55,10 +55,10 @@ public record MeasureReportRef(int index, String id) {
5555
* @param results the patient's categorized validation results
5656
* @param measureReport the patient's MeasureReport in the submission bundle (may be null)
5757
* @param writeExpressions when false, {@code expression[]} is omitted from every issue
58-
* @return the OperationOutcome, or {@link Optional#empty()} when no unacceptable-category findings exist
58+
* @return the OperationOutcome, or {@link Optional#empty()} when no submitted-category findings exist
5959
*/
6060
public Optional<OperationOutcome> build(List<Result> results, MeasureReportRef measureReport, boolean writeExpressions) {
61-
// Group findings by unacceptable category (acceptable == false); a Result may map to several
61+
// Group findings by submitted category (submit == true); a Result may map to several
6262
// categories. Keyed by category id, not by the Category entity: Category defines no
6363
// equals/hashCode, so two instances of the same logical category (loaded in different
6464
// persistence contexts, say) would otherwise land in separate groups and emit a duplicate issue
@@ -71,7 +71,7 @@ public Optional<OperationOutcome> build(List<Result> results, MeasureReportRef m
7171
continue;
7272
}
7373
for (Category category : categories) {
74-
if (!category.isAcceptable()) {
74+
if (category.isSubmit()) {
7575
byCategoryId.computeIfAbsent(category.getId(), id -> new ArrayList<>()).add(result);
7676
}
7777
}

Java/validation/src/main/java/com/lantanagroup/link/validation/services/ReadyForValidationConsumer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,9 @@ protected void process(ConsumerRecord<ReadyForValidation.Key, ReadyForValidation
9393
}
9494

9595
/**
96-
* When enabled, builds the pre-qualification OperationOutcome for the patient's unacceptable-category
96+
* When enabled, builds the pre-qualification OperationOutcome for the patient's submitted-category
9797
* findings and appends it to the same patient NDJSON blob in ABS. No-op when the flag is off, when
98-
* there is no blob storage or payload URI (e.g. local/dev), or when there are no unacceptable findings.
98+
* there is no blob storage or payload URI (e.g. local/dev), or when there are no submitted findings.
9999
*/
100100
private void appendPreQualOperationOutcome(Bundle bundle, List<Result> results, String payloadUri) {
101101
if (!preQualificationConfig.isWritePreQualOperationOutcome()) {

Java/validation/src/test/java/com/lantanagroup/link/validation/services/PreQualOperationOutcomeBuilderTest.java

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,14 @@ void setUp() {
3636
// -------------------------------------------------------------------------
3737

3838
private Category category(String id, boolean acceptable) {
39+
return category(id, acceptable, true);
40+
}
41+
42+
private Category category(String id, boolean acceptable, boolean submit) {
3943
Category category = new Category();
4044
category.setId(id);
4145
category.setAcceptable(acceptable);
46+
category.setSubmit(submit);
4247
return category;
4348
}
4449

@@ -59,7 +64,7 @@ private List<String> expressionStrings(OperationOutcome.OperationOutcomeIssueCom
5964
// -------------------------------------------------------------------------
6065

6166
@Test
62-
void build_oneIssuePerUnacceptableCategory_withOoTotal() {
67+
void build_oneIssuePerSubmittedCategory_withOoTotal() {
6368
Result r1 = result("Code is inactive.", "expr1", category("inactive_code", false));
6469
Result r2 = result("Unable to validate.", "expr2", category("unable_to_validate_code", false));
6570

@@ -133,7 +138,7 @@ void build_distinctCategoryInstancesWithSameId_produceASingleIssue() {
133138
}
134139

135140
@Test
136-
void build_oneResultMappingToMultipleUnacceptableCategories_producesAnIssuePerCategory() {
141+
void build_oneResultMappingToMultipleSubmittedCategories_producesAnIssuePerCategory() {
137142
Result r = result("msg", "expr", category("cat_a", false), category("cat_b", false));
138143

139144
OperationOutcome oo = builder.build(List.of(r), MEASURE_REPORT, true).orElseThrow();
@@ -142,23 +147,41 @@ void build_oneResultMappingToMultipleUnacceptableCategories_producesAnIssuePerCa
142147
}
143148

144149
@Test
145-
void build_excludesAcceptableCategories() {
146-
Result unacceptable = result("bad", "expr1", category("inactive_code", false));
147-
Result acceptable = result("ok", "expr2", category("incorrect_display_value_for_code", true));
150+
void build_includesSubmittedCategoriesRegardlessOfAcceptable() {
151+
Result submitted = result("included", "expr1", category("submitted", true, true));
152+
Result nonSubmitted = result("excluded", "expr2", category("not-submitted", false, false));
148153

149-
OperationOutcome oo = builder.build(List.of(unacceptable, acceptable), MEASURE_REPORT, true).orElseThrow();
154+
OperationOutcome oo = builder.build(List.of(submitted, nonSubmitted), MEASURE_REPORT, true).orElseThrow();
150155

151156
assertEquals(1, oo.getIssue().size());
152157
CodeType cat = (CodeType) oo.getIssueFirstRep()
153158
.getExtensionByUrl(PreQualOperationOutcomeBuilder.PQ_ISSUE_CAT_URL).getValue();
154-
assertEquals("inactive_code", cat.getValue());
159+
assertEquals("submitted", cat.getValue());
160+
int total = ((IntegerType) oo.getExtensionByUrl(PreQualOperationOutcomeBuilder.OO_TOTAL_URL).getValue()).getValue();
161+
assertEquals(1, total);
162+
}
163+
164+
@Test
165+
void build_resultWithMixedSubmitCategories_emitsOnlySubmittedCategory() {
166+
Result result = result("message", "expr",
167+
category("submitted", false, true),
168+
category("not-submitted", false, false));
169+
170+
OperationOutcome oo = builder.build(List.of(result), MEASURE_REPORT, true).orElseThrow();
171+
172+
assertEquals(1, oo.getIssue().size());
173+
CodeType category = (CodeType) oo.getIssueFirstRep()
174+
.getExtensionByUrl(PreQualOperationOutcomeBuilder.PQ_ISSUE_CAT_URL).getValue();
175+
assertEquals("submitted", category.getValue());
176+
int total = ((IntegerType) oo.getExtensionByUrl(PreQualOperationOutcomeBuilder.OO_TOTAL_URL).getValue()).getValue();
177+
assertEquals(1, total);
155178
}
156179

157180
@Test
158-
void build_noUnacceptableFindings_returnsEmpty() {
159-
Result acceptable = result("ok", "expr", category("incorrect_display_value_for_code", true));
181+
void build_noSubmittedFindings_returnsEmpty() {
182+
Result nonSubmitted = result("not submitted", "expr", category("not-submitted", false, false));
160183

161-
assertTrue(builder.build(List.of(acceptable), MEASURE_REPORT, true).isEmpty());
184+
assertTrue(builder.build(List.of(nonSubmitted), MEASURE_REPORT, true).isEmpty());
162185
}
163186

164187
@Test

Java/validation/src/test/java/com/lantanagroup/link/validation/services/ReadyForValidationConsumerTest.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ private void stubBlobDownload() {
513513
}
514514

515515
@Test
516-
void process_flagOn_unacceptableFindings_appendsOperationOutcomeToSameBlob() throws Exception {
516+
void process_flagOn_submittedFindings_appendsOperationOutcomeToSameBlob() throws Exception {
517517
preQualificationConfig.setWritePreQualOperationOutcome(true);
518518
stubBlobDownload();
519519

@@ -522,7 +522,7 @@ void process_flagOn_unacceptableFindings_appendsOperationOutcomeToSameBlob() thr
522522
when(jsonParser.encodeResourceToString(any()))
523523
.thenReturn("{\"resourceType\":\"OperationOutcome\"}");
524524

525-
Result result = resultWithCategories(List.of(categoryWithAcceptable(false)));
525+
Result result = resultWithCategories(List.of(categoryWithSubmit(true)));
526526
result.setMessage("Code is inactive.");
527527
when(validationService.validate(bundle)).thenReturn(List.of(result));
528528

@@ -532,10 +532,10 @@ void process_flagOn_unacceptableFindings_appendsOperationOutcomeToSameBlob() thr
532532
}
533533

534534
@Test
535-
void process_flagOff_unacceptableFindings_doesNotAppend() throws Exception {
535+
void process_flagOff_submittedFindings_doesNotAppend() throws Exception {
536536
stubBlobDownload(); // flag defaults to false
537537

538-
Result result = resultWithCategories(List.of(categoryWithAcceptable(false)));
538+
Result result = resultWithCategories(List.of(categoryWithSubmit(true)));
539539
when(validationService.validate(bundle)).thenReturn(List.of(result));
540540

541541
consumer.process(buildRecord(PAYLOAD_URI));
@@ -544,11 +544,11 @@ void process_flagOff_unacceptableFindings_doesNotAppend() throws Exception {
544544
}
545545

546546
@Test
547-
void process_flagOn_noUnacceptableFindings_doesNotAppend() throws Exception {
547+
void process_flagOn_noSubmittedFindings_doesNotAppend() throws Exception {
548548
preQualificationConfig.setWritePreQualOperationOutcome(true);
549549
stubBlobDownload();
550550

551-
Result result = resultWithCategories(List.of(categoryWithAcceptable(true)));
551+
Result result = resultWithCategories(List.of(categoryWithSubmit(false)));
552552
when(validationService.validate(bundle)).thenReturn(List.of(result));
553553

554554
consumer.process(buildRecord(PAYLOAD_URI));
@@ -571,7 +571,7 @@ void process_flagOn_bundleAlreadyHasPreQualOperationOutcome_doesNotAppendAgain()
571571

572572
stubBlobDownload();
573573

574-
Result result = resultWithCategories(List.of(categoryWithAcceptable(false)));
574+
Result result = resultWithCategories(List.of(categoryWithSubmit(true)));
575575
result.setMessage("Code is inactive.");
576576
when(validationService.validate(bundle)).thenReturn(List.of(result));
577577

@@ -596,7 +596,7 @@ void process_flagOn_bundleHasUnrelatedOperationOutcome_stillAppends() throws Exc
596596
when(fhirContext.newJsonParser()).thenReturn(jsonParser);
597597
when(jsonParser.encodeResourceToString(any())).thenReturn("{\"resourceType\":\"OperationOutcome\"}");
598598

599-
Result result = resultWithCategories(List.of(categoryWithAcceptable(false)));
599+
Result result = resultWithCategories(List.of(categoryWithSubmit(true)));
600600
result.setMessage("Code is inactive.");
601601
when(validationService.validate(bundle)).thenReturn(List.of(result));
602602

@@ -610,7 +610,7 @@ void process_flagOn_noBlobService_doesNotAppend() throws Exception {
610610
preQualificationConfig.setWritePreQualOperationOutcome(true);
611611
stubRestRetrieval(); // no blob service -> bundle comes via REST, append is skipped
612612

613-
Result result = resultWithCategories(List.of(categoryWithAcceptable(false)));
613+
Result result = resultWithCategories(List.of(categoryWithSubmit(true)));
614614
when(validationService.validate(bundle)).thenReturn(List.of(result));
615615

616616
consumerWithoutBlobStorage.process(buildRecord(PAYLOAD_URI));
@@ -626,7 +626,7 @@ void process_flagOn_nullPayloadUri_doesNotAppend() throws Exception {
626626
preQualificationConfig.setWritePreQualOperationOutcome(true);
627627
stubRestRetrieval(); // no payload URI -> bundle comes via REST
628628

629-
Result result = resultWithCategories(List.of(categoryWithAcceptable(false)));
629+
Result result = resultWithCategories(List.of(categoryWithSubmit(true)));
630630
result.setMessage("Code is inactive.");
631631
when(validationService.validate(bundle)).thenReturn(List.of(result));
632632

0 commit comments

Comments
 (0)