Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,15 @@ public static String mapSampleMaterialToEpipulseCode(SampleMaterial sampleMateri
return "NASALSWAB";
case THROAT_SWAB:
case RECTAL_SWAB:
case CLINICAL_SAMPLE:
case OTHER:
return "OTH";
case SALIVA:
return "SALOR"; // Saliva/oral fluid
case EDTA_WHOLE_BLOOD:
return "EDTA"; // EDTA whole blood
case DRY_BLOOD:
return "DRYBLOSP"; // Dry blood spot
default:
return null;
}
Expand Down Expand Up @@ -234,10 +237,10 @@ public static String mapClusterTypeToEpipulseCode(ClusterType clusterType) {
* Maps SORMAS CaseImportedStatus enum to EpiPulse imported status codes.
* <p>
* EpiPulse Reference Values:
* - AUTOCH = Autochthonous (not imported case)
* - NOTIMP = Not imported case
* - IMP = Imported case
* - IMPR = Import-related case
* - UNK = Unknown importation status
* - IMPREL = Import-related case
* - IMPUNK = Unknown importation status
*
* @param importedStatus
* SORMAS case imported status enum
Expand All @@ -252,11 +255,11 @@ public static String mapCaseImportedStatusToEpipulseCode(CaseImportedStatus impo
case IMPORTED_CASE:
return "IMP";
case IMPORT_RELATED_CASE:
return "IMPR";
return "IMPREL";
case UNKNOWN_IMPORTATION_STATUS:
return "UNK";
return "IMPUNK";
case NOT_IMPORTED_CASE:
return "AUTOCH";
return "NOTIMP";
default:
return null;
}
Expand All @@ -279,6 +282,8 @@ public static String mapCaseImportedStatusToEpipulseCode(CaseImportedStatus impo
* Diarrhea symptom state
* @param otitisMedia
* Otitis media symptom state
* @param pneumonia
* Pneumonia (clinical or radiologic) symptom state
* @param otherComplications
* Other complications symptom state
* @return List of EpiPulse complication codes (empty list returns "NONE" in CSV)
Expand All @@ -287,6 +292,7 @@ public static List<String> mapSymptomsToComplicationCodes(
SymptomState acuteEncephalitis,
SymptomState diarrhea,
SymptomState otitisMedia,
SymptomState pneumonia,
SymptomState otherComplications) {

List<String> complications = new ArrayList<>();
Expand All @@ -300,11 +306,13 @@ public static List<String> mapSymptomsToComplicationCodes(
if (otitisMedia == SymptomState.YES) {
complications.add("OME");
}
if (pneumonia == SymptomState.YES) {
complications.add("PNEU");
}
if (otherComplications == SymptomState.YES) {
complications.add("OTH");
}

// Note: PNEU (pneumonia) not currently available in SORMAS Symptoms for MEAS
// If no complications found, empty list will result in "NONE" in CSV

return complications;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package de.symeda.sormas.api.epipulse;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

import org.junit.jupiter.api.Test;

import de.symeda.sormas.api.sample.SampleMaterial;

public class EpipulseLaboratoryMapperTest {

@Test
public void testMapSampleMaterialToEpipulseCode_DryBlood() {
assertEquals("DRYBLOSP", EpipulseLaboratoryMapper.mapSampleMaterialToEpipulseCode(SampleMaterial.DRY_BLOOD));
}

@Test
public void testMapSampleMaterialToEpipulseCode_Blood() {
assertEquals("SER", EpipulseLaboratoryMapper.mapSampleMaterialToEpipulseCode(SampleMaterial.BLOOD));
}

@Test
public void testMapSampleMaterialToEpipulseCode_Sera() {
assertEquals("SER", EpipulseLaboratoryMapper.mapSampleMaterialToEpipulseCode(SampleMaterial.SERA));
}

@Test
public void testMapSampleMaterialToEpipulseCode_Urine() {
assertEquals("URINE", EpipulseLaboratoryMapper.mapSampleMaterialToEpipulseCode(SampleMaterial.URINE));
}

@Test
public void testMapSampleMaterialToEpipulseCode_NasalSwab() {
assertEquals("NASALSWAB", EpipulseLaboratoryMapper.mapSampleMaterialToEpipulseCode(SampleMaterial.NASAL_SWAB));
}

@Test
public void testMapSampleMaterialToEpipulseCode_ThroatSwab() {
assertEquals("OTH", EpipulseLaboratoryMapper.mapSampleMaterialToEpipulseCode(SampleMaterial.THROAT_SWAB));
}

@Test
public void testMapSampleMaterialToEpipulseCode_RectalSwab() {
assertEquals("OTH", EpipulseLaboratoryMapper.mapSampleMaterialToEpipulseCode(SampleMaterial.RECTAL_SWAB));
}

@Test
public void testMapSampleMaterialToEpipulseCode_ClinicalSample() {
assertEquals("OTH", EpipulseLaboratoryMapper.mapSampleMaterialToEpipulseCode(SampleMaterial.CLINICAL_SAMPLE));
}

@Test
public void testMapSampleMaterialToEpipulseCode_Other() {
assertEquals("OTH", EpipulseLaboratoryMapper.mapSampleMaterialToEpipulseCode(SampleMaterial.OTHER));
}

@Test
public void testMapSampleMaterialToEpipulseCode_Saliva() {
assertEquals("SALOR", EpipulseLaboratoryMapper.mapSampleMaterialToEpipulseCode(SampleMaterial.SALIVA));
}

@Test
public void testMapSampleMaterialToEpipulseCode_EdtaWholeBlood() {
assertEquals("EDTA", EpipulseLaboratoryMapper.mapSampleMaterialToEpipulseCode(SampleMaterial.EDTA_WHOLE_BLOOD));
}

@Test
public void testMapSampleMaterialToEpipulseCode_UnmappedMaterial() {
assertNull(EpipulseLaboratoryMapper.mapSampleMaterialToEpipulseCode(SampleMaterial.CEREBROSPINAL_FLUID));
assertNull(EpipulseLaboratoryMapper.mapSampleMaterialToEpipulseCode(SampleMaterial.STOOL));
}

@Test
public void testMapSampleMaterialToEpipulseCode_Null() {
assertNull(EpipulseLaboratoryMapper.mapSampleMaterialToEpipulseCode(null));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ public String buildPathogenTestsCte() {
" pathogentest.testtype," +
" pathogentest.testresult" +
" ), '#'" +
" ORDER BY pathogentest.testdatetime DESC) AS all_pathogen_tests_from_latest" +
" ORDER BY COALESCE(pathogentest.testdatetime, pathogentest.reportdate, pathogentest.creationdate) DESC) AS all_pathogen_tests_from_latest" +
" FROM pathogentest" +
" INNER JOIN case_all_samples_from_latest" +
" ON pathogentest.sample_id = ANY" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ private String buildPneuSerotypingDataCte() {
" AND s.deleted = false " +
" AND pt.testtype IN ('SEROGROUPING', 'GENOTYPING', 'WHOLE_GENOME_SEQUENCING') " +
" AND pt.typingid IS NOT NULL " +
" ORDER BY pt.testdatetime DESC " +
" ORDER BY COALESCE(pt.testdatetime, pt.reportdate, pt.creationdate) DESC NULLS LAST, pt.id DESC " +
" LIMIT 1) as serotype " +
" FROM filtered_cases c)";
//@formatter:on
Expand All @@ -240,7 +240,7 @@ private String buildPneuPathogenDetectionMethodCte() {
" WHERE s.associatedcase_id = c.id " +
" AND s.deleted = false " +
" AND pt.testresultverified = true " +
" ORDER BY pt.testdatetime DESC " +
" ORDER BY COALESCE(pt.testdatetime, pt.reportdate, pt.creationdate) DESC NULLS LAST, pt.id DESC " +
" LIMIT 1) as detection_method " +
" FROM filtered_cases c)";
//@formatter:on
Expand Down Expand Up @@ -341,7 +341,7 @@ private String buildPneuAstDataCte() {
" LEFT JOIN pathogentest pt ON pt.sample_id = s.id " +
" AND pt.testtype = 'ANTIBIOTIC_SUSCEPTIBILITY' " +
" LEFT JOIN drugsusceptibility ds ON pt.drugsusceptibility_id = ds.id " +
" ORDER BY c.id, pt.testdatetime DESC" +
" ORDER BY c.id, COALESCE(pt.testdatetime, pt.reportdate, pt.creationdate) DESC NULLS LAST, pt.id DESC" +
")";
//@formatter:on
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,19 +136,21 @@ protected void mapDiseaseSpecificFields(EpipulseDiseaseExportEntryDto dto, Objec
}
}

// Complications mapping (4 fields)
// Complications mapping (5 fields)
String acuteEncephalitisRaw = (String) row[++index];
String diarrheaRaw = (String) row[++index];
String otitisMediaRaw = (String) row[++index];
String pneumoniaRaw = (String) row[++index];
String otherComplicationsRaw = (String) row[++index];

SymptomState acuteEncephalitis = parseSymptomState(acuteEncephalitisRaw);
SymptomState diarrhea = parseSymptomState(diarrheaRaw);
SymptomState otitisMedia = parseSymptomState(otitisMediaRaw);
SymptomState pneumonia = parseSymptomState(pneumoniaRaw);
SymptomState otherComplications = parseSymptomState(otherComplicationsRaw);

dto.setComplicationDiagnosis(
EpipulseLaboratoryMapper.mapSymptomsToComplicationCodes(acuteEncephalitis, diarrhea, otitisMedia, otherComplications));
EpipulseLaboratoryMapper.mapSymptomsToComplicationCodes(acuteEncephalitis, diarrhea, otitisMedia, pneumonia, otherComplications));

// Clinical criteria status
String clinicalConfirmationRaw = (String) row[++index];
Expand Down Expand Up @@ -218,18 +220,22 @@ private String buildSampleDataCte() {
" STRING_AGG(DISTINCT CAST(s3.samplematerial AS text), ',' ORDER BY CAST(s3.samplematerial AS text)) as specimen_types_serology " +
" FROM filtered_cases c " +
" LEFT JOIN samples s ON s.associatedcase_id = c.id AND s.deleted = false " +
" LEFT JOIN (SELECT DISTINCT s_vir.id, s_vir.associatedcase_id, s_vir.samplematerial " +
" LEFT JOIN (SELECT DISTINCT s_vir.associatedcase_id, s_vir.samplematerial " +
" FROM samples s_vir " +
" JOIN pathogentest pt_vir ON pt_vir.sample_id = s_vir.id " +
" WHERE s_vir.deleted = false " +
" AND s_vir.samplematerial IS NOT NULL " +
" AND pt_vir.testtype IN ('PCR_RT_PCR', 'CULTURE', 'ISOLATION', 'DIRECT_FLUORESCENT_ANTIBODY', 'INDIRECT_FLUORESCENT_ANTIBODY')) s2 " +
" AND s_vir.associatedcase_id IN (SELECT id FROM filtered_cases)) s2 " +
" ON s2.associatedcase_id = c.id " +
" LEFT JOIN (SELECT DISTINCT s_sero.id, s_sero.associatedcase_id, s_sero.samplematerial " +
" LEFT JOIN (SELECT DISTINCT s_sero.associatedcase_id, s_sero.samplematerial " +
" FROM samples s_sero " +
" JOIN pathogentest pt_sero ON pt_sero.sample_id = s_sero.id " +
" LEFT JOIN pathogentest pt_sero ON pt_sero.sample_id = s_sero.id " +
" AND pt_sero.testtype IN ('IGG_SERUM_ANTIBODY', 'IGM_SERUM_ANTIBODY') " +
" WHERE s_sero.deleted = false " +
" AND pt_sero.testtype IN ('IGG_SERUM_ANTIBODY', 'IGM_SERUM_ANTIBODY', 'SEROLOGY')) s3 " +
" AND s_sero.samplematerial IS NOT NULL " +
" AND s_sero.associatedcase_id IN (SELECT id FROM filtered_cases) " +
" AND (pt_sero.id IS NOT NULL OR NOT EXISTS ( " +
" SELECT 1 FROM pathogentest pt_any WHERE pt_any.sample_id = s_sero.id " +
" ))) s3 " +
" ON s3.associatedcase_id = c.id " +
" GROUP BY c.id)";
//@formatter:on
Expand All @@ -238,29 +244,27 @@ private String buildSampleDataCte() {
private String buildVirusDetectionDataCte() {
//@formatter:off
return "virus_detection_data AS (SELECT c.id as case_id," +
" MIN(pt.testdatetime) as lab_result_date," +
" MIN(COALESCE(pt.testdatetime, pt.reportdate, pt.creationdate)) as lab_result_date," +
" (SELECT pt2.testresult " +
" FROM samples s2 " +
" JOIN pathogentest pt2 ON pt2.sample_id = s2.id " +
" WHERE s2.associatedcase_id = c.id " +
" AND s2.deleted = false " +
" AND pt2.testtype IN ('PCR_RT_PCR', 'CULTURE', 'ISOLATION', 'DIRECT_FLUORESCENT_ANTIBODY', 'INDIRECT_FLUORESCENT_ANTIBODY') " +
" AND pt2.testresultverified = true " +
" ORDER BY pt2.testdatetime ASC " +
" AND pt2.testtype IN ('PCR_RT_PCR', 'CULTURE', 'ISOLATION', 'DIRECT_FLUORESCENT_ANTIBODY', 'INDIRECT_FLUORESCENT_ANTIBODY', 'SEQUENCING', 'GENOTYPING') " +
" ORDER BY pt2.testresultverified DESC, COALESCE(pt2.testdatetime, pt2.reportdate, pt2.creationdate) ASC " +
" LIMIT 1) as virus_detection_result," +
" (SELECT COALESCE(pt3.typingid, pt3.genotyperesult) " +
" FROM samples s3 " +
" JOIN pathogentest pt3 ON pt3.sample_id = s3.id " +
" WHERE s3.associatedcase_id = c.id " +
" AND s3.deleted = false " +
" AND (pt3.typingid IS NOT NULL OR pt3.genotyperesult IS NOT NULL) " +
" ORDER BY pt3.testdatetime ASC " +
" ORDER BY COALESCE(pt3.testdatetime, pt3.reportdate, pt3.creationdate) ASC " +
" LIMIT 1) as genotype_raw " +
" FROM filtered_cases c " +
" LEFT JOIN samples s ON s.associatedcase_id = c.id AND s.deleted = false " +
" LEFT JOIN pathogentest pt ON pt.sample_id = s.id " +
" AND pt.testtype IN ('PCR_RT_PCR', 'CULTURE', 'ISOLATION', 'DIRECT_FLUORESCENT_ANTIBODY', 'INDIRECT_FLUORESCENT_ANTIBODY') " +
" AND pt.testresultverified = true " +
" AND pt.testtype IN ('PCR_RT_PCR', 'CULTURE', 'ISOLATION', 'DIRECT_FLUORESCENT_ANTIBODY', 'INDIRECT_FLUORESCENT_ANTIBODY', 'SEQUENCING', 'GENOTYPING') " +
" GROUP BY c.id)";
//@formatter:on
}
Expand All @@ -277,7 +281,7 @@ private String buildIggSerologyDataCte() {
" WHERE s_igg.associatedcase_id = c.id " +
" AND s_igg.deleted = false " +
" AND pt_igg.testtype = 'IGG_SERUM_ANTIBODY' " +
" ORDER BY pt_igg.testdatetime ASC " +
" ORDER BY COALESCE(pt_igg.testdatetime, pt_igg.reportdate, pt_igg.creationdate) ASC " +
" LIMIT 1) as igg_result " +
" FROM filtered_cases c)";
//@formatter:on
Expand All @@ -292,7 +296,7 @@ private String buildIgmSerologyDataCte() {
" WHERE s_igm.associatedcase_id = c.id " +
" AND s_igm.deleted = false " +
" AND pt_igm.testtype = 'IGM_SERUM_ANTIBODY' " +
" ORDER BY pt_igm.testdatetime ASC " +
" ORDER BY COALESCE(pt_igm.testdatetime, pt_igm.reportdate, pt_igm.creationdate) ASC " +
" LIMIT 1) as igm_result " +
" FROM filtered_cases c)";
//@formatter:on
Expand Down Expand Up @@ -337,6 +341,7 @@ private String buildComplicationsDataCte() {
" s.acuteencephalitis," +
" s.diarrhea," +
" s.otitismedia," +
" s.pneumoniaclinicalorradiologic," +
" s.othercomplications " +
" FROM filtered_cases c " +
" LEFT JOIN symptoms s ON c.symptoms_id = s.id)";
Expand Down Expand Up @@ -366,6 +371,7 @@ private String buildMeaslesSelectClause() {
.append(" comp.acuteencephalitis,")
.append(" comp.diarrhea,")
.append(" comp.otitismedia,")
.append(" comp.pneumoniaclinicalorradiologic,")
.append(" comp.othercomplications,")
.append(" c.clinicalconfirmation,")
.append(" el.infection_locations,")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ private String buildMeniSerogroupCte() {
" AND s.deleted = false " +
" AND pt.testtype IN ('SEROGROUPING', 'SLIDE_AGGLUTINATION') " +
" AND pt.typingid IS NOT NULL " +
" ORDER BY pt.testdatetime DESC " +
" ORDER BY COALESCE(pt.testdatetime, pt.reportdate, pt.creationdate) DESC NULLS LAST, pt.id DESC " +
" LIMIT 1) as serogroup " +
" FROM filtered_cases c" +
")";
Expand Down Expand Up @@ -419,7 +419,7 @@ private String buildMeniAstDataCte() {
" LEFT JOIN pathogentest pt ON pt.sample_id = s.id " +
" AND pt.testtype = 'ANTIBIOTIC_SUSCEPTIBILITY' " +
" LEFT JOIN drugsusceptibility ds ON pt.drugsusceptibility_id = ds.id " +
" ORDER BY c.id, pt.testdatetime DESC" +
" ORDER BY c.id, COALESCE(pt.testdatetime, pt.reportdate, pt.creationdate) DESC NULLS LAST, pt.id DESC" +
")";
//@formatter:on
}
Expand Down
Loading