FHL-Pflichtsegment für ASVFEH validieren
This commit is contained in:
@@ -34,6 +34,7 @@ import de.gecheckt.asv.validation.model.ValidationSeverity;
|
|||||||
* 16. Für ASVREC mit Rechnungskennzeichen "1" in REA dürfen DGN und LEA nicht vorhanden sein
|
* 16. Für ASVREC mit Rechnungskennzeichen "1" in REA dürfen DGN und LEA nicht vorhanden sein
|
||||||
* 17. Für ASVREC mit Rechnungskennzeichen "1" in REA muss der Rechnungsbetrag "0,00" sein
|
* 17. Für ASVREC mit Rechnungskennzeichen "1" in REA muss der Rechnungsbetrag "0,00" sein
|
||||||
* 18. Für ASVREC müssen IFA, REA und IVA jeweils genau einmal vorkommen
|
* 18. Für ASVREC müssen IFA, REA und IVA jeweils genau einmal vorkommen
|
||||||
|
* 19. Für ASVFEH-Nachrichten muss mindestens ein FHL-Segment vorhanden sein
|
||||||
*/
|
*/
|
||||||
public class DefaultStructureValidator implements StructureValidator {
|
public class DefaultStructureValidator implements StructureValidator {
|
||||||
|
|
||||||
@@ -146,6 +147,9 @@ public class DefaultStructureValidator implements StructureValidator {
|
|||||||
|
|
||||||
// Neue Regel: Für ASVREC müssen IFA, REA und IVA jeweils genau einmal vorkommen
|
// Neue Regel: Für ASVREC müssen IFA, REA und IVA jeweils genau einmal vorkommen
|
||||||
validateAsvrecSegmentCardinality(message, errors);
|
validateAsvrecSegmentCardinality(message, errors);
|
||||||
|
|
||||||
|
// Neue Regel: Für ASVFEH-Nachrichten muss mindestens ein FHL-Segment vorhanden sein
|
||||||
|
validateAsvfehRequiredFhlSegment(message, errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -529,7 +533,9 @@ public class DefaultStructureValidator implements StructureValidator {
|
|||||||
if (unhSegment.isEmpty()) {
|
if (unhSegment.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!"ASVREC".equals(extractMessageType(unhSegment.get()))) {
|
String messageType = extractMessageType(unhSegment.get());
|
||||||
|
// Nur für ASVREC-Nachrichten prüfen
|
||||||
|
if (!"ASVREC".equals(messageType)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -594,7 +600,9 @@ public class DefaultStructureValidator implements StructureValidator {
|
|||||||
if (unhSegment.isEmpty()) {
|
if (unhSegment.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!"ASVREC".equals(extractMessageType(unhSegment.get()))) {
|
String messageType = extractMessageType(unhSegment.get());
|
||||||
|
// Nur für ASVREC-Nachrichten prüfen
|
||||||
|
if (!"ASVREC".equals(messageType)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -689,7 +697,9 @@ public class DefaultStructureValidator implements StructureValidator {
|
|||||||
if (unhSegment.isEmpty()) {
|
if (unhSegment.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!"ASVREC".equals(extractMessageType(unhSegment.get()))) {
|
String messageType = extractMessageType(unhSegment.get());
|
||||||
|
// Nur für ASVREC-Nachrichten prüfen
|
||||||
|
if (!"ASVREC".equals(messageType)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -738,7 +748,9 @@ public class DefaultStructureValidator implements StructureValidator {
|
|||||||
if (unhSegment.isEmpty()) {
|
if (unhSegment.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!"ASVREC".equals(extractMessageType(unhSegment.get()))) {
|
String messageType = extractMessageType(unhSegment.get());
|
||||||
|
// Nur für ASVREC-Nachrichten prüfen
|
||||||
|
if (!"ASVREC".equals(messageType)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -787,6 +799,38 @@ public class DefaultStructureValidator implements StructureValidator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validiert, dass für ASVFEH-Nachrichten mindestens ein FHL-Segment vorhanden ist.
|
||||||
|
*
|
||||||
|
* @param message die zu validierende Nachricht
|
||||||
|
* @param errors die Liste zum Hinzufügen von Validierungsfehlern
|
||||||
|
*/
|
||||||
|
private void validateAsvfehRequiredFhlSegment(Message message, List<ValidationError> errors) {
|
||||||
|
// Prüfe den Nachrichtentyp aus dem UNH-Segment
|
||||||
|
var unhSegment = message.getFirstSegment("UNH");
|
||||||
|
if (unhSegment.isPresent()) {
|
||||||
|
String messageType = extractMessageType(unhSegment.get());
|
||||||
|
|
||||||
|
// Nur für ASVFEH-Nachrichten prüfen
|
||||||
|
if ("ASVFEH".equals(messageType)) {
|
||||||
|
// Prüfe, ob mindestens ein FHL-Segment vorhanden ist
|
||||||
|
if (message.getFirstSegment("FHL").isEmpty()) {
|
||||||
|
errors.add(createError(
|
||||||
|
"STRUCTURE_025",
|
||||||
|
"ASVFEH-Nachricht muss mindestens ein FHL-Segment enthalten",
|
||||||
|
ValidationSeverity.ERROR,
|
||||||
|
"",
|
||||||
|
message.messagePosition(),
|
||||||
|
"",
|
||||||
|
0,
|
||||||
|
"",
|
||||||
|
"FHL-Segment erforderlich für ASVFEH-Nachrichten"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extrahiert den Nachrichtentyp aus dem UNH-Segment.
|
* Extrahiert den Nachrichtentyp aus dem UNH-Segment.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
package de.gecheckt.asv.validation.structure;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
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.validation.model.ValidationError;
|
||||||
|
import de.gecheckt.asv.validation.model.ValidationResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testfälle für die Validierung der Mindestpräsenz des FHL-Segments in ASVFEH-Nachrichten.
|
||||||
|
*
|
||||||
|
* Testet spezifisch die neue Regel:
|
||||||
|
* Für ASVFEH-Nachrichten muss mindestens ein FHL-Segment vorhanden sein.
|
||||||
|
*/
|
||||||
|
class DefaultStructureValidatorAsvfehFhlSegmentTest {
|
||||||
|
|
||||||
|
private DefaultStructureValidator validator;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
validator = new DefaultStructureValidator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validate_shouldNotReportErrorForAsvfehWithOneFhlSegment() {
|
||||||
|
// Given: ASVFEH-Nachricht mit einem FHL-Segment
|
||||||
|
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_025
|
||||||
|
assertFalse(result.hasErrors(), "Es sollte keine Fehler geben");
|
||||||
|
assertTrue(result.getErrors().stream()
|
||||||
|
.noneMatch(error -> "STRUCTURE_025".equals(error.errorCode())),
|
||||||
|
"STRUCTURE_025 Fehler sollte nicht auftreten");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validate_shouldNotReportErrorForAsvfehWithMultipleFhlSegments() {
|
||||||
|
// Given: ASVFEH-Nachricht mit mehreren FHL-Segmenten
|
||||||
|
Segment unh = new Segment("UNH", 1, List.of(new Field(1, "12345"), new Field(2, "ASVFEH:D:03B:UN:EAN008")));
|
||||||
|
Segment fhl1 = new Segment("FHL", 2, List.of(new Field(1, "1")));
|
||||||
|
Segment fhl2 = new Segment("FHL", 3, List.of(new Field(1, "2")));
|
||||||
|
Segment unt = new Segment("UNT", 4, List.of(new Field(1, "4"), new Field(2, "12345")));
|
||||||
|
Message message = new Message(1, List.of(unh, fhl1, fhl2, unt));
|
||||||
|
InputFile inputFile = new InputFile("test.txt", List.of(message));
|
||||||
|
|
||||||
|
// When
|
||||||
|
ValidationResult result = validator.validate(inputFile);
|
||||||
|
|
||||||
|
// Then: Kein Fehler STRUCTURE_025
|
||||||
|
assertFalse(result.hasErrors(), "Es sollte keine Fehler geben");
|
||||||
|
assertTrue(result.getErrors().stream()
|
||||||
|
.noneMatch(error -> "STRUCTURE_025".equals(error.errorCode())),
|
||||||
|
"STRUCTURE_025 Fehler sollte nicht auftreten");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validate_shouldReportErrorForAsvfehWithoutFhlSegment() {
|
||||||
|
// Given: ASVFEH-Nachricht ohne FHL-Segment
|
||||||
|
Segment unh = new Segment("UNH", 1, List.of(new Field(1, "12345"), new Field(2, "ASVFEH:D:03B:UN:EAN008")));
|
||||||
|
Segment seg = new Segment("SEG", 2, List.of(new Field(1, "value")));
|
||||||
|
Segment unt = new Segment("UNT", 3, List.of(new Field(1, "3"), new Field(2, "12345")));
|
||||||
|
Message message = new Message(1, List.of(unh, seg, unt));
|
||||||
|
InputFile inputFile = new InputFile("test.txt", List.of(message));
|
||||||
|
|
||||||
|
// When
|
||||||
|
ValidationResult result = validator.validate(inputFile);
|
||||||
|
|
||||||
|
// Then: Genau ein Fehler STRUCTURE_025
|
||||||
|
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_025", error.errorCode());
|
||||||
|
assertEquals("ASVFEH-Nachricht muss mindestens ein FHL-Segment enthalten", error.description());
|
||||||
|
assertEquals("", error.segmentName());
|
||||||
|
assertEquals(1, error.segmentPosition());
|
||||||
|
assertEquals("FHL-Segment erforderlich für ASVFEH-Nachrichten", error.expectedRule());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validate_shouldNotReportErrorForAsvrecWithoutFhlSegment() {
|
||||||
|
// Given: ASVREC-Nachricht ohne FHL-Segment (sollte keinen Fehler erzeugen)
|
||||||
|
Segment unh = new Segment("UNH", 1, List.of(new Field(1, "12345"), new Field(2, "ASVREC:D:03B:UN:EAN008")));
|
||||||
|
Segment ifa = new Segment("IFA", 2);
|
||||||
|
Segment rea = new Segment("REA", 3);
|
||||||
|
Segment iva = new Segment("IVA", 4);
|
||||||
|
Segment unt = new Segment("UNT", 5, List.of(new Field(1, "5"), new Field(2, "12345")));
|
||||||
|
Message message = new Message(1, List.of(unh, ifa, rea, iva, unt));
|
||||||
|
InputFile inputFile = new InputFile("test.txt", List.of(message));
|
||||||
|
|
||||||
|
// When
|
||||||
|
ValidationResult result = validator.validate(inputFile);
|
||||||
|
|
||||||
|
// Then: Kein Fehler STRUCTURE_025
|
||||||
|
assertFalse(result.getErrors().stream()
|
||||||
|
.anyMatch(error -> "STRUCTURE_025".equals(error.errorCode())),
|
||||||
|
"STRUCTURE_025 Fehler sollte nicht auftreten für ASVREC");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -213,7 +213,7 @@ class DefaultStructureValidatorAsvrecRechnungskennzeichenTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void validate_asvfeh_keineRechnungskennzeichenRegel() {
|
void validate_asvfeh_keineRechnungskennzeichenRegel() {
|
||||||
// ASVFEH mit REA Kennzeichen "0" und ohne DGN/LEA -> kein STRUCTURE_017/018
|
// ASVFEH mit REA Kennzeichen "0", FHL und ohne DGN/LEA -> kein STRUCTURE_017/018
|
||||||
Segment unh = new Segment("UNH", 1,
|
Segment unh = new Segment("UNH", 1,
|
||||||
List.of(new Field(1, "12345"), new Field(2, "ASVFEH:D:03B:UN:EAN008")));
|
List.of(new Field(1, "12345"), new Field(2, "ASVFEH:D:03B:UN:EAN008")));
|
||||||
Segment rea = new Segment("REA", 2, List.of(
|
Segment rea = new Segment("REA", 2, List.of(
|
||||||
@@ -222,9 +222,10 @@ class DefaultStructureValidatorAsvrecRechnungskennzeichenTest {
|
|||||||
new Field(3, "RNR-001"),
|
new Field(3, "RNR-001"),
|
||||||
new Field(4, "0")
|
new Field(4, "0")
|
||||||
));
|
));
|
||||||
Segment unt = new Segment("UNT", 3,
|
Segment fhl = new Segment("FHL", 3, List.of(new Field(1, "1")));
|
||||||
List.of(new Field(1, "3"), new Field(2, "12345")));
|
Segment unt = new Segment("UNT", 4,
|
||||||
Message message = new Message(1, List.of(unh, rea, unt));
|
List.of(new Field(1, "4"), new Field(2, "12345")));
|
||||||
|
Message message = new Message(1, List.of(unh, rea, fhl, unt));
|
||||||
InputFile inputFile = new InputFile("test.txt", List.of(message));
|
InputFile inputFile = new InputFile("test.txt", List.of(message));
|
||||||
|
|
||||||
ValidationResult result = validator.validate(inputFile);
|
ValidationResult result = validator.validate(inputFile);
|
||||||
|
|||||||
@@ -259,10 +259,11 @@ class DefaultStructureValidatorAsvrecSegmentCardinalityTest {
|
|||||||
Segment rea2 = new Segment("REA", 5);
|
Segment rea2 = new Segment("REA", 5);
|
||||||
Segment iva1 = new Segment("IVA", 6);
|
Segment iva1 = new Segment("IVA", 6);
|
||||||
Segment iva2 = new Segment("IVA", 7);
|
Segment iva2 = new Segment("IVA", 7);
|
||||||
Segment unt = new Segment("UNT", 8,
|
Segment fhl = new Segment("FHL", 8, List.of(new Field(1, "1")));
|
||||||
List.of(new Field(1, "8"), new Field(2, "12345")));
|
Segment unt = new Segment("UNT", 9,
|
||||||
|
List.of(new Field(1, "9"), new Field(2, "12345")));
|
||||||
|
|
||||||
Message message = new Message(1, List.of(unh, ifa1, ifa2, rea1, rea2, iva1, iva2, unt));
|
Message message = new Message(1, List.of(unh, ifa1, ifa2, rea1, rea2, iva1, iva2, fhl, unt));
|
||||||
InputFile inputFile = new InputFile("test.txt", List.of(message));
|
InputFile inputFile = new InputFile("test.txt", List.of(message));
|
||||||
|
|
||||||
ValidationResult result = validator.validate(inputFile);
|
ValidationResult result = validator.validate(inputFile);
|
||||||
|
|||||||
@@ -131,15 +131,16 @@ class DefaultStructureValidatorAsvrecSegmentOrderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void validate_shouldNotReportOrderErrorForAsvfeh() {
|
void validate_shouldNotReportOrderErrorForAsvfeh() {
|
||||||
// ASVFEH mit umgekehrter Reihenfolge der Segmente -> kein STRUCTURE_016
|
// ASVFEH mit umgekehrter Reihenfolge der Segmente und FHL -> kein STRUCTURE_016
|
||||||
Segment unh = new Segment("UNH", 1,
|
Segment unh = new Segment("UNH", 1,
|
||||||
List.of(new Field(1, "12345"), new Field(2, "ASVFEH:D:03B:UN:EAN008")));
|
List.of(new Field(1, "12345"), new Field(2, "ASVFEH:D:03B:UN:EAN008")));
|
||||||
Segment iva = new Segment("IVA", 2);
|
Segment iva = new Segment("IVA", 2);
|
||||||
Segment rea = new Segment("REA", 3);
|
Segment rea = new Segment("REA", 3);
|
||||||
Segment ifa = new Segment("IFA", 4);
|
Segment ifa = new Segment("IFA", 4);
|
||||||
Segment unt = new Segment("UNT", 5,
|
Segment fhl = new Segment("FHL", 5, List.of(new Field(1, "1")));
|
||||||
List.of(new Field(1, "5"), new Field(2, "12345")));
|
Segment unt = new Segment("UNT", 6,
|
||||||
Message message = new Message(1, List.of(unh, iva, rea, ifa, unt));
|
List.of(new Field(1, "6"), new Field(2, "12345")));
|
||||||
|
Message message = new Message(1, List.of(unh, iva, rea, ifa, fhl, unt));
|
||||||
InputFile inputFile = new InputFile("test.txt", List.of(message));
|
InputFile inputFile = new InputFile("test.txt", List.of(message));
|
||||||
|
|
||||||
ValidationResult result = validator.validate(inputFile);
|
ValidationResult result = validator.validate(inputFile);
|
||||||
|
|||||||
@@ -168,10 +168,11 @@ class DefaultStructureValidatorAsvrecSegmentsTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void validate_shouldNotReportErrorForAsvfehWithoutIfaReaIvaSegments() {
|
void validate_shouldNotReportErrorForAsvfehWithoutIfaReaIvaSegments() {
|
||||||
// Given
|
// Given: ASVFEH mit FHL, aber ohne IFA/REA/IVA
|
||||||
Segment unh = new Segment("UNH", 1, List.of(new Field(1, "12345"), new Field(2, "ASVFEH:D:03B:UN:EAN008")));
|
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")));
|
Segment fhl = new Segment("FHL", 2, List.of(new Field(1, "1")));
|
||||||
Message message = new Message(1, List.of(unh, unt));
|
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));
|
InputFile inputFile = new InputFile("test.txt", List.of(message));
|
||||||
|
|
||||||
// When
|
// When
|
||||||
|
|||||||
Reference in New Issue
Block a user