@@ -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