From b87b2995c85a719344f16970642ba29b2ef357a7 Mon Sep 17 00:00:00 2001 From: Philip Helger Date: Fri, 3 Jan 2025 16:51:24 +0100 Subject: [PATCH] Added ZF 2.0.1 validation and fixed examples --- README.md | 2 + .../phive/zugferd/ZugferdValidation.java | 72 +++++++++++++++++++ .../ValidationExecutionManagerFuncTest.java | 2 +- .../helger/phive/zugferd/mock/CTestFiles.java | 44 ++++++++++-- .../2.0.1/en16931/zugferd-invoice-1.xml | 2 + .../2.0.1/en16931/zugferd-invoice-15.xml | 2 + .../2.0.1/en16931/zugferd-invoice-17.xml | 2 + .../2.0.1/extended/zugferd-invoice-4.xml | 6 +- .../2.0.1/extended/zugferd-invoice-5.xml | 18 +++-- .../2.0.1/minimum/zugferd-invoice-1.xml | 24 ++++++- 10 files changed, 157 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index fa644fdb..9cf6201b 100644 --- a/README.md +++ b/README.md @@ -202,6 +202,8 @@ I hope that with the introduction of PINT, the versioning problem will be solved * v3.2.3 - work in progress * Fixed Factur-X VES display name to include the profile name as well + * Added support for ZuGFERD 2.0.1 - all profiles (XML only) + * Added support for ZuGFERD 2.1 - all profiles (XML only) * v3.2.2 - 2024-12-05 * Updated to XRechnung 3.0.2 Schematron Rules 2.2.0 * Added Peppol November 2024 release (Billing 3.0.18 and Upgrade 3.0.14) diff --git a/phive-rules-zugferd/src/main/java/com/helger/phive/zugferd/ZugferdValidation.java b/phive-rules-zugferd/src/main/java/com/helger/phive/zugferd/ZugferdValidation.java index e0e777fc..d79646b7 100644 --- a/phive-rules-zugferd/src/main/java/com/helger/phive/zugferd/ZugferdValidation.java +++ b/phive-rules-zugferd/src/main/java/com/helger/phive/zugferd/ZugferdValidation.java @@ -47,6 +47,23 @@ public final class ZugferdValidation public static final String GROUP_ID_ZUGFERD = "de.zugferd"; public static final String GROUP_ID_FACTUR_X = "fr.factur-x"; + // v2.0.1 + public static final DVRCoordinate VID_ZUGFERD_2_0_1_MINIMUM = PhiveRulesHelper.createCoordinate (GROUP_ID_ZUGFERD, + EZugferdProfile.MINIMUM.getArtifactID (), + "2.0.1"); + public static final DVRCoordinate VID_ZUGFERD_2_0_1_BASIC_WL = PhiveRulesHelper.createCoordinate (GROUP_ID_ZUGFERD, + EZugferdProfile.BASIC_WL.getArtifactID (), + "2.0.1"); + public static final DVRCoordinate VID_ZUGFERD_2_0_1_BASIC = PhiveRulesHelper.createCoordinate (GROUP_ID_ZUGFERD, + EZugferdProfile.BASIC.getArtifactID (), + "2.0.1"); + public static final DVRCoordinate VID_ZUGFERD_2_0_1_EN16931 = PhiveRulesHelper.createCoordinate (GROUP_ID_ZUGFERD, + EZugferdProfile.EN16931.getArtifactID (), + "2.0.1"); + public static final DVRCoordinate VID_ZUGFERD_2_0_1_EXTENDED = PhiveRulesHelper.createCoordinate (GROUP_ID_ZUGFERD, + EZugferdProfile.EXTENDED.getArtifactID (), + "2.0.1"); + // v2.1 public static final DVRCoordinate VID_ZUGFERD_2_1_MINIMUM = PhiveRulesHelper.createCoordinate (GROUP_ID_ZUGFERD, EZugferdProfile.MINIMUM.getArtifactID (), @@ -102,6 +119,7 @@ public final class ZugferdValidation private static final ICommonsMap ZUGFERD_TO_FACTURX_MAP = new CommonsHashMap <> (); static { + ZUGFERD_TO_FACTURX_MAP.put (DVRVersion.parseOrNull ("2.0.1"), DVRVersion.parseOrNull ("1.0.3")); ZUGFERD_TO_FACTURX_MAP.put (DVRVersion.parseOrNull ("2.1"), DVRVersion.parseOrNull ("1.0.5")); ZUGFERD_TO_FACTURX_MAP.put (DVRVersion.parseOrNull ("2.2"), DVRVersion.parseOrNull ("1.0.6")); ZUGFERD_TO_FACTURX_MAP.put (DVRVersion.parseOrNull ("2.3.2"), DVRVersion.parseOrNull ("1.0.7-2")); @@ -156,6 +174,60 @@ public static void initZugferd (@Nonnull final IValidationExecutorSetRegistry aVES; + aVES = ValidationExecutorSet.create (aVESID, + sDisplayName, + aStatus, + ValidationExecutorXSD.create (new ClassPathResource ("/external/schemas/" + + sZugferdVersion + + "/" + + sProfileNamePart + + "/zugferd2p0_" + + sProfileNamePart + + ".xsd", + _getCL ())), + aVESchematron); + aRegistry.registerValidationExecutorSet (aVES); + + // Also register alias as Factur-X + _registerFacturXAlias (aRegistry, eProfile, aVES); + } + // Zugferd 2.1 / Factur-X 1.0.5 for (final EZugferdProfile eProfile : EZugferdProfile.values ()) { diff --git a/phive-rules-zugferd/src/test/java/com/helger/phive/zugferd/ValidationExecutionManagerFuncTest.java b/phive-rules-zugferd/src/test/java/com/helger/phive/zugferd/ValidationExecutionManagerFuncTest.java index cb4a57a0..f2d0d204 100644 --- a/phive-rules-zugferd/src/test/java/com/helger/phive/zugferd/ValidationExecutionManagerFuncTest.java +++ b/phive-rules-zugferd/src/test/java/com/helger/phive/zugferd/ValidationExecutionManagerFuncTest.java @@ -49,7 +49,7 @@ public void testApplyCompleteValidation () for (final PhiveTestFile aTestFile : CTestFiles.getAllTestFiles ()) { final IValidationExecutorSet aExecutors = CTestFiles.VES_REGISTRY.getOfID (aTestFile.getVESID ()); - assertNotNull (aExecutors); + assertNotNull ("Failed to resolve VESID '" + aTestFile.getVESID () + "'", aExecutors); LOGGER.info ("Validating " + aTestFile.getResource ().getPath () + diff --git a/phive-rules-zugferd/src/test/java/com/helger/phive/zugferd/mock/CTestFiles.java b/phive-rules-zugferd/src/test/java/com/helger/phive/zugferd/mock/CTestFiles.java index bd5b0680..c62da286 100644 --- a/phive-rules-zugferd/src/test/java/com/helger/phive/zugferd/mock/CTestFiles.java +++ b/phive-rules-zugferd/src/test/java/com/helger/phive/zugferd/mock/CTestFiles.java @@ -55,7 +55,14 @@ private CTestFiles () public static ICommonsList getAllTestFiles () { final ICommonsList ret = new CommonsArrayList <> (); - for (final DVRCoordinate aVESID : new DVRCoordinate [] { // 2.1 + for (final DVRCoordinate aVESID : new DVRCoordinate [] { // 2.0.1 + ZugferdValidation.VID_ZUGFERD_2_0_1_MINIMUM, + ZugferdValidation.VID_ZUGFERD_2_0_1_BASIC_WL, + ZugferdValidation.VID_ZUGFERD_2_0_1_BASIC, + ZugferdValidation.VID_ZUGFERD_2_0_1_EN16931, + ZugferdValidation.VID_ZUGFERD_2_0_1_EXTENDED, + + // 2.1 ZugferdValidation.VID_ZUGFERD_2_1_MINIMUM, ZugferdValidation.VID_ZUGFERD_2_1_BASIC_WL, ZugferdValidation.VID_ZUGFERD_2_1_BASIC, @@ -85,9 +92,10 @@ public static ICommonsList getAllTestFiles () @Nonnull @Nonempty - private static ICommonsList _createListFacturX (@Nonnull final String sZugferdVersion, - @Nonnegative final int nCount, - @Nonnull final EZugferdProfile eProfile) + private static ICommonsList _createList (@Nonnull final String sZugferdVersion, + @Nonnegative final int nCount, + @Nonnull final EZugferdProfile eProfile, + @Nonnull final String sFilenamePrefix) { final ICommonsList ret = new CommonsArrayList <> (nCount); for (int i = 1; i <= nCount; ++i) @@ -95,18 +103,44 @@ private static ICommonsList _createListFacturX (@N sZugferdVersion + "/" + eProfile.getFolderName () + - "/factur-x-" + + "/" + + sFilenamePrefix + + "-" + i + ".xml")); return ret; } + @Nonnull + @Nonempty + private static ICommonsList _createListFacturX (@Nonnull final String sZugferdVersion, + @Nonnegative final int nCount, + @Nonnull final EZugferdProfile eProfile) + { + return _createList (sZugferdVersion, nCount, eProfile, "factur-x"); + } + @Nonnull @ReturnsMutableCopy public static ICommonsList getAllMatchingTestFiles (@Nonnull final DVRCoordinate aVESID) { ValueEnforcer.notNull (aVESID, "VESID"); + { + final String sVersion = "2.0.1"; + final String sFilenamePrefix = "zugferd-invoice"; + if (aVESID.equals (ZugferdValidation.VID_ZUGFERD_2_0_1_MINIMUM)) + return _createList (sVersion, 1, EZugferdProfile.MINIMUM, sFilenamePrefix); + if (aVESID.equals (ZugferdValidation.VID_ZUGFERD_2_0_1_BASIC_WL)) + return _createList (sVersion, 0, EZugferdProfile.BASIC_WL, sFilenamePrefix); + if (aVESID.equals (ZugferdValidation.VID_ZUGFERD_2_0_1_BASIC)) + return _createList (sVersion, 3, EZugferdProfile.BASIC, sFilenamePrefix); + if (aVESID.equals (ZugferdValidation.VID_ZUGFERD_2_0_1_EN16931)) + return _createList (sVersion, 20, EZugferdProfile.EN16931, sFilenamePrefix); + if (aVESID.equals (ZugferdValidation.VID_ZUGFERD_2_0_1_EXTENDED)) + return _createList (sVersion, 5, EZugferdProfile.EXTENDED, sFilenamePrefix); + } + { final String sVersion = "2.1"; if (aVESID.equals (ZugferdValidation.VID_ZUGFERD_2_1_MINIMUM)) diff --git a/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/en16931/zugferd-invoice-1.xml b/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/en16931/zugferd-invoice-1.xml index 786d46fd..cd87fdce 100644 --- a/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/en16931/zugferd-invoice-1.xml +++ b/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/en16931/zugferd-invoice-1.xml @@ -98,7 +98,9 @@ Handelsregisternummer: H A 123 4.0000 0.6667 + diff --git a/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/en16931/zugferd-invoice-15.xml b/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/en16931/zugferd-invoice-15.xml index 966eb58e..89e1708e 100644 --- a/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/en16931/zugferd-invoice-15.xml +++ b/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/en16931/zugferd-invoice-15.xml @@ -98,7 +98,9 @@ Handelsregisternummer: H A 123 4.0000 0.6667 + diff --git a/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/en16931/zugferd-invoice-17.xml b/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/en16931/zugferd-invoice-17.xml index 512109af..d399e69a 100644 --- a/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/en16931/zugferd-invoice-17.xml +++ b/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/en16931/zugferd-invoice-17.xml @@ -148,8 +148,10 @@ VKE/Geb: 1 1.5000 0.05 + diff --git a/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/extended/zugferd-invoice-4.xml b/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/extended/zugferd-invoice-4.xml index 49211154..bac0efd2 100644 --- a/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/extended/zugferd-invoice-4.xml +++ b/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/extended/zugferd-invoice-4.xml @@ -101,7 +101,8 @@ GLN 4304171000002 -5.0000 - 1.0000 + + 1.0000 @@ -147,7 +148,8 @@ GLN 4304171000002 -2.0000 - 1.0000 + + 1.0000 diff --git a/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/extended/zugferd-invoice-5.xml b/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/extended/zugferd-invoice-5.xml index 1fe1fda8..2d366a10 100644 --- a/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/extended/zugferd-invoice-5.xml +++ b/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/extended/zugferd-invoice-5.xml @@ -114,7 +114,8 @@ WEEE-Reg-Nr.: DE87654321 100.0000 - 4.0000 + + 4.0000 @@ -160,7 +161,8 @@ WEEE-Reg-Nr.: DE87654321 50.0000 - 1.0000 + + 1.0000 @@ -193,7 +195,8 @@ WEEE-Reg-Nr.: DE87654321 10.0000 - 1.0000 + + 1.0000 @@ -231,7 +234,8 @@ WEEE-Reg-Nr.: DE87654321 15.0000 - 20.0000 + + 20.0000 @@ -268,7 +272,8 @@ WEEE-Reg-Nr.: DE87654321 15.0000 - 1.0000 + + 1.0000 @@ -329,7 +334,8 @@ WEEE-Reg-Nr.: DE87654321 2.0000 - 1.0000 + + 1.0000 diff --git a/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/minimum/zugferd-invoice-1.xml b/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/minimum/zugferd-invoice-1.xml index 61bbf5cd..b4b2f34b 100644 --- a/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/minimum/zugferd-invoice-1.xml +++ b/phive-rules-zugferd/src/test/resources/external/test-files/2.0.1/minimum/zugferd-invoice-1.xml @@ -41,9 +41,13 @@ Gewinn, Datenverlust, Kommunikationsverlust, Einnahmeausfall, Vertragseinbußen, Schäden, Verluste oder Haftpflichten im Zusammenhang mit einer Unterbrechung der Geschäftstätigkeit, noch für konkrete, beiläufig entstandene, mittelbare Schäden, Straf- oder Folgeschäden und zwar auch dann nicht, wenn die Möglichkeit der Kosten, Verluste bzw. Schäden hätte normalerweise vorhergesehen werden können.--> - + - + urn:zugferd.de:2p0:minimum @@ -86,12 +90,26 @@ Kosten, Verluste bzw. Schäden hätte normalerweise vorhergesehen werden können EUR + + + 37.62 + VAT + 198.00 + S + 19.00 + + + + + 20180404 + + 198.00 198.00 37.62 235.62 - 235.62 + 235.62