Kardinalität von FHL für ASVFEH auf maximal 99 begrenzen

This commit is contained in:
2026-03-27 07:39:34 +01:00
parent a804a19639
commit 32d50ec087
2 changed files with 129 additions and 0 deletions

View File

@@ -150,6 +150,9 @@ public class DefaultStructureValidator implements StructureValidator {
// Neue Regel: Für ASVFEH-Nachrichten muss mindestens ein FHL-Segment vorhanden sein
validateAsvfehRequiredFhlSegment(message, errors);
// Neue Regel: Für ASVFEH-Nachrichten darf FHL höchstens 99-mal vorkommen
validateAsvfehFhlCardinality(message, errors);
}
}
}
@@ -843,6 +846,44 @@ public class DefaultStructureValidator implements StructureValidator {
}
}
/**
* Validiert, dass für ASVFEH-Nachrichten das FHL-Segment höchstens 99-mal vorkommt.
* Diese Regel greift nur für ASVFEH-Nachrichten. Für ASVREC wird keine Prüfung durchgeführt.
* Wenn kein FHL vorhanden ist, wird hier kein Fehler erzeugt (die Präsenzregel STRUCTURE_025 deckt das ab).
*
* @param message die zu validierende Nachricht
* @param errors die Liste zum Hinzufügen von Validierungsfehlern
*/
private void validateAsvfehFhlCardinality(Message message, List<ValidationError> errors) {
var unhSegment = message.getFirstSegment("UNH");
if (unhSegment.isEmpty()) {
return;
}
String messageType = extractMessageType(unhSegment.get());
// Nur für ASVFEH-Nachrichten prüfen
if (!"ASVFEH".equals(messageType)) {
return;
}
// Anzahl der FHL-Segmente zählen
int fhlCount = message.getSegments("FHL").size();
// Nur bei mehr als 99 Vorkommen einen Fehler erzeugen
if (fhlCount > 99) {
errors.add(createError(
"STRUCTURE_027",
"ASVFEH-Nachricht darf FHL höchstens 99-mal enthalten",
ValidationSeverity.ERROR,
"FHL",
message.messagePosition(),
"",
0,
String.valueOf(fhlCount),
"FHL darf maximal 99-mal vorkommen"
));
}
}
/**
* Extrahiert den Nachrichtentyp aus dem UNH-Segment.
*

View File

@@ -2,6 +2,7 @@ package de.gecheckt.asv.validation.structure;
import static org.junit.jupiter.api.Assertions.*;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
@@ -111,4 +112,91 @@ class DefaultStructureValidatorAsvfehFhlSegmentTest {
.anyMatch(error -> "STRUCTURE_025".equals(error.errorCode())),
"STRUCTURE_025 Fehler sollte nicht auftreten für ASVREC");
}
@Test
void validate_shouldNotReportErrorForAsvfehWithOneFhl() {
// Given: ASVFEH mit genau 1 FHL
Segment unh = new Segment("UNH", 1, List.of(new Field(1, "12345"), new Field(2, "ASVFEH:D:03B:UN:EAN008")));
Segment fhl = new Segment("FHL", 2, List.of(new Field(1, "1")));
Segment unt = new Segment("UNT", 3, List.of(new Field(1, "3"), new Field(2, "12345")));
Message message = new Message(1, List.of(unh, fhl, unt));
InputFile inputFile = new InputFile("test.txt", List.of(message));
// When
ValidationResult result = validator.validate(inputFile);
// Then: Kein Fehler STRUCTURE_027
assertFalse(result.getErrors().stream()
.anyMatch(error -> "STRUCTURE_027".equals(error.errorCode())),
"STRUCTURE_027 sollte nicht auftreten bei 1 FHL");
}
@Test
void validate_shouldNotReportErrorForAsvfehWith99Fhl() {
// Given: ASVFEH mit genau 99 FHL
List<Segment> segments = new ArrayList<>();
segments.add(new Segment("UNH", 1, List.of(new Field(1, "12345"), new Field(2, "ASVFEH:D:03B:UN:EAN008"))));
for (int i = 0; i < 99; i++) {
segments.add(new Segment("FHL", i + 2, List.of(new Field(1, String.valueOf(i + 1)))));
}
segments.add(new Segment("UNT", 101, List.of(new Field(1, "101"), new Field(2, "12345"))));
Message message = new Message(1, segments);
InputFile inputFile = new InputFile("test.txt", List.of(message));
// When
ValidationResult result = validator.validate(inputFile);
// Then: Kein Fehler STRUCTURE_027
assertFalse(result.getErrors().stream()
.anyMatch(error -> "STRUCTURE_027".equals(error.errorCode())),
"STRUCTURE_027 sollte nicht auftreten bei 99 FHL");
}
@Test
void validate_shouldReportErrorForAsvfehWith100Fhl() {
// Given: ASVFEH mit genau 100 FHL
List<Segment> segments = new ArrayList<>();
segments.add(new Segment("UNH", 1, List.of(new Field(1, "12345"), new Field(2, "ASVFEH:D:03B:UN:EAN008"))));
for (int i = 0; i < 100; i++) {
segments.add(new Segment("FHL", i + 2, List.of(new Field(1, String.valueOf(i + 1)))));
}
segments.add(new Segment("UNT", 102, List.of(new Field(1, "102"), new Field(2, "12345"))));
Message message = new Message(1, segments);
InputFile inputFile = new InputFile("test.txt", List.of(message));
// When
ValidationResult result = validator.validate(inputFile);
// Then: Genau ein Fehler STRUCTURE_027
assertTrue(result.hasErrors(), "Es sollte einen Fehler geben");
assertEquals(1, result.getErrors().size(), "Es sollte genau einen Fehler geben");
ValidationError error = result.getErrors().get(0);
assertEquals("STRUCTURE_027", error.errorCode());
assertEquals("ASVFEH-Nachricht darf FHL höchstens 99-mal enthalten", error.description());
assertEquals("FHL", error.segmentName());
assertEquals(1, error.segmentPosition());
assertEquals("FHL darf maximal 99-mal vorkommen", error.expectedRule());
}
@Test
void validate_shouldNotReportErrorForAsvrecWith100Fhl() {
// Given: ASVREC mit 100 FHL (sollte keinen Fehler durch diese Regel erzeugen)
List<Segment> segments = new ArrayList<>();
segments.add(new Segment("UNH", 1, List.of(new Field(1, "12345"), new Field(2, "ASVREC:D:03B:UN:EAN008"))));
for (int i = 0; i < 100; i++) {
segments.add(new Segment("FHL", i + 2, List.of(new Field(1, String.valueOf(i + 1)))));
}
segments.add(new Segment("UNT", 102, List.of(new Field(1, "102"), new Field(2, "12345"))));
Message message = new Message(1, segments);
InputFile inputFile = new InputFile("test.txt", List.of(message));
// When
ValidationResult result = validator.validate(inputFile);
// Then: Kein Fehler STRUCTURE_027 (Regel gilt nur für ASVFEH)
assertFalse(result.getErrors().stream()
.anyMatch(error -> "STRUCTURE_027".equals(error.errorCode())),
"STRUCTURE_027 sollte nicht auftreten für ASVREC");
}
}