From 41674a5d6cab34fcab6c579bbafe577f185d92b3 Mon Sep 17 00:00:00 2001 From: SergiuPacurariu Date: Tue, 14 Jan 2025 14:10:18 +0200 Subject: [PATCH] #13207 - [LUX] Automatic case processing for Pertussis cases --- .../processing/AbstractProcessingFlow.java | 18 ++++ .../AutomaticLabMessageProcessorTest.java | 85 +++++++++++++++++++ 2 files changed, 103 insertions(+) diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/externalmessage/processing/AbstractProcessingFlow.java b/sormas-api/src/main/java/de/symeda/sormas/api/externalmessage/processing/AbstractProcessingFlow.java index 5fc5b5bf63f..1a279a25e5c 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/externalmessage/processing/AbstractProcessingFlow.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/externalmessage/processing/AbstractProcessingFlow.java @@ -22,13 +22,19 @@ import org.slf4j.LoggerFactory; import de.symeda.sormas.api.CountryHelper; +import de.symeda.sormas.api.Disease; +import de.symeda.sormas.api.caze.CaseClassification; import de.symeda.sormas.api.caze.CaseDataDto; +import de.symeda.sormas.api.caze.CaseOutcome; +import de.symeda.sormas.api.caze.InvestigationStatus; import de.symeda.sormas.api.externalmessage.ExternalMessageDto; import de.symeda.sormas.api.feature.FeatureType; import de.symeda.sormas.api.infrastructure.facility.FacilityDto; import de.symeda.sormas.api.infrastructure.facility.FacilityReferenceDto; import de.symeda.sormas.api.infrastructure.facility.FacilityType; import de.symeda.sormas.api.person.PersonDto; +import de.symeda.sormas.api.sample.PathogenTestResultType; +import de.symeda.sormas.api.sample.PathogenTestType; import de.symeda.sormas.api.user.UserDto; import de.symeda.sormas.api.utils.dataprocessing.EntitySelection; import de.symeda.sormas.api.utils.dataprocessing.HandlerCallback; @@ -175,6 +181,18 @@ protected CaseDataDto buildCase(PersonDto person, ExternalMessageDto externalMes caseDto.setHealthFacility(processingFacade.getFacilityReferenceByUuid(FacilityDto.NONE_FACILITY_UUID)); } + if (processingFacade.isConfiguredCountry(CountryHelper.COUNTRY_CODE_LUXEMBOURG)) { + if (externalMessageDto.getDisease().equals(Disease.PERTUSSIS) + && externalMessageDto.getSampleReports().get(0).getTestReports().get(0).getTestResult().equals(PathogenTestResultType.POSITIVE)) { + PathogenTestType testType = externalMessageDto.getSampleReports().get(0).getTestReports().get(0).getTestType(); + if (testType.equals(PathogenTestType.CULTURE) || testType.equals(PathogenTestType.PCR_RT_PCR)) { + caseDto.setCaseClassification(CaseClassification.CONFIRMED); + } + } + caseDto.setInvestigationStatus(InvestigationStatus.PENDING); + caseDto.setOutcome(CaseOutcome.NO_OUTCOME); + } + caseDto.setVaccinationStatus(externalMessageDto.getVaccinationStatus()); caseDto.getHospitalization().setAdmittedToHealthFacility(externalMessageDto.getAdmittedToHealthFacility()); diff --git a/sormas-backend/src/test/java/de/symeda/sormas/backend/externalmessage/labmessage/AutomaticLabMessageProcessorTest.java b/sormas-backend/src/test/java/de/symeda/sormas/backend/externalmessage/labmessage/AutomaticLabMessageProcessorTest.java index 85da716cf6f..fe82a6270d6 100644 --- a/sormas-backend/src/test/java/de/symeda/sormas/backend/externalmessage/labmessage/AutomaticLabMessageProcessorTest.java +++ b/sormas-backend/src/test/java/de/symeda/sormas/backend/externalmessage/labmessage/AutomaticLabMessageProcessorTest.java @@ -20,6 +20,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; import java.util.Collections; import java.util.Date; @@ -31,8 +32,11 @@ import org.junit.jupiter.api.Test; import de.symeda.sormas.api.Disease; +import de.symeda.sormas.api.caze.CaseClassification; import de.symeda.sormas.api.caze.CaseCriteria; import de.symeda.sormas.api.caze.CaseDataDto; +import de.symeda.sormas.api.caze.CaseOutcome; +import de.symeda.sormas.api.caze.InvestigationStatus; import de.symeda.sormas.api.externalmessage.ExternalMessageDto; import de.symeda.sormas.api.externalmessage.ExternalMessageStatus; import de.symeda.sormas.api.externalmessage.ExternalMessageType; @@ -58,7 +62,9 @@ import de.symeda.sormas.api.utils.DateHelper; import de.symeda.sormas.api.utils.dataprocessing.ProcessingResult; import de.symeda.sormas.backend.AbstractBeanTest; +import de.symeda.sormas.backend.MockProducer; import de.symeda.sormas.backend.TestDataCreator; +import de.symeda.sormas.backend.common.ConfigFacadeEjb; import de.symeda.sormas.backend.disease.DiseaseConfigurationFacadeEjb; public class AutomaticLabMessageProcessorTest extends AbstractBeanTest { @@ -217,6 +223,7 @@ public void testProcessWithExistingPersonAndCase() throws ExecutionException, In /** * External message with sample date in the threshold period should generate a new sample to the existing case + * * @throws ExecutionException * @throws InterruptedException */ @@ -410,6 +417,84 @@ public void testProcessMessageWithNoNationalHealthId() throws ExecutionException assertThat(pathogenTests, hasSize(1)); } + @Test + public void testProcessPertussisMessageTestTypeCulture() throws ExecutionException, InterruptedException { + MockProducer.getProperties().setProperty(ConfigFacadeEjb.COUNTRY_LOCALE, "lu"); + ExternalMessageDto cultureMessage = createExternalMessage((messageDto) -> { + messageDto.setDisease(Disease.PERTUSSIS); + messageDto.getSampleReports().get(0).getTestReports().get(0).setTestType(PathogenTestType.CULTURE); + messageDto.getSampleReports().get(0).getTestReports().get(0).setTestResult(PathogenTestResultType.POSITIVE); + }); + ProcessingResult result = runFlow(cultureMessage); + assertThat(result.getStatus(), is(DONE)); + assertThat(cultureMessage.getStatus(), is(ExternalMessageStatus.PROCESSED)); + assertThat(getExternalMessageFacade().getByUuid(cultureMessage.getUuid()).getStatus(), is(ExternalMessageStatus.PROCESSED)); + CaseDataDto positiveCase = getCaseData(); + assertThat(positiveCase, is(notNullValue())); + assertThat(positiveCase.getDisease(), is(cultureMessage.getDisease())); + assertThat(positiveCase.getCaseClassification(), is(CaseClassification.CONFIRMED)); + assertThat(positiveCase.getInvestigationStatus(), is(InvestigationStatus.PENDING)); + assertThat(positiveCase.getOutcome(), is(CaseOutcome.NO_OUTCOME)); + } + + @Test + public void testProcessPertussisTestTypePCR() throws ExecutionException, InterruptedException { + MockProducer.getProperties().setProperty(ConfigFacadeEjb.COUNTRY_LOCALE, "lu"); + ExternalMessageDto pcrMessage = createExternalMessage((messageDto) -> { + messageDto.setDisease(Disease.PERTUSSIS); + messageDto.getSampleReports().get(0).getTestReports().get(0).setTestType(PathogenTestType.PCR_RT_PCR); + messageDto.getSampleReports().get(0).getTestReports().get(0).setTestResult(PathogenTestResultType.POSITIVE); + }); + runFlow(pcrMessage); + assertThat(pcrMessage.getStatus(), is(ExternalMessageStatus.PROCESSED)); + CaseDataDto pcrCase = getCaseData(); + assertThat(pcrCase, is(notNullValue())); + assertThat(pcrCase.getDisease(), is(pcrMessage.getDisease())); + assertThat(pcrCase.getCaseClassification(), is(CaseClassification.CONFIRMED)); + assertThat(pcrCase.getInvestigationStatus(), is(InvestigationStatus.PENDING)); + assertThat(pcrCase.getOutcome(), is(CaseOutcome.NO_OUTCOME)); + } + + @Test + public void testProcessPertussisTestNegativeResult() throws ExecutionException, InterruptedException { + ExternalMessageDto negativeMessage = createExternalMessage((messageDto) -> { + messageDto.setDisease(Disease.PERTUSSIS); + messageDto.getSampleReports().get(0).getTestReports().get(0).setTestType(PathogenTestType.CULTURE); + messageDto.getSampleReports().get(0).getTestReports().get(0).setTestResult(PathogenTestResultType.NEGATIVE); + }); + runFlow(negativeMessage); + assertThat(negativeMessage.getStatus(), is(ExternalMessageStatus.PROCESSED)); + CaseDataDto negativeCase = getCaseData(); + assertThat(negativeCase, is(notNullValue())); + assertThat(negativeCase.getDisease(), is(negativeMessage.getDisease())); + assertThat(negativeCase.getCaseClassification(), is(CaseClassification.NOT_CLASSIFIED)); + assertThat(negativeCase.getInvestigationStatus(), is(InvestigationStatus.PENDING)); + assertThat(negativeCase.getOutcome(), is(CaseOutcome.NO_OUTCOME)); + } + + @Test + public void testProcessPertussisOtherTestType() throws ExecutionException, InterruptedException { + ExternalMessageDto rapidTestMessage = createExternalMessage((messageDto) -> { + messageDto.setDisease(Disease.PERTUSSIS); + messageDto.getSampleReports().get(0).getTestReports().get(0).setTestType(PathogenTestType.RAPID_TEST); + messageDto.getSampleReports().get(0).getTestReports().get(0).setTestResult(PathogenTestResultType.POSITIVE); + }); + runFlow(rapidTestMessage); + assertThat(rapidTestMessage.getStatus(), is(ExternalMessageStatus.PROCESSED)); + CaseDataDto rapidTestcase = getCaseData(); + assertThat(rapidTestcase, is(notNullValue())); + assertThat(rapidTestcase.getDisease(), is(rapidTestMessage.getDisease())); + assertThat(rapidTestcase.getCaseClassification(), is(CaseClassification.NOT_CLASSIFIED)); + assertThat(rapidTestcase.getInvestigationStatus(), is(InvestigationStatus.PENDING)); + assertThat(rapidTestcase.getOutcome(), is(CaseOutcome.NO_OUTCOME)); + } + + private CaseDataDto getCaseData() { + List persons = getPersonFacade().getAllAfter(new Date(0)); + List cases = getCaseFacade().getByPersonUuids(persons.stream().map(PersonDto::getUuid).collect(Collectors.toList())); + return cases.get(0); + } + private ProcessingResult runFlow(ExternalMessageDto labMessage) throws ExecutionException, InterruptedException { return flow.processLabMessage(labMessage);