diff --git a/lib/src/main/java/gdv/xport/satz/Satz.java b/lib/src/main/java/gdv/xport/satz/Satz.java index b628c645..a4c35fd3 100644 --- a/lib/src/main/java/gdv/xport/satz/Satz.java +++ b/lib/src/main/java/gdv/xport/satz/Satz.java @@ -493,7 +493,7 @@ private void setSatzversion(final String version) { /** * Liefert die Satzversion - * + * * @return die Satzversion */ public final AlphaNumFeld getSatzversion() { @@ -613,12 +613,25 @@ public T getFeld(final Bezeichner bezeichner, final Class cl } private BetragMitVorzeichen getBetragMitVorzeichen(final Bezeichner bezeichner) { - Betrag betrag = getFeld(bezeichner, Betrag.class); - Feld vorzeichen = getVorzeichenOf(bezeichner); - BetragMitVorzeichen bmv = new BetragMitVorzeichen(Bezeichner.of(bezeichner.getName() + " mit Vorzeichen"), - betrag.getAnzahlBytes()+1, ByteAdresse.of(betrag.getByteAdresse())); - bmv.setInhalt(betrag.getInhalt() + vorzeichen.getInhalt()); - return bmv; + Betrag betrag = getFeld(bezeichner, Betrag.class); + + // Das Vorzeichenfeld darf leer sein (aber nur, wenn der Betrag dazu 0 ist!), in diesem Fall ersetzen wir es vor + // der Instanziierung von BetragMitVorzeichen durch ein "+", damit die weitere numerische Verarbeitung funktioniert. + Feld vorzeichen = getVorzeichenOf(bezeichner); + String vorzeichenInhalt = vorzeichen.getInhalt(); + if (StringUtils.isBlank(vorzeichenInhalt)) { + if (StringUtils.isNotBlank(betrag.getInhalt()) && !StringUtils.repeat('0', betrag.getAnzahlBytes()).equals(betrag.getInhalt())) { + throw new IllegalStateException("Vorzeichenfeld ist leer fuer " + bezeichner + ", aber Betrag ist nicht 0."); + } + vorzeichenInhalt = "+"; + } + + BetragMitVorzeichen bmv = new BetragMitVorzeichen( + Bezeichner.of(bezeichner.getName() + " mit Vorzeichen"), + betrag.getAnzahlBytes() + 1, ByteAdresse.of(betrag.getByteAdresse()) + ); + bmv.setInhalt(betrag.getInhalt() + vorzeichenInhalt); + return bmv; } private Feld getVorzeichenOf(final Bezeichner bezeichner) { @@ -928,7 +941,7 @@ public void export(final OutputStream ostream) throws IOException { public Satz importFrom(final String s) throws IOException { return importFrom(new PushbackLineNumberReader(new StringReader(s), 256)); } - + protected void removeUnusedTeildatensaetze(SortedSet usedIndexes) { Teildatensatz[] usedTeildatensaetze = new Teildatensatz[usedIndexes.size()]; int i = 0; @@ -1314,7 +1327,7 @@ private static boolean contains(Bezeichner bezeichner, List felder) { /** * Legt eine Kopie des Satzes an. - * + * * @return Kopie * @throws CloneNotSupportedException sollte nicht auftreten * @see Cloneable diff --git a/lib/src/test/java/gdv/xport/satz/SatzTest.java b/lib/src/test/java/gdv/xport/satz/SatzTest.java index cad08d8c..657ae0b9 100644 --- a/lib/src/test/java/gdv/xport/satz/SatzTest.java +++ b/lib/src/test/java/gdv/xport/satz/SatzTest.java @@ -215,6 +215,24 @@ public void testGetBetragMitVorzeichen() { assertEquals(new BigDecimal("-1.23"), betrag.toBigDecimal()); } + @Test + public void testGetBetragMitLeeremVorzeichen() { + Satz satz = SatzFactory.getSatz(SatzTyp.of(500)); + satz.setFeld(Bezeichner.SCHADENBEARBEITUNGSKOSTEN_IN_WAEHRUNGSEINHEITEN, "00000001234"); + satz.getTeildatensatz(1).setFeld(ByteAdresse.of(167), ""); + + // Leeres Vorzeichen, aber nicht leerer Betrag -> IllegalStateException + assertThrows(IllegalStateException.class, () -> satz.getFeld(Bezeichner.SCHADENBEARBEITUNGSKOSTEN_IN_WAEHRUNGSEINHEITEN, BetragMitVorzeichen.class)); + + // Leeres Vorzeichen und Betrag 0 -> Vorzeichen-Feld weiter leer, aber der Betrag mit Vorzeichen ist "+0" + satz.setFeld(Bezeichner.SCHADENBEARBEITUNGSKOSTEN_IN_WAEHRUNGSEINHEITEN, "00000000000"); + BetragMitVorzeichen betrag = satz.getFeld(Bezeichner.SCHADENBEARBEITUNGSKOSTEN_IN_WAEHRUNGSEINHEITEN, BetragMitVorzeichen.class); + assertEquals(14, betrag.getAnzahlBytes()); + assertEquals('+', betrag.getVorzeichen()); + assertEquals(" ", satz.getFeld(ByteAdresse.of(167)).getInhalt()); + assertEquals(0, betrag.toBigDecimal().compareTo(BigDecimal.ZERO)); + } + /** * Testfall fuer Issue #12. */