Skip to content

Commit 9bc8641

Browse files
committed
#13773 - Add Epipulse export functionality for IMI disease
1 parent ffc95fe commit 9bc8641

15 files changed

+1646
-101
lines changed

sormas-api/src/main/java/de/symeda/sormas/api/epipulse/EpipulseDiseaseExportEntryDto.java

Lines changed: 318 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,34 @@ public class EpipulseDiseaseExportEntryDto {
166166
private Double micValueAST_PEN;
167167
private String sir_PEN;
168168

169+
// MENI-specific fields (Invasive Meningococcal Infection)
170+
// Serogroup (NEIMENI_A/B/C/W/X/Y/Z/29E/NGA/OTH)
171+
private String serogroup;
172+
// Isolate IDs (repeatable)
173+
private List<String> isolateIds;
174+
// Main pathogen detection methods (repeatable)
175+
private List<String> mainPathogenDetectionMethods;
176+
// Second pathogen detection methods (repeatable)
177+
private List<String> secondPathogenDetectionMethods;
178+
// MLST results (repeatable)
179+
private List<String> resultMlst;
180+
// PorA1 result
181+
private String resultPorA1;
182+
// PorA2 result
183+
private String resultPorA2;
184+
// FetA VR result
185+
private String resultFetVR;
186+
// ReportedEMERTII flag
187+
private Boolean reportedEmertii;
188+
// CIP (Ciprofloxacin) AST - MENI uses this instead of ERY
189+
private String micSign_CIP;
190+
private Double micValueAST_CIP;
191+
private String sir_CIP;
192+
// RIF (Rifampicin) AST - MENI-specific antibiotic
193+
private String micSign_RIF;
194+
private Double micValueAST_RIF;
195+
private String sir_RIF;
196+
169197
public String getReportingCountry() {
170198
return reportingCountry;
171199
}
@@ -515,6 +543,7 @@ public String getAgeMonthForCsv() {
515543
case PERT:
516544
case MEAS:
517545
case PNEU:
546+
case MENI:
518547
if (ageYears != null && ageYears < 2) {
519548
return ageMonths == null ? null : ageMonths.toString();
520549
}
@@ -536,6 +565,7 @@ public String getPlaceOfResidenceForCsv() {
536565
case PERT:
537566
case MEAS:
538567
case PNEU:
568+
case MENI:
539569
if (addressCommunityNutsCode != null && !addressCommunityNutsCode.isEmpty()) {
540570
return addressCommunityNutsCode;
541571
} else if (addressDistrictNutsCode != null && !addressDistrictNutsCode.isEmpty()) {
@@ -554,6 +584,7 @@ public String getPlaceOfNotificationForCsv() {
554584
case PERT:
555585
case MEAS:
556586
case PNEU:
587+
case MENI:
557588
if (responsibleCommunityNutsCode != null && !responsibleCommunityNutsCode.isEmpty()) {
558589
return responsibleCommunityNutsCode;
559590
} else if (responsibleDistrictNutsCode != null && !responsibleDistrictNutsCode.isEmpty()) {
@@ -635,23 +666,55 @@ public String getDateOfLastVaccinationForCsv() {
635666
public String getVaccinationStatusForCsv() {
636667

637668
if (immunizations.isEmpty()) {
669+
// Fallback: check if we have PCV/PPV dose counts from actual vaccination records (PNEU)
670+
int fallbackDoses = getFallbackDoseCount();
671+
if (fallbackDoses > 0) {
672+
return mapDoseCountToStatus(fallbackDoses);
673+
}
638674
return EpipulseVaccinationStatusRef.NOTVACC.getCode();
639675
}
640676

641677
int totalDoses = 0;
678+
boolean hasUnknownDoses = false;
642679
for (EpipulseImmunizationCheckDto immunizationCheckDto : immunizations) {
643680
if (immunizationCheckDto.getNumberOfDoses() == null) {
644-
return EpipulseVaccinationStatusRef.UNKDOSE.getCode();
681+
hasUnknownDoses = true;
645682
} else {
646683
totalDoses += immunizationCheckDto.getNumberOfDoses();
647684
}
648685
}
649686

687+
// If numberOfDoses is unknown but we have actual vaccination counts, use those
688+
if (hasUnknownDoses && totalDoses == 0) {
689+
int fallbackDoses = getFallbackDoseCount();
690+
if (fallbackDoses > 0) {
691+
return mapDoseCountToStatus(fallbackDoses);
692+
}
693+
return EpipulseVaccinationStatusRef.UNKDOSE.getCode();
694+
}
695+
696+
return mapDoseCountToStatus(totalDoses);
697+
}
698+
699+
private int getFallbackDoseCount() {
700+
int fallbackDoses = 0;
701+
if (pcvDoses != null) {
702+
fallbackDoses += pcvDoses;
703+
}
704+
if (ppvDoses != null) {
705+
fallbackDoses += ppvDoses;
706+
}
707+
return fallbackDoses;
708+
}
709+
710+
private String mapDoseCountToStatus(int totalDoses) {
650711
if (totalDoses > 10) {
651712
return EpipulseVaccinationStatusRef.TEN_DOSE.getCode();
652713
}
653714

654715
switch (totalDoses) {
716+
case 0:
717+
return EpipulseVaccinationStatusRef.NOTVACC.getCode();
655718
case 1:
656719
return EpipulseVaccinationStatusRef.ONE_DOSE.getCode();
657720
case 2:
@@ -670,9 +733,11 @@ public String getVaccinationStatusForCsv() {
670733
return EpipulseVaccinationStatusRef.EIGHT_DOSE.getCode();
671734
case 9:
672735
return EpipulseVaccinationStatusRef.NINE_DOSE.getCode();
736+
case 10:
737+
return EpipulseVaccinationStatusRef.TEN_DOSE.getCode();
738+
default:
739+
return null;
673740
}
674-
675-
return null;
676741
}
677742

678743
public String getVaccinationStatusMaternalForCsv() {
@@ -1347,6 +1412,254 @@ public String getSir_PENForCsv() {
13471412
return sir_PEN != null ? sir_PEN : "";
13481413
}
13491414

1415+
// MENI-specific getters and setters
1416+
public String getSerogroup() {
1417+
return serogroup;
1418+
}
1419+
1420+
public void setSerogroup(String serogroup) {
1421+
this.serogroup = serogroup;
1422+
}
1423+
1424+
public List<String> getIsolateIds() {
1425+
return isolateIds;
1426+
}
1427+
1428+
public void setIsolateIds(List<String> isolateIds) {
1429+
this.isolateIds = isolateIds;
1430+
}
1431+
1432+
public List<String> getMainPathogenDetectionMethods() {
1433+
return mainPathogenDetectionMethods;
1434+
}
1435+
1436+
public void setMainPathogenDetectionMethods(List<String> mainPathogenDetectionMethods) {
1437+
this.mainPathogenDetectionMethods = mainPathogenDetectionMethods;
1438+
}
1439+
1440+
public List<String> getSecondPathogenDetectionMethods() {
1441+
return secondPathogenDetectionMethods;
1442+
}
1443+
1444+
public void setSecondPathogenDetectionMethods(List<String> secondPathogenDetectionMethods) {
1445+
this.secondPathogenDetectionMethods = secondPathogenDetectionMethods;
1446+
}
1447+
1448+
public List<String> getResultMlst() {
1449+
return resultMlst;
1450+
}
1451+
1452+
public void setResultMlst(List<String> resultMlst) {
1453+
this.resultMlst = resultMlst;
1454+
}
1455+
1456+
public String getResultPorA1() {
1457+
return resultPorA1;
1458+
}
1459+
1460+
public void setResultPorA1(String resultPorA1) {
1461+
this.resultPorA1 = resultPorA1;
1462+
}
1463+
1464+
public String getResultPorA2() {
1465+
return resultPorA2;
1466+
}
1467+
1468+
public void setResultPorA2(String resultPorA2) {
1469+
this.resultPorA2 = resultPorA2;
1470+
}
1471+
1472+
public String getResultFetVR() {
1473+
return resultFetVR;
1474+
}
1475+
1476+
public void setResultFetVR(String resultFetVR) {
1477+
this.resultFetVR = resultFetVR;
1478+
}
1479+
1480+
public Boolean getReportedEmertii() {
1481+
return reportedEmertii;
1482+
}
1483+
1484+
public void setReportedEmertii(Boolean reportedEmertii) {
1485+
this.reportedEmertii = reportedEmertii;
1486+
}
1487+
1488+
public String getMicSign_CIP() {
1489+
return micSign_CIP;
1490+
}
1491+
1492+
public void setMicSign_CIP(String micSign_CIP) {
1493+
this.micSign_CIP = micSign_CIP;
1494+
}
1495+
1496+
public Double getMicValueAST_CIP() {
1497+
return micValueAST_CIP;
1498+
}
1499+
1500+
public void setMicValueAST_CIP(Double micValueAST_CIP) {
1501+
this.micValueAST_CIP = micValueAST_CIP;
1502+
}
1503+
1504+
public String getSir_CIP() {
1505+
return sir_CIP;
1506+
}
1507+
1508+
public void setSir_CIP(String sir_CIP) {
1509+
this.sir_CIP = sir_CIP;
1510+
}
1511+
1512+
public String getMicSign_RIF() {
1513+
return micSign_RIF;
1514+
}
1515+
1516+
public void setMicSign_RIF(String micSign_RIF) {
1517+
this.micSign_RIF = micSign_RIF;
1518+
}
1519+
1520+
public Double getMicValueAST_RIF() {
1521+
return micValueAST_RIF;
1522+
}
1523+
1524+
public void setMicValueAST_RIF(Double micValueAST_RIF) {
1525+
this.micValueAST_RIF = micValueAST_RIF;
1526+
}
1527+
1528+
public String getSir_RIF() {
1529+
return sir_RIF;
1530+
}
1531+
1532+
public void setSir_RIF(String sir_RIF) {
1533+
this.sir_RIF = sir_RIF;
1534+
}
1535+
1536+
// MENI-specific CSV getter methods
1537+
public String getSerogroupForCsv() {
1538+
return serogroup != null ? serogroup : "";
1539+
}
1540+
1541+
public List<String> getIsolateIdsForCsv(int maxCount) {
1542+
List<String> ids = new ArrayList<>();
1543+
for (int i = 0; i < maxCount; i++) {
1544+
if (isolateIds != null && i < isolateIds.size()) {
1545+
ids.add(isolateIds.get(i));
1546+
} else {
1547+
ids.add("");
1548+
}
1549+
}
1550+
return ids;
1551+
}
1552+
1553+
public List<String> getMainPathogenDetectionMethodsForCsv(int maxCount) {
1554+
List<String> methods = new ArrayList<>();
1555+
for (int i = 0; i < maxCount; i++) {
1556+
if (mainPathogenDetectionMethods != null && i < mainPathogenDetectionMethods.size()) {
1557+
methods.add(mainPathogenDetectionMethods.get(i));
1558+
} else {
1559+
methods.add("");
1560+
}
1561+
}
1562+
return methods;
1563+
}
1564+
1565+
public List<String> getSecondPathogenDetectionMethodsForCsv(int maxCount) {
1566+
List<String> methods = new ArrayList<>();
1567+
for (int i = 0; i < maxCount; i++) {
1568+
if (secondPathogenDetectionMethods != null && i < secondPathogenDetectionMethods.size()) {
1569+
methods.add(secondPathogenDetectionMethods.get(i));
1570+
} else {
1571+
methods.add("");
1572+
}
1573+
}
1574+
return methods;
1575+
}
1576+
1577+
public List<String> getResultMlstForCsv(int maxCount) {
1578+
List<String> results = new ArrayList<>();
1579+
for (int i = 0; i < maxCount; i++) {
1580+
if (resultMlst != null && i < resultMlst.size()) {
1581+
results.add(resultMlst.get(i));
1582+
} else {
1583+
results.add("");
1584+
}
1585+
}
1586+
return results;
1587+
}
1588+
1589+
public String getResultPorA1ForCsv() {
1590+
return resultPorA1 != null ? resultPorA1 : "";
1591+
}
1592+
1593+
public String getResultPorA2ForCsv() {
1594+
return resultPorA2 != null ? resultPorA2 : "";
1595+
}
1596+
1597+
public String getResultFetVRForCsv() {
1598+
return resultFetVR != null ? resultFetVR : "";
1599+
}
1600+
1601+
public String getReportedEmertiiForCsv() {
1602+
return reportedEmertii != null ? String.valueOf(reportedEmertii) : "";
1603+
}
1604+
1605+
public String getMicSign_CIPForCsv() {
1606+
return micSign_CIP != null ? micSign_CIP : "";
1607+
}
1608+
1609+
public String getMicValueAST_CIPForCsv() {
1610+
return micValueAST_CIP != null ? String.valueOf(micValueAST_CIP) : "";
1611+
}
1612+
1613+
public String getSir_CIPForCsv() {
1614+
return sir_CIP != null ? sir_CIP : "";
1615+
}
1616+
1617+
public String getMicSign_RIFForCsv() {
1618+
return micSign_RIF != null ? micSign_RIF : "";
1619+
}
1620+
1621+
public String getMicValueAST_RIFForCsv() {
1622+
return micValueAST_RIF != null ? String.valueOf(micValueAST_RIF) : "";
1623+
}
1624+
1625+
public String getSir_RIFForCsv() {
1626+
return sir_RIF != null ? sir_RIF : "";
1627+
}
1628+
1629+
/**
1630+
* Gets vaccination status for MENI (max 4 doses instead of 10).
1631+
* MENI uses 1DOSE through 4DOSE instead of the standard 10DOSE max.
1632+
*/
1633+
public String getVaccinationStatusMeniForCsv() {
1634+
if (immunizations == null || immunizations.isEmpty()) {
1635+
return EpipulseVaccinationStatusRef.NOTVACC.getCode();
1636+
}
1637+
1638+
int totalDoses = 0;
1639+
for (EpipulseImmunizationCheckDto immunizationCheckDto : immunizations) {
1640+
if (immunizationCheckDto.getNumberOfDoses() == null) {
1641+
return EpipulseVaccinationStatusRef.UNKDOSE.getCode();
1642+
} else {
1643+
totalDoses += immunizationCheckDto.getNumberOfDoses();
1644+
}
1645+
}
1646+
1647+
if (totalDoses >= 4) {
1648+
return EpipulseVaccinationStatusRef.FOUR_DOSE.getCode();
1649+
}
1650+
1651+
switch (totalDoses) {
1652+
case 1:
1653+
return EpipulseVaccinationStatusRef.ONE_DOSE.getCode();
1654+
case 2:
1655+
return EpipulseVaccinationStatusRef.TWO_DOSE.getCode();
1656+
case 3:
1657+
return EpipulseVaccinationStatusRef.THREE_DOSE.getCode();
1658+
}
1659+
1660+
return EpipulseVaccinationStatusRef.NOTVACC.getCode();
1661+
}
1662+
13501663
public void calculateAge() {
13511664
if (symptomOnsetDate == null || yearOfBirth == null || monthOfBirth == null || dayOfBirth == null) {
13521665
return;
@@ -1505,7 +1818,8 @@ public List<EpipulseImmunizationCheckDto> parseImmunizationChecks(String dbPrevi
15051818
List<EpipulseImmunizationCheckDto> immunizations = new ArrayList<>();
15061819
EpipulseImmunizationCheckDto dto = null;
15071820
for (String immunizationStr : allImmunizationArr) {
1508-
String[] immunizationArr = immunizationStr.split(RECORD_SPLIT_CHARACTER);
1821+
// Use -1 limit to preserve trailing empty strings (e.g., when numberOfDoses is null)
1822+
String[] immunizationArr = immunizationStr.split(RECORD_SPLIT_CHARACTER, -1);
15091823
if (immunizationArr.length < 4) {
15101824
continue;
15111825
}

0 commit comments

Comments
 (0)