From 7fba03abd6378b24f390fdb642e80c08c93972fd Mon Sep 17 00:00:00 2001 From: Markus Neidhart Date: Mon, 23 May 2022 18:21:20 +0200 Subject: [PATCH] Issue #82: Teildatensaetze werden beim Import unter Umstaenden falsch erkannt korrigiert, dass Teildatensaetze fuer Sparte Leben (versch. Wagnisarten) bei unguenstiger Sortierung falsch geparst werden. Passiert z.B. dann, wenn: 0220.010.2.1 0220.010.48.1 0220.010.2.2 geliefert wird. Grund ist, dass die ersten 7 Felder immer identisch sind (da die Wagnisart spaeter geliefert wird). Durch die alte Logik wurde aber der zweite Tds von Wagnisart 2 faelschlicherweise als zweiter Tds von Wagnisart 4/8 interpretiert. Neu wird zusaetzlich noch geprueft, ob es sich bei der naechsten Zeile um den gleichen Satztyp handelt. Falls nicht, wird mit der neuen Zeile ein neuer Datensatz importiert. Test ergaenzt, der das prueft. --- .../main/java/gdv/xport/satz/Datensatz.java | 23 ++++++++- .../test/java/gdv/xport/DatenpaketTest.java | 47 +++++++++++++++++++ .../testdatei_leben_mixed_teildatensaetze.txt | 20 ++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 lib/src/test/resources/testdatei_leben_mixed_teildatensaetze.txt diff --git a/lib/src/main/java/gdv/xport/satz/Datensatz.java b/lib/src/main/java/gdv/xport/satz/Datensatz.java index f87586bc..cdcebfff 100644 --- a/lib/src/main/java/gdv/xport/satz/Datensatz.java +++ b/lib/src/main/java/gdv/xport/satz/Datensatz.java @@ -558,7 +558,9 @@ protected boolean matchesNextTeildatensatz(final PushbackLineNumberReader reader for (int i = 30; i < 42; i++) { if (lastFeld1To7[i] != newLine[i]) return false; } - return matchesLastFeld(satznummer, reader); + if (!matchesLastFeld(satznummer, reader)) return false; + + return matchesNextSatztyp(reader); } } return false; @@ -571,6 +573,25 @@ private static boolean matchesLastFeld(Character satznummer, PushbackLineNumberR return !(Character.isDigit(newSatznummer) && Character.isDigit(satznummer) && newSatznummer <= satznummer); } + /** + * Prueft, ob die kommende Zeile noch den gleichen Satztyp hat wie der aktuelle Datensatz + * + * @param reader den Reader + * @return true, wenn der Satztyp uebereinstimmt + */ + private boolean matchesNextSatztyp(PushbackLineNumberReader reader) { + + try { + int satzart = Importer.of(reader).readSatzart(); + SatzTyp satztyp = Importer.of(reader).readSatzTyp(satzart); + return satztyp != null && satztyp.equals(getSatzTyp()); + } catch (IOException ex) { + LOG.info("No next satztyp found ({}).", ex.getLocalizedMessage()); + LOG.debug("Details:", ex); + return false; + } + } + /** * Read teildatensatz nummer. *

diff --git a/lib/src/test/java/gdv/xport/DatenpaketTest.java b/lib/src/test/java/gdv/xport/DatenpaketTest.java index 8060b14a..42952874 100644 --- a/lib/src/test/java/gdv/xport/DatenpaketTest.java +++ b/lib/src/test/java/gdv/xport/DatenpaketTest.java @@ -937,4 +937,51 @@ public void testConfigVorsatzNachsatz() { assertEquals(Config.STRICT, datenpaket.getNachsatz().getConfig()); } + /** + * Test fuer Issue #82. Problem ist, dass Teildatensaetze bei Leben in der falschen Reihenfolge (Wagnisarten) nicht + * korrekt auf die Saetze geparst werden. So wird z.B. ein Tds2 von Wagnisart 2 (der direkt auf einen Tds1 von + * Wagnisart 48 folgt), faelschlicherweise als Tds2 der Wagnisart 48 interpretiert. Hiermit wurde das + * Problem nachgestellt. + * + * @throws IOException Signals that an I/O exception has occurred. + */ + @Test + public void testImportLebenFromFileMixedTeildatensaetze() throws IOException { + File file = new File("src/test/resources", "testdatei_leben_mixed_teildatensaetze.txt"); + datenpaket.importFrom(file); + List violations = datenpaket.validate(); + LOG.info("violations = {}", violations); + + // test that every teildatensatz of all datensaetze has the correct satznummer (according to the identified + // teildatensatz) and the correct wagnisart + List> wrongDatensatzTeildatensatzList = new ArrayList<>(); + for (int i = 0; i < datenpaket.getDatensaetze().size(); i++) { + Datensatz datensatz = datenpaket.getDatensaetze().get(i); + for (int j = 0; j < datensatz.getTeildatensaetze().size(); j++) { + Teildatensatz teildatensatz = datensatz.getTeildatensaetze().get(j); + char satznummerOfTeildatensatz = teildatensatz.getSatznummer().toChar(); + String wagnisartOfTeildatensatz = datensatz.hasWagnisart() ? datensatz.getWagnisart() : ""; // nimm wagnisart vom Datensatz (erster Teildatensatz, soll fuer alle folgenden gleich sein) + if (teildatensatz.hasFeld(Bezeichner.SATZNUMMER) + && StringUtils.isNumeric(teildatensatz.getFeldInhalt(Bezeichner.SATZNUMMER)) + && !String.valueOf(satznummerOfTeildatensatz).equals(teildatensatz.getFeldInhalt(Bezeichner.SATZNUMMER))) { + wrongDatensatzTeildatensatzList.add(Pair.of(i, j)); + } + // leben: pruefe dass wagnisart fuer alle tds dieselbe ist + else if (wagnisartOfTeildatensatz != null + && wagnisartOfTeildatensatz.length() > 0 + && teildatensatz.hasFeld(Bezeichner.WAGNISART) + && StringUtils.isNumeric(teildatensatz.getFeldInhalt(Bezeichner.WAGNISART)) + && !wagnisartOfTeildatensatz.equals(teildatensatz.getFeldInhalt(Bezeichner.WAGNISART))) { + wrongDatensatzTeildatensatzList.add(Pair.of(i, j)); + } + } + } + + assertTrue("There are teildatensaetze with wrong satznummern: (datensatz, teildatensatz) -> " + wrongDatensatzTeildatensatzList, wrongDatensatzTeildatensatzList.isEmpty()); + + datenpaket.pack(); + + assertEquals("Size of datensaetze not as expected", 8, datenpaket.getDatensaetze().size()); + } + } diff --git a/lib/src/test/resources/testdatei_leben_mixed_teildatensaetze.txt b/lib/src/test/resources/testdatei_leben_mixed_teildatensaetze.txt new file mode 100644 index 00000000..d1c2c83f --- /dev/null +++ b/lib/src/test/resources/testdatei_leben_mixed_teildatensaetze.txt @@ -0,0 +1,20 @@ +000111110 2305202200000000 2.42.32.5 1.92.2 1.1 1 +000111110 2305202200000000 2 +000111110 2305202200000000 3 +010011110 010 12345600 Tester Hans 03081982 11 +010011110 010 12345600 0000002 +010011110 010 12345600 3 +010011110 010 12345600 4 +010011110 010 12345600 00000000 00000000 00000000 5 +020011110 010 12345600 000000000000000000000000 00000000 00000000 00000 000000000000 00000000000000 1 +020011110 010 12345600 000000000000000000 000000000000000000000 2 +021011110 010 00 00000000000000 0 00000 00000 00000000000000000000 00000000000000000000000000000000 00000000 1 +021011110 010 00 0000000000 000000 00000000 00000000000000000 2 +022011110 010 12345600 00001 0 Tester Juniorin 101120152000 000000000 000000000000000000 00000000 1 +022011110 010 12345600 00001 2 000000000000000000000000000 000000000000 00000000 00000 00000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000 00000 00000000 1 +022011110 010 12345600 00001 4 000000000000000000000000000 000000000000000000000000 00000 00000000000000000000000000000000000000 0000 000000000000000000000000000000000000000000000000000000000000000000000000000 1 +022011110 010 12345600 2 00000000000000000000000000000000000 00000000 00000000000000000000 000000000000000000000000000000000000 2 +022011110 010 12345600 4 00000000000000000000 000000000000000000000000000000000000 2 +022011110 010 12345600 2 00000 00000 6 +022011110 010 12345600 2 000000000 0000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000 8 +99990000000008 00000000000000000000000000000+00000000000000+00000000000000+00000000000000+ \ No newline at end of file