UNT-Segmentanzahl gegen tatsächliche Nachrichtenstruktur validieren
This commit is contained in:
@@ -23,6 +23,7 @@ import de.gecheckt.asv.validation.model.ValidationSeverity;
|
|||||||
* 5. Segmentpositionen innerhalb einer Nachricht müssen eindeutig und positiv sein
|
* 5. Segmentpositionen innerhalb einer Nachricht müssen eindeutig und positiv sein
|
||||||
* 6. Nachrichtenpositionen innerhalb einer Eingabedatei müssen eindeutig und positiv sein
|
* 6. Nachrichtenpositionen innerhalb einer Eingabedatei müssen eindeutig und positiv sein
|
||||||
* 7. UNH- und UNT-Referenznummern müssen innerhalb einer Nachricht übereinstimmen
|
* 7. UNH- und UNT-Referenznummern müssen innerhalb einer Nachricht übereinstimmen
|
||||||
|
* 8. Die im UNT angegebene Segmentanzahl muss der tatsächlichen Anzahl der Segmente entsprechen
|
||||||
*/
|
*/
|
||||||
public class DefaultStructureValidator implements StructureValidator {
|
public class DefaultStructureValidator implements StructureValidator {
|
||||||
|
|
||||||
@@ -87,6 +88,52 @@ public class DefaultStructureValidator implements StructureValidator {
|
|||||||
|
|
||||||
// Regel 7: UNH- und UNT-Referenznummern müssen übereinstimmen
|
// Regel 7: UNH- und UNT-Referenznummern müssen übereinstimmen
|
||||||
validateUnhUntReferenceNumbers(message, errors);
|
validateUnhUntReferenceNumbers(message, errors);
|
||||||
|
|
||||||
|
// Regel 8: UNT-Segmentanzahl muss mit tatsächlicher Segmentanzahl übereinstimmen
|
||||||
|
validateUntSegmentCount(message, errors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validiert, dass die im UNT angegebene Segmentanzahl der tatsächlichen Anzahl entspricht.
|
||||||
|
*
|
||||||
|
* @param message die zu validierende Nachricht
|
||||||
|
* @param errors die Liste zum Hinzufügen von Validierungsfehlern
|
||||||
|
*/
|
||||||
|
private void validateUntSegmentCount(Message message, List<ValidationError> errors) {
|
||||||
|
var untSegment = message.getFirstSegment("UNT");
|
||||||
|
|
||||||
|
// Nur prüfen, wenn UNT-Segment vorhanden ist
|
||||||
|
if (untSegment.isPresent()) {
|
||||||
|
var fields = untSegment.get().fields();
|
||||||
|
|
||||||
|
// Prüfen, ob das erste Feld (Segmentanzahl) vorhanden ist
|
||||||
|
if (!fields.isEmpty()) {
|
||||||
|
var countField = fields.get(0); // 0074 - Anzahl der Segmente
|
||||||
|
var countValue = countField.rawValue();
|
||||||
|
|
||||||
|
// Nur prüfen, wenn der Wert numerisch interpretiert werden kann
|
||||||
|
try {
|
||||||
|
int declaredCount = Integer.parseInt(countValue);
|
||||||
|
int actualCount = message.segments().size();
|
||||||
|
|
||||||
|
if (declaredCount != actualCount) {
|
||||||
|
errors.add(createError(
|
||||||
|
"STRUCTURE_008",
|
||||||
|
"Die im UNT angegebene Segmentanzahl entspricht nicht der tatsächlichen Anzahl",
|
||||||
|
ValidationSeverity.ERROR,
|
||||||
|
"UNT",
|
||||||
|
message.messagePosition(),
|
||||||
|
"0074",
|
||||||
|
1,
|
||||||
|
declaredCount + " != " + actualCount,
|
||||||
|
"Segmentanzahl in UNT muss mit tatsächlicher Anzahl übereinstimmen"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
// Nicht-numerischer Wert - keine zusätzliche Fehlermeldung gemäß Anforderung
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -211,4 +211,98 @@ class DefaultStructureValidatorTest {
|
|||||||
assertFalse(result.getErrors().stream()
|
assertFalse(result.getErrors().stream()
|
||||||
.anyMatch(error -> "STRUCTURE_007".equals(error.errorCode())));
|
.anyMatch(error -> "STRUCTURE_007".equals(error.errorCode())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validate_shouldReportErrorWhenUntSegmentCountDoesNotMatch() throws IOException, InputFileParseException {
|
||||||
|
// Given
|
||||||
|
SegmentLineTokenizer tokenizer = new DefaultSegmentLineTokenizer();
|
||||||
|
DefaultInputFileParser parser = new DefaultInputFileParser(tokenizer);
|
||||||
|
String fileName = "invalid-segment-count-too-small.asv";
|
||||||
|
Path filePath = Path.of("src/test/resources/invalid-segment-count-too-small.asv");
|
||||||
|
String fileContent = Files.readString(filePath);
|
||||||
|
|
||||||
|
// When
|
||||||
|
InputFile inputFile = parser.parse(fileName, fileContent);
|
||||||
|
ValidationResult result = validator.validate(inputFile);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
assertTrue(result.hasErrors());
|
||||||
|
assertEquals(1, result.getErrors().size());
|
||||||
|
|
||||||
|
ValidationError error = result.getErrors().get(0);
|
||||||
|
assertEquals("STRUCTURE_008", error.errorCode());
|
||||||
|
assertEquals("Die im UNT angegebene Segmentanzahl entspricht nicht der tatsächlichen Anzahl", error.description());
|
||||||
|
assertEquals("UNT", error.segmentName());
|
||||||
|
assertEquals(1, error.segmentPosition());
|
||||||
|
assertEquals("0074", error.fieldName());
|
||||||
|
assertEquals(1, error.fieldPosition());
|
||||||
|
assertEquals("8 != 9", error.actualValue());
|
||||||
|
assertEquals("Segmentanzahl in UNT muss mit tatsächlicher Anzahl übereinstimmen", error.expectedRule());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validate_shouldNotReportErrorWhenUntSegmentCountMatches() throws IOException, InputFileParseException {
|
||||||
|
// Given
|
||||||
|
SegmentLineTokenizer tokenizer = new DefaultSegmentLineTokenizer();
|
||||||
|
DefaultInputFileParser parser = new DefaultInputFileParser(tokenizer);
|
||||||
|
String fileName = "valid-segment-count.asv";
|
||||||
|
Path filePath = Path.of("src/test/resources/valid-segment-count.asv");
|
||||||
|
String fileContent = Files.readString(filePath);
|
||||||
|
|
||||||
|
// When
|
||||||
|
InputFile inputFile = parser.parse(fileName, fileContent);
|
||||||
|
ValidationResult result = validator.validate(inputFile);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
// Should not have STRUCTURE_008 error
|
||||||
|
assertFalse(result.getErrors().stream()
|
||||||
|
.anyMatch(error -> "STRUCTURE_008".equals(error.errorCode())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validate_shouldNotReportErrorWhenUntSegmentCountIsNonNumeric() throws IOException, InputFileParseException {
|
||||||
|
// Given
|
||||||
|
SegmentLineTokenizer tokenizer = new DefaultSegmentLineTokenizer();
|
||||||
|
DefaultInputFileParser parser = new DefaultInputFileParser(tokenizer);
|
||||||
|
String fileName = "invalid-segment-count-non-numeric.asv";
|
||||||
|
Path filePath = Path.of("src/test/resources/invalid-segment-count-non-numeric.asv");
|
||||||
|
String fileContent = Files.readString(filePath);
|
||||||
|
|
||||||
|
// When
|
||||||
|
InputFile inputFile = parser.parse(fileName, fileContent);
|
||||||
|
ValidationResult result = validator.validate(inputFile);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
// Should not have STRUCTURE_008 error (because count field is non-numeric)
|
||||||
|
assertFalse(result.getErrors().stream()
|
||||||
|
.anyMatch(error -> "STRUCTURE_008".equals(error.errorCode())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validate_shouldReportErrorWhenUntSegmentCountIsTooLarge() throws IOException, InputFileParseException {
|
||||||
|
// Given
|
||||||
|
SegmentLineTokenizer tokenizer = new DefaultSegmentLineTokenizer();
|
||||||
|
DefaultInputFileParser parser = new DefaultInputFileParser(tokenizer);
|
||||||
|
String fileName = "invalid-segment-count-too-large.asv";
|
||||||
|
Path filePath = Path.of("src/test/resources/invalid-segment-count-too-large.asv");
|
||||||
|
String fileContent = Files.readString(filePath);
|
||||||
|
|
||||||
|
// When
|
||||||
|
InputFile inputFile = parser.parse(fileName, fileContent);
|
||||||
|
ValidationResult result = validator.validate(inputFile);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
assertTrue(result.hasErrors());
|
||||||
|
assertEquals(1, result.getErrors().size());
|
||||||
|
|
||||||
|
ValidationError error = result.getErrors().get(0);
|
||||||
|
assertEquals("STRUCTURE_008", error.errorCode());
|
||||||
|
assertEquals("Die im UNT angegebene Segmentanzahl entspricht nicht der tatsächlichen Anzahl", error.description());
|
||||||
|
assertEquals("UNT", error.segmentName());
|
||||||
|
assertEquals(1, error.segmentPosition());
|
||||||
|
assertEquals("0074", error.fieldName());
|
||||||
|
assertEquals(1, error.fieldPosition());
|
||||||
|
assertEquals("10 != 9", error.actualValue());
|
||||||
|
assertEquals("Segmentanzahl in UNT muss mit tatsächlicher Anzahl übereinstimmen", error.expectedRule());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
9
src/test/resources/invalid-segment-count-non-numeric.asv
Normal file
9
src/test/resources/invalid-segment-count-non-numeric.asv
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
UNH+12345+ORDERS:D:03B:UN:EAN008'
|
||||||
|
BGM+220+100001'
|
||||||
|
DTM+137:20260325:102'
|
||||||
|
NAD+BY+5000000000000:16++Customer Name'
|
||||||
|
LIN+1++Product123:SA'
|
||||||
|
QTY+21:10:PCE'
|
||||||
|
UNS+S'
|
||||||
|
CNT+2:1'
|
||||||
|
UNT+abc+12345'
|
||||||
9
src/test/resources/invalid-segment-count-too-large.asv
Normal file
9
src/test/resources/invalid-segment-count-too-large.asv
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
UNH+12345+ORDERS:D:03B:UN:EAN008'
|
||||||
|
BGM+220+100001'
|
||||||
|
DTM+137:20260325:102'
|
||||||
|
NAD+BY+5000000000000:16++Customer Name'
|
||||||
|
LIN+1++Product123:SA'
|
||||||
|
QTY+21:10:PCE'
|
||||||
|
UNS+S'
|
||||||
|
CNT+2:1'
|
||||||
|
UNT+10+12345'
|
||||||
9
src/test/resources/invalid-segment-count-too-small.asv
Normal file
9
src/test/resources/invalid-segment-count-too-small.asv
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
UNH+12345+ORDERS:D:03B:UN:EAN008'
|
||||||
|
BGM+220+100001'
|
||||||
|
DTM+137:20260325:102'
|
||||||
|
NAD+BY+5000000000000:16++Customer Name'
|
||||||
|
LIN+1++Product123:SA'
|
||||||
|
QTY+21:10:PCE'
|
||||||
|
UNS+S'
|
||||||
|
CNT+2:1'
|
||||||
|
UNT+8+12345'
|
||||||
@@ -6,4 +6,4 @@ LIN+1++Product123:SA'
|
|||||||
QTY+21:10:PCE'
|
QTY+21:10:PCE'
|
||||||
UNS+S'
|
UNS+S'
|
||||||
CNT+2:1'
|
CNT+2:1'
|
||||||
UNT+6+54321'
|
UNT+9+54321'
|
||||||
9
src/test/resources/valid-segment-count.asv
Normal file
9
src/test/resources/valid-segment-count.asv
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
UNH+12345+ORDERS:D:03B:UN:EAN008'
|
||||||
|
BGM+220+100001'
|
||||||
|
DTM+137:20260325:102'
|
||||||
|
NAD+BY+5000000000000:16++Customer Name'
|
||||||
|
LIN+1++Product123:SA'
|
||||||
|
QTY+21:10:PCE'
|
||||||
|
UNS+S'
|
||||||
|
CNT+2:1'
|
||||||
|
UNT+9+12345'
|
||||||
Reference in New Issue
Block a user