UNH-Nachrichtentyp in Testressourcen auf ASVREC umstellen
This commit is contained in:
@@ -27,6 +27,7 @@ import de.gecheckt.asv.validation.model.ValidationSeverity;
|
||||
* 9. Eine Nachricht muss mindestens ein UNH-Segment enthalten
|
||||
* 10. Eine Nachricht muss mindestens ein UNT-Segment enthalten
|
||||
* 11. UNH muss vor UNT stehen
|
||||
* 12. Der Nachrichtentyp in UNH/S009/0065 darf nur ASVREC oder ASVFEH sein
|
||||
*/
|
||||
public class DefaultStructureValidator implements StructureValidator {
|
||||
|
||||
@@ -95,28 +96,35 @@ public class DefaultStructureValidator implements StructureValidator {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Hole die UNH- und UNT-Segmente einmalig für alle Validierungen
|
||||
var unhSegment = message.getFirstSegment("UNH");
|
||||
var untSegment = message.getFirstSegment("UNT");
|
||||
|
||||
// Merke, ob grundlegende Strukturfehler vorliegen
|
||||
boolean hasBasicStructureErrors = false;
|
||||
|
||||
// Regel 9: Nachricht muss mindestens ein UNH-Segment enthalten
|
||||
validateUnhPresence(message, errors);
|
||||
validateUnhPresence(message, errors, unhSegment);
|
||||
|
||||
// Regel 10: Nachricht muss mindestens ein UNT-Segment enthalten
|
||||
validateUntPresence(message, errors);
|
||||
validateUntPresence(message, errors, untSegment);
|
||||
|
||||
// Prüfe, ob grundlegende Strukturfehler vorliegen
|
||||
if (unhSegment.isEmpty() || untSegment.isEmpty()) {
|
||||
hasBasicStructureErrors = true;
|
||||
}
|
||||
|
||||
// Führe weitere Validierungen nur durch, wenn beide Segmente vorhanden sind
|
||||
// und keine grundlegenden Strukturfehler vorliegen
|
||||
if (!hasBasicStructureErrors && unhSegment.isPresent() && untSegment.isPresent()) {
|
||||
// Regel 7: UNH- und UNT-Referenznummern müssen übereinstimmen
|
||||
// Nur prüfen, wenn beide Segmente vorhanden sind
|
||||
if (message.getFirstSegment("UNH").isPresent() && message.getFirstSegment("UNT").isPresent()) {
|
||||
validateUnhUntReferenceNumbers(message, errors);
|
||||
}
|
||||
|
||||
// Regel 8: UNT-Segmentanzahl muss mit tatsächlicher Segmentanzahl übereinstimmen
|
||||
// Nur prüfen, wenn UNT-Segment vorhanden ist
|
||||
if (message.getFirstSegment("UNT").isPresent()) {
|
||||
validateUntSegmentCount(message, errors);
|
||||
}
|
||||
validateUnhUntReferenceNumbers(message, errors, unhSegment.get(), untSegment.get());
|
||||
|
||||
// Regel 11: UNH muss vor UNT stehen
|
||||
// Nur prüfen, wenn beide Segmente vorhanden sind
|
||||
if (message.getFirstSegment("UNH").isPresent() && message.getFirstSegment("UNT").isPresent()) {
|
||||
validateUnhBeforeUnt(message, errors);
|
||||
validateUnhBeforeUnt(message, errors, unhSegment.get(), untSegment.get());
|
||||
|
||||
// Regel 8: UNT-Segmentanzahl muss mit tatsächlicher Segmentanzahl übereinstimmen
|
||||
validateUntSegmentCount(message, errors, untSegment.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,10 +134,10 @@ public class DefaultStructureValidator implements StructureValidator {
|
||||
*
|
||||
* @param message die zu validierende Nachricht
|
||||
* @param errors die Liste zum Hinzufügen von Validierungsfehlern
|
||||
* @param unhSegment das UNH-Segment der Nachricht (kann leer sein)
|
||||
*/
|
||||
private void validateUnhPresence(Message message, List<ValidationError> errors) {
|
||||
var unhSegment = message.getFirstSegment("UNH");
|
||||
|
||||
private void validateUnhPresence(Message message, List<ValidationError> errors,
|
||||
java.util.Optional<Segment> unhSegment) {
|
||||
// Wenn kein UNH-Segment vorhanden ist, Fehler hinzufügen
|
||||
if (unhSegment.isEmpty()) {
|
||||
errors.add(createError(
|
||||
@@ -144,6 +152,47 @@ public class DefaultStructureValidator implements StructureValidator {
|
||||
"UNH-Segment erforderlich"
|
||||
));
|
||||
}
|
||||
// Wenn UNH-Segment vorhanden ist, prüfe den Nachrichtentyp
|
||||
else {
|
||||
validateMessageType(unhSegment.get(), message.messagePosition(), errors);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validiert den Nachrichtentyp im UNH-Segment.
|
||||
*
|
||||
* @param unhSegment das UNH-Segment
|
||||
* @param messagePosition die Position der Nachricht
|
||||
* @param errors die Liste zum Hinzufügen von Validierungsfehlern
|
||||
*/
|
||||
private void validateMessageType(Segment unhSegment, int messagePosition, List<ValidationError> errors) {
|
||||
// Prüfe, ob das zweite Feld nach dem Segmentnamen vorhanden ist
|
||||
if (unhSegment.fields().size() >= 2) {
|
||||
var messageTypeField = unhSegment.fields().get(1); // S009 composite element
|
||||
var rawValue = messageTypeField.rawValue();
|
||||
|
||||
// Extrahiere den Nachrichtentyp vor dem ersten ':'
|
||||
String messageType = rawValue;
|
||||
int colonIndex = rawValue.indexOf(':');
|
||||
if (colonIndex > 0) {
|
||||
messageType = rawValue.substring(0, colonIndex);
|
||||
}
|
||||
|
||||
// Prüfe, ob der Nachrichtentyp gültig ist
|
||||
if (!"ASVREC".equals(messageType) && !"ASVFEH".equals(messageType)) {
|
||||
errors.add(createError(
|
||||
"STRUCTURE_012",
|
||||
"Ungültiger Nachrichtentyp in UNH/S009/0065: " + messageType,
|
||||
ValidationSeverity.ERROR,
|
||||
"UNH",
|
||||
messagePosition,
|
||||
"S009/0065",
|
||||
2,
|
||||
messageType,
|
||||
"Nachrichtentyp muss ASVREC oder ASVFEH sein"
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,10 +200,10 @@ public class DefaultStructureValidator implements StructureValidator {
|
||||
*
|
||||
* @param message die zu validierende Nachricht
|
||||
* @param errors die Liste zum Hinzufügen von Validierungsfehlern
|
||||
* @param untSegment das UNT-Segment der Nachricht (kann leer sein)
|
||||
*/
|
||||
private void validateUntPresence(Message message, List<ValidationError> errors) {
|
||||
var untSegment = message.getFirstSegment("UNT");
|
||||
|
||||
private void validateUntPresence(Message message, List<ValidationError> errors,
|
||||
java.util.Optional<Segment> untSegment) {
|
||||
// Wenn kein UNT-Segment vorhanden ist, Fehler hinzufügen
|
||||
if (untSegment.isEmpty()) {
|
||||
errors.add(createError(
|
||||
@@ -176,13 +225,10 @@ public class DefaultStructureValidator implements StructureValidator {
|
||||
*
|
||||
* @param message die zu validierende Nachricht
|
||||
* @param errors die Liste zum Hinzufügen von Validierungsfehlern
|
||||
* @param untSegment das UNT-Segment
|
||||
*/
|
||||
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();
|
||||
private void validateUntSegmentCount(Message message, List<ValidationError> errors, Segment untSegment) {
|
||||
var fields = untSegment.fields();
|
||||
|
||||
// Prüfen, ob das erste Feld (Segmentanzahl) vorhanden ist
|
||||
if (!fields.isEmpty()) {
|
||||
@@ -212,22 +258,19 @@ public class DefaultStructureValidator implements StructureValidator {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validiert, dass UNH vor UNT steht.
|
||||
*
|
||||
* @param message die zu validierende Nachricht
|
||||
* @param errors die Liste zum Hinzufügen von Validierungsfehlern
|
||||
* @param unhSegment das UNH-Segment
|
||||
* @param untSegment das UNT-Segment
|
||||
*/
|
||||
private void validateUnhBeforeUnt(Message message, List<ValidationError> errors) {
|
||||
var unhSegment = message.getFirstSegment("UNH");
|
||||
var untSegment = message.getFirstSegment("UNT");
|
||||
|
||||
// Prüft, ob beide Segmente vorhanden sind, bevor eine Validierung erfolgt
|
||||
if (unhSegment.isPresent() && untSegment.isPresent()) {
|
||||
int unhPosition = unhSegment.get().segmentPosition();
|
||||
int untPosition = untSegment.get().segmentPosition();
|
||||
private void validateUnhBeforeUnt(Message message, List<ValidationError> errors,
|
||||
Segment unhSegment, Segment untSegment) {
|
||||
int unhPosition = unhSegment.segmentPosition();
|
||||
int untPosition = untSegment.segmentPosition();
|
||||
|
||||
// UNH muss vor UNT stehen
|
||||
if (unhPosition > untPosition) {
|
||||
@@ -244,22 +287,19 @@ public class DefaultStructureValidator implements StructureValidator {
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validiert, dass die Referenznummern in UNH und UNT übereinstimmen.
|
||||
*
|
||||
* @param message die zu validierende Nachricht
|
||||
* @param errors die Liste zum Hinzufügen von Validierungsfehlern
|
||||
* @param unhSegment das UNH-Segment
|
||||
* @param untSegment das UNT-Segment
|
||||
*/
|
||||
private void validateUnhUntReferenceNumbers(Message message, List<ValidationError> errors) {
|
||||
var unhSegment = message.getFirstSegment("UNH");
|
||||
var untSegment = message.getFirstSegment("UNT");
|
||||
|
||||
// Prüft, ob beide Segmente vorhanden sind, bevor eine Validierung erfolgt
|
||||
if (unhSegment.isPresent() && untSegment.isPresent()) {
|
||||
var unhFields = unhSegment.get().fields();
|
||||
var untFields = untSegment.get().fields();
|
||||
private void validateUnhUntReferenceNumbers(Message message, List<ValidationError> errors,
|
||||
Segment unhSegment, Segment untSegment) {
|
||||
var unhFields = unhSegment.fields();
|
||||
var untFields = untSegment.fields();
|
||||
|
||||
// UNH-Referenznummer ist im 1. Feld (erstes Feld nach dem Segmentnamen)
|
||||
// UNT-Referenznummer ist im 2. Feld (zweites Feld nach dem Segmentnamen)
|
||||
@@ -289,7 +329,6 @@ public class DefaultStructureValidator implements StructureValidator {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validiert alle Segmente einer Nachricht.
|
||||
|
||||
@@ -75,7 +75,7 @@ class DefaultStructureValidatorTest {
|
||||
void validate_shouldReportErrorWhenSegmentHasDuplicatePositions() {
|
||||
// Manually create segments with duplicate positions to bypass parser validation
|
||||
// Also include required UNH and UNT segments
|
||||
Segment unh = new Segment("UNH", 1, List.of(new Field(1, "12345"), new Field(2, "ORDERS:D:03B:UN:EAN008")));
|
||||
Segment unh = new Segment("UNH", 1, List.of(new Field(1, "12345"), new Field(2, "ASVREC:D:03B:UN:EAN008")));
|
||||
Segment segment1 = new Segment("SEG1", 2);
|
||||
Segment segment2 = new Segment("SEG2", 2); // Duplicate position
|
||||
Segment unt = new Segment("UNT", 4, List.of(new Field(1, "4"), new Field(2, "12345")));
|
||||
@@ -100,7 +100,7 @@ class DefaultStructureValidatorTest {
|
||||
void validate_shouldReportErrorWhenFieldHasDuplicatePositions() {
|
||||
// Create segments with duplicate field positions manually to bypass parser validation
|
||||
// Also include required UNH and UNT segments
|
||||
Segment unh = new Segment("UNH", 1, List.of(new Field(1, "12345"), new Field(2, "ORDERS:D:03B:UN:EAN008")));
|
||||
Segment unh = new Segment("UNH", 1, List.of(new Field(1, "12345"), new Field(2, "ASVREC:D:03B:UN:EAN008")));
|
||||
Field field1 = new Field(1, "value1");
|
||||
Field field2 = new Field(1, "value2"); // Duplicate position
|
||||
Segment segment = new Segment("SEG1", 2, List.of(field1, field2));
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
package de.gecheckt.asv.validation.structure;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import de.gecheckt.asv.domain.model.Field;
|
||||
import de.gecheckt.asv.domain.model.InputFile;
|
||||
import de.gecheckt.asv.domain.model.Message;
|
||||
import de.gecheckt.asv.domain.model.Segment;
|
||||
import de.gecheckt.asv.parser.DefaultInputFileParser;
|
||||
import de.gecheckt.asv.parser.DefaultSegmentLineTokenizer;
|
||||
import de.gecheckt.asv.parser.InputFileParseException;
|
||||
import de.gecheckt.asv.parser.SegmentLineTokenizer;
|
||||
import de.gecheckt.asv.validation.model.ValidationError;
|
||||
import de.gecheckt.asv.validation.model.ValidationResult;
|
||||
|
||||
class DefaultStructureValidatorTestAdditional {
|
||||
|
||||
private DefaultStructureValidator validator;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
validator = new DefaultStructureValidator();
|
||||
}
|
||||
|
||||
@Test
|
||||
void validate_shouldNotReportErrorWhenMessageTypeIsASVREC() {
|
||||
// Given
|
||||
Segment unh = new Segment("UNH", 1, List.of(new Field(1, "12345"), new Field(2, "ASVREC:D:03B:UN:EAN008")));
|
||||
Segment unt = new Segment("UNT", 2, List.of(new Field(1, "2"), new Field(2, "12345")));
|
||||
Message message = new Message(1, List.of(unh, unt));
|
||||
InputFile inputFile = new InputFile("test.txt", List.of(message));
|
||||
|
||||
// When
|
||||
ValidationResult result = validator.validate(inputFile);
|
||||
|
||||
// Then
|
||||
// Should not have STRUCTURE_012 error for valid ASVREC message type
|
||||
assertFalse(result.getErrors().stream()
|
||||
.anyMatch(error -> "STRUCTURE_012".equals(error.errorCode())));
|
||||
assertFalse(result.hasErrors(), "There should be no validation errors for valid ASVREC message type");
|
||||
}
|
||||
|
||||
@Test
|
||||
void validate_shouldNotReportErrorWhenMessageTypeIsASVFEH() {
|
||||
// Given
|
||||
Segment unh = new Segment("UNH", 1, List.of(new Field(1, "12345"), new Field(2, "ASVFEH:D:03B:UN:EAN008")));
|
||||
Segment unt = new Segment("UNT", 2, List.of(new Field(1, "2"), new Field(2, "12345")));
|
||||
Message message = new Message(1, List.of(unh, unt));
|
||||
InputFile inputFile = new InputFile("test.txt", List.of(message));
|
||||
|
||||
// When
|
||||
ValidationResult result = validator.validate(inputFile);
|
||||
|
||||
// Then
|
||||
// Should not have STRUCTURE_012 error for valid ASVFEH message type
|
||||
assertFalse(result.getErrors().stream()
|
||||
.anyMatch(error -> "STRUCTURE_012".equals(error.errorCode())));
|
||||
assertFalse(result.hasErrors(), "There should be no validation errors for valid ASVFEH message type");
|
||||
}
|
||||
|
||||
@Test
|
||||
void validate_shouldReportErrorWhenMessageTypeIsInvalid() {
|
||||
// Given
|
||||
Segment unh = new Segment("UNH", 1, List.of(new Field(1, "12345"), new Field(2, "INVALID:D:03B:UN:EAN008")));
|
||||
Segment unt = new Segment("UNT", 2, List.of(new Field(1, "2"), new Field(2, "12345")));
|
||||
Message message = new Message(1, List.of(unh, unt));
|
||||
InputFile inputFile = new InputFile("test.txt", List.of(message));
|
||||
|
||||
// When
|
||||
ValidationResult result = validator.validate(inputFile);
|
||||
|
||||
// Then
|
||||
assertTrue(result.hasErrors());
|
||||
assertEquals(1, result.getErrors().size());
|
||||
|
||||
ValidationError error = result.getErrors().get(0);
|
||||
assertEquals("STRUCTURE_012", error.errorCode());
|
||||
assertEquals("Ungültiger Nachrichtentyp in UNH/S009/0065: INVALID", error.description());
|
||||
assertEquals("UNH", error.segmentName());
|
||||
assertEquals(1, error.segmentPosition());
|
||||
assertEquals("S009/0065", error.fieldName());
|
||||
assertEquals(2, error.fieldPosition());
|
||||
assertEquals("INVALID", error.actualValue());
|
||||
assertEquals("Nachrichtentyp muss ASVREC oder ASVFEH sein", error.expectedRule());
|
||||
}
|
||||
|
||||
@Test
|
||||
void validate_shouldNotReportAdditionalErrorWhenUnhIsMissing() throws IOException, InputFileParseException {
|
||||
// Given
|
||||
SegmentLineTokenizer tokenizer = new DefaultSegmentLineTokenizer();
|
||||
DefaultInputFileParser parser = new DefaultInputFileParser(tokenizer);
|
||||
String fileName = "no-unh.asv";
|
||||
Path filePath = Path.of("src/test/resources/no-unh.asv");
|
||||
String fileContent = Files.readString(filePath);
|
||||
|
||||
// When
|
||||
InputFile inputFile = parser.parse(fileName, fileContent);
|
||||
ValidationResult result = validator.validate(inputFile);
|
||||
|
||||
// Then
|
||||
// Should not have STRUCTURE_012 error for missing UNH
|
||||
assertFalse(result.getErrors().stream()
|
||||
.anyMatch(error -> "STRUCTURE_012".equals(error.errorCode())));
|
||||
// Should have exactly one error for missing UNH (STRUCTURE_009)
|
||||
assertEquals(1, result.getErrors().size(), "Should have exactly one error for missing UNH");
|
||||
assertEquals("STRUCTURE_009", result.getErrors().get(0).errorCode(), "Error should be STRUCTURE_009 for missing UNH");
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
UNH+12345+ORDERS:D:03B:UN:EAN008'
|
||||
SEG1+value1+value1'
|
||||
UNT+3+12345'
|
||||
@@ -1,4 +0,0 @@
|
||||
UNH+12345+ORDERS:D:03B:UN:EAN008'
|
||||
SEG1+value1+value2'
|
||||
SEG2+value3+value4'
|
||||
UNT+3+12345'
|
||||
@@ -1,4 +1,4 @@
|
||||
UNH+12345+ORDERS:D:03B:UN:EAN008'
|
||||
UNH+12345+ASVREC:D:03B:UN:EAN008'
|
||||
BGM+220+100001'
|
||||
DTM+137:20260325:102'
|
||||
NAD+BY+5000000000000:16++Customer Name'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
UNH+12345+ORDERS:D:03B:UN:EAN008'
|
||||
UNH+12345+ASVREC:D:03B:UN:EAN008'
|
||||
BGM+220+100001'
|
||||
DTM+137:20260325:102'
|
||||
NAD+BY+5000000000000:16++Customer Name'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
UNH+12345+ORDERS:D:03B:UN:EAN008'
|
||||
UNH+12345+ASVREC:D:03B:UN:EAN008'
|
||||
BGM+220+100001'
|
||||
DTM+137:20260325:102'
|
||||
NAD+BY+5000000000000:16++Customer Name'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
UNH+12345+ORDERS:D:03B:UN:EAN008'
|
||||
UNH+12345+ASVREC:D:03B:UN:EAN008'
|
||||
BGM+220+100001'
|
||||
DTM+137:20260325:102'
|
||||
NAD+BY+5000000000000:16++Customer Name'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
UNH+1+ORDERS:D:03B:UN:EAN008'
|
||||
UNH+1+ASVREC:D:03B:UN:EAN008'
|
||||
BGM+220+100001'
|
||||
DTM+137:20260325:102'
|
||||
NAD+BY+5000000000000:16++Customer Name'
|
||||
@@ -6,4 +6,4 @@ LIN+1++Product123:SA'
|
||||
QTY+21:10:PCE'
|
||||
UNS+S'
|
||||
CNT+2:1'
|
||||
UNT+8+1'
|
||||
UNT+9+1'
|
||||
@@ -1,4 +1,4 @@
|
||||
UNH+12345+ORDERS:D:03B:UN:EAN008'
|
||||
UNH+12345+ASVREC:D:03B:UN:EAN008'
|
||||
BGM+220+100001'
|
||||
DTM+137:20260325:102'
|
||||
NAD+BY+5000000000000:16++Customer Name'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
UNH+12345+ORDERS:D:03B:UN:EAN008'
|
||||
UNH+12345+ASVREC:D:03B:UN:EAN008'
|
||||
BGM+220+100001'
|
||||
DTM+137:20260325:102'
|
||||
NAD+BY+5000000000000:16++Customer Name'
|
||||
|
||||
@@ -6,4 +6,4 @@ LIN+1++Product123:SA'
|
||||
QTY+21:10:PCE'
|
||||
UNS+S'
|
||||
CNT+2:1'
|
||||
UNH+1+ORDERS:D:03B:UN:EAN008'
|
||||
UNH+1+ASVREC:D:03B:UN:EAN008'
|
||||
@@ -1,4 +1,4 @@
|
||||
UNH+12345+ORDERS:D:03B:UN:EAN008'
|
||||
UNH+12345+ASVREC:D:03B:UN:EAN008'
|
||||
BGM+220+100001'
|
||||
DTM+137:20260325:102'
|
||||
NAD+BY+5000000000000:16++Customer Name'
|
||||
|
||||
Reference in New Issue
Block a user