Skip to content

Commit 30e9043

Browse files
authored
Merge pull request #13831 from SORMAS-Foundation/bugfix-13793-na_test_result_confirmation_dialog
#13793 - Disabled classification popup for pathogen tests that are negative
2 parents fcb1f01 + f27172d commit 30e9043

1 file changed

Lines changed: 79 additions & 28 deletions

File tree

sormas-ui/src/main/java/de/symeda/sormas/ui/samples/PathogenTestController.java

Lines changed: 79 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,33 @@ public void savePathogenTests(List<PathogenTestDto> pathogenTests, SampleReferen
351351
TRAY_NOTIFICATION);
352352
}
353353

354+
/**
355+
* Handles the association of a pathogen test with a case.
356+
* Based on pathogen test results the following logic is applied:
357+
*
358+
* <p>Negative test result AND test result verified
359+
* <ol>
360+
* <li>Tested disease == case disease AND test result != sample pathogen test result: Ask user whether to update the sample pathogen test result</li>
361+
* <li>Tested disease != case disease: Do nothing</li>
362+
* </ol>
363+
* </p>
364+
* <p>Positive test result AND test result verified
365+
* <ol>
366+
* <li>Tested disease == case disease: Ask user whether to update the sample pathogen test result
367+
* <ol>
368+
* <li>Tested disease variant != case disease variant: Ask user to change the case disease variant</li>
369+
* <li>Case classification != confirmed: Ask user whether to confirm the case</li>
370+
* </ol>
371+
* </li>
372+
* <li>Tested disease != case disease: Ask user to create a new case for the tested disease</li>
373+
* </ol>
374+
* </p>
375+
*
376+
* @param pathogenTests the pathogen tests
377+
* @param associatedCase the associated case
378+
* @param suppressNavigateToCase whether to suppress navigation to the case
379+
*
380+
*/
354381
private void handleAssociatedCase(List<PathogenTestDto> pathogenTests, CaseReferenceDto associatedCase, boolean suppressNavigateToCase) {
355382

356383
if (!UiUtil.permitted(UserRight.CASE_EDIT)) {
@@ -367,46 +394,68 @@ private void handleAssociatedCase(List<PathogenTestDto> pathogenTests, CaseRefer
367394
// a.2) Case classification != confirmed: Ask user whether to confirm the case
368395
// b) Tested disease != case disease: Ask user to create a new case for the tested disease
369396

370-
CaseDataDto caze = FacadeProvider.getCaseFacade().getCaseDataByUuid(associatedCase.getUuid());
397+
final CaseDataDto caze = FacadeProvider.getCaseFacade().getCaseDataByUuid(associatedCase.getUuid());
371398

372-
Map<Disease, List<PathogenTestDto>> testsByDisease = pathogenTests.stream().collect(Collectors.groupingBy(PathogenTestDto::getTestedDisease));
373-
Optional<PathogenTestDto> positiveWithSameDisease = testsByDisease.getOrDefault(caze.getDisease(), Collections.emptyList())
399+
final Map<Disease, List<PathogenTestDto>> testsByDisease =
400+
pathogenTests.stream().collect(Collectors.groupingBy(PathogenTestDto::getTestedDisease));
401+
final Optional<PathogenTestDto> positiveWithSameDisease = testsByDisease.getOrDefault(caze.getDisease(), Collections.emptyList())
374402
.stream()
375403
.filter(t -> t.getTestResult() == PathogenTestResultType.POSITIVE && Boolean.TRUE.equals(t.getTestResultVerified()))
376404
.findFirst();
377405

378-
Optional<PathogenTestDto> negativeWithSameDisease = testsByDisease.getOrDefault(caze.getDisease(), Collections.emptyList())
406+
final Optional<PathogenTestDto> negativeWithSameDisease = testsByDisease.getOrDefault(caze.getDisease(), Collections.emptyList())
379407
.stream()
380408
.filter(t -> t.getTestResult() == PathogenTestResultType.NEGATIVE && Boolean.TRUE.equals(t.getTestResultVerified()))
381409
.findFirst();
382410

383-
PathogenTestDto resultedPathogenTest;
384-
if (positiveWithSameDisease.isPresent()) {
385-
resultedPathogenTest = positiveWithSameDisease.get();
386-
} else if (negativeWithSameDisease.isPresent()) {
387-
resultedPathogenTest = negativeWithSameDisease.get();
388-
} else {
389-
resultedPathogenTest = null;
390-
}
411+
final boolean hasVerifiedPositiveTest = positiveWithSameDisease.isPresent();
412+
final boolean hasVerifiedNegativeTest = negativeWithSameDisease.isPresent();
413+
414+
final boolean hasVerifiedTests = hasVerifiedPositiveTest || hasVerifiedNegativeTest;
415+
416+
417+
// 1. Ask user to update sample overall result if latest test result is different
418+
// 2. Ask user to update disease variant if case variant is different
419+
// 3. Ask user if they want to confirm the case only if any of the tests are verified either positive or negative (not pending or other)
420+
421+
// We need to display popups if any of the tests are verified either positive or negative
422+
if (hasVerifiedTests) {
423+
// get either the positive or negative test
424+
final PathogenTestDto resultedPathogenTest = hasVerifiedPositiveTest ? positiveWithSameDisease.get() : negativeWithSameDisease.get();
425+
426+
// just a sanity check
427+
if (resultedPathogenTest == null) {
428+
throw new IllegalStateException("No verified test found for disease " + caze.getDisease());
429+
}
391430

392-
if (resultedPathogenTest != null) {
393-
showChangeAssociatedSampleResultDialog(resultedPathogenTest, (accepted) -> {
394-
if (accepted) {
395-
checkForDiseaseVariantUpdate(resultedPathogenTest, caze, suppressNavigateToCase, this::showConfirmCaseDialog);
431+
showChangeAssociatedSampleResultDialog(resultedPathogenTest, accepted -> { // Change sample result
432+
// Accepted SR may have changed
433+
if (Boolean.TRUE.equals(accepted)) {
434+
checkForDiseaseVariantUpdate(resultedPathogenTest, caze, suppressNavigateToCase, c -> { // Update disease variant
435+
// Only show the confirmation dialog if there are verified positive tests
436+
// We decided this based on the intented text in the dialog but based on the test results instead of the sample overall result
437+
if (hasVerifiedPositiveTest) {
438+
// The final laboratory result of the sample the saved pathogen test belongs to is positive. <-- sample overall result
439+
// However, the case cannot be automatically classified as a confirmed case because it is missing some information.
440+
// Do you want to set the case classification to confirmed anyway?
441+
this.showConfirmCaseDialog(c); // Case classification
442+
}
443+
});
396444
}
397445
});
398446
}
399447

400448
testsByDisease.keySet().stream().filter(disease -> disease != caze.getDisease()).forEach((disease) -> {
401449
List<PathogenTestDto> tests = testsByDisease.get(disease);
402450

403-
Optional<PathogenTestDto> positiveWithOtherDisease =
404-
tests.stream().filter(t -> t.getTestResult() == PathogenTestResultType.POSITIVE && Boolean.TRUE.equals(t.getTestResultVerified())).findFirst();
451+
Optional<PathogenTestDto> positiveWithOtherDisease = tests.stream()
452+
.filter(t -> t.getTestResult() == PathogenTestResultType.POSITIVE && Boolean.TRUE.equals(t.getTestResultVerified()))
453+
.findFirst();
405454

406455
if (positiveWithOtherDisease.isPresent()) {
407456
List<CaseDataDto> duplicatedCases =
408457
FacadeProvider.getCaseFacade().getDuplicatesWithPathogenTest(caze.getPerson(), positiveWithOtherDisease.get());
409-
if (duplicatedCases == null || duplicatedCases.size() == 0) {
458+
if (duplicatedCases == null || duplicatedCases.isEmpty()) {
410459
PathogenTestDto positiveTestWithOtherDisease = positiveWithOtherDisease.get();
411460

412461
showCaseCloningWithNewDiseaseDialog(
@@ -466,8 +515,9 @@ private void handleAssociatedContact(List<PathogenTestDto> pathogenTests, Contac
466515
testsByDisease.keySet().stream().filter(disease -> disease != contact.getDisease()).forEach((disease) -> {
467516
List<PathogenTestDto> tests = testsByDisease.get(disease);
468517

469-
Optional<PathogenTestDto> positiveWithOtherDisease =
470-
tests.stream().filter(t -> t.getTestResult() == PathogenTestResultType.POSITIVE && Boolean.TRUE.equals(t.getTestResultVerified())).findFirst();
518+
Optional<PathogenTestDto> positiveWithOtherDisease = tests.stream()
519+
.filter(t -> t.getTestResult() == PathogenTestResultType.POSITIVE && Boolean.TRUE.equals(t.getTestResultVerified()))
520+
.findFirst();
471521
if (positiveWithOtherDisease.isPresent()) {
472522
List<CaseDataDto> duplicatedCases =
473523
FacadeProvider.getCaseFacade().getDuplicatesWithPathogenTest(contact.getPerson(), positiveWithOtherDisease.get());
@@ -530,8 +580,9 @@ private void handleAssociatedEventParticipant(List<PathogenTestDto> pathogenTest
530580
testsByDisease.keySet().stream().filter(disease -> disease != eventDisease).forEach((disease) -> {
531581
List<PathogenTestDto> tests = testsByDisease.get(disease);
532582

533-
Optional<PathogenTestDto> positiveWithOtherDisease =
534-
tests.stream().filter(t -> t.getTestResult() == PathogenTestResultType.POSITIVE && Boolean.TRUE.equals(t.getTestResultVerified())).findFirst();
583+
Optional<PathogenTestDto> positiveWithOtherDisease = tests.stream()
584+
.filter(t -> t.getTestResult() == PathogenTestResultType.POSITIVE && Boolean.TRUE.equals(t.getTestResultVerified()))
585+
.findFirst();
535586
if (positiveWithOtherDisease.isPresent() && UiUtil.enabled(FeatureType.CASE_SURVEILANCE)) {
536587
List<CaseDataDto> duplicatedCases = FacadeProvider.getCaseFacade()
537588
.getDuplicatesWithPathogenTest(eventParticipant.getPerson().toReference(), positiveWithOtherDisease.get());
@@ -616,7 +667,7 @@ public void showConvertEventParticipantToCaseDialog(EventParticipantDto eventPar
616667
I18nProperties.getString(Strings.no),
617668
800,
618669
confirmed -> {
619-
if (confirmed) {
670+
if (Boolean.TRUE.equals(confirmed)) {
620671
if (differentDiseases) {
621672
ControllerProvider.getCaseController().createFromEventParticipantDifferentDisease(eventParticipant, testedDisease);
622673
} else {
@@ -635,7 +686,7 @@ public void showConvertContactToCaseDialog(ContactDto contact, Consumer<Boolean>
635686
I18nProperties.getString(Strings.no),
636687
800,
637688
confirmed -> {
638-
if (confirmed) {
689+
if (Boolean.TRUE.equals(confirmed)) {
639690
ControllerProvider.getCaseController().createFromContact(contact);
640691
}
641692
callback.accept(confirmed);
@@ -650,7 +701,7 @@ public void showCreateContactCaseDialog(ContactDto contact, Disease disease) {
650701
I18nProperties.getString(Strings.no),
651702
800,
652703
confirmed -> {
653-
if (confirmed) {
704+
if (Boolean.TRUE.equals(confirmed)) {
654705
ControllerProvider.getCaseController().createFromUnrelatedContact(contact, disease);
655706
}
656707
});
@@ -670,7 +721,7 @@ public static void showCaseCloningWithNewDiseaseDialog(
670721
I18nProperties.getString(Strings.no),
671722
800,
672723
confirmed -> {
673-
if (confirmed) {
724+
if (Boolean.TRUE.equals(confirmed)) {
674725
existingCaseDto.setCaseClassification(CaseClassification.NOT_CLASSIFIED);
675726
existingCaseDto.setClassificationUser(null);
676727
existingCaseDto.setDisease(disease);
@@ -702,7 +753,7 @@ public void showConfirmCaseDialog(CaseDataDto caze) {
702753
I18nProperties.getString(Strings.no),
703754
800,
704755
confirmed -> {
705-
if (confirmed) {
756+
if (Boolean.TRUE.equals(confirmed)) {
706757
CaseDataDto caseDataByUuid = FacadeProvider.getCaseFacade().getCaseDataByUuid(caze.getUuid());
707758
caseDataByUuid.setCaseClassification(CaseClassification.CONFIRMED);
708759
FacadeProvider.getCaseFacade().save(caseDataByUuid);

0 commit comments

Comments
 (0)