Skip to content

Commit

Permalink
Added ZF 2.0.1 validation and fixed examples
Browse files Browse the repository at this point in the history
  • Loading branch information
phax committed Jan 3, 2025
1 parent c761e1e commit b87b299
Show file tree
Hide file tree
Showing 10 changed files with 157 additions and 17 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 (),
Expand Down Expand Up @@ -102,6 +119,7 @@ public final class ZugferdValidation
private static final ICommonsMap <DVRVersion, DVRVersion> 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"));
Expand Down Expand Up @@ -156,6 +174,60 @@ public static void initZugferd (@Nonnull final IValidationExecutorSetRegistry <I
final boolean bDeprecated = true;
final boolean bNotDeprecated = false;

// Zugferd 2.0.1 / Factur-X 1.0.3
for (final EZugferdProfile eProfile : EZugferdProfile.values ())
{
final String sZugferdVersion = "2.0.1";
final String sProfileNamePart;
switch (eProfile)
{
case MINIMUM:
case BASIC_WL:
sProfileNamePart = "basicwl_minimum";
break;
case BASIC:
case EN16931:
sProfileNamePart = "en16931";
break;
case EXTENDED:
sProfileNamePart = "extended";
break;
default:
throw new IllegalStateException ();
}

final var aVESchematron = PhiveRulesCIIHelper.createXSLT_CII_D16B (new ClassPathResource ("/external/schematron/" +
sZugferdVersion +
"/zugferd2p0_" +
sProfileNamePart +
".xslt",
_getCL ()));

// Register as Zugferd
final DVRCoordinate aVESID = PhiveRulesHelper.createCoordinate (GROUP_ID_ZUGFERD,
eProfile.getArtifactID (),
sZugferdVersion);
final String sDisplayName = "ZUGFeRD " + sZugferdVersion + " (" + eProfile.getDisplayName () + ")";
final IValidationExecutorSetStatus aStatus = PhiveRulesHelper.createSimpleStatus (bDeprecated);
final ValidationExecutorSet <IValidationSourceXML> 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 ())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void testApplyCompleteValidation ()
for (final PhiveTestFile aTestFile : CTestFiles.getAllTestFiles ())
{
final IValidationExecutorSet <IValidationSourceXML> aExecutors = CTestFiles.VES_REGISTRY.getOfID (aTestFile.getVESID ());
assertNotNull (aExecutors);
assertNotNull ("Failed to resolve VESID '" + aTestFile.getVESID () + "'", aExecutors);

LOGGER.info ("Validating " +
aTestFile.getResource ().getPath () +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,14 @@ private CTestFiles ()
public static ICommonsList <PhiveTestFile> getAllTestFiles ()
{
final ICommonsList <PhiveTestFile> 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,
Expand Down Expand Up @@ -85,28 +92,55 @@ public static ICommonsList <PhiveTestFile> getAllTestFiles ()

@Nonnull
@Nonempty
private static ICommonsList <? extends IReadableResource> _createListFacturX (@Nonnull final String sZugferdVersion,
@Nonnegative final int nCount,
@Nonnull final EZugferdProfile eProfile)
private static ICommonsList <? extends IReadableResource> _createList (@Nonnull final String sZugferdVersion,
@Nonnegative final int nCount,
@Nonnull final EZugferdProfile eProfile,
@Nonnull final String sFilenamePrefix)
{
final ICommonsList <IReadableResource> ret = new CommonsArrayList <> (nCount);
for (int i = 1; i <= nCount; ++i)
ret.add (new ClassPathResource ("/external/test-files/" +
sZugferdVersion +
"/" +
eProfile.getFolderName () +
"/factur-x-" +
"/" +
sFilenamePrefix +
"-" +
i +
".xml"));
return ret;
}

@Nonnull
@Nonempty
private static ICommonsList <? extends IReadableResource> _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 <? extends IReadableResource> 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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ Handelsregisternummer: H A 123
<ram:ChargeAmount>4.0000</ram:ChargeAmount>
<ram:AppliedTradeAllowanceCharge>
<ram:ActualAmount>0.6667</ram:ActualAmount>
<!-- [PH] disabled due to Schematron check
<ram:Reason>Rabatt</ram:Reason>
-->
</ram:AppliedTradeAllowanceCharge>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ Handelsregisternummer: H A 123
<ram:ChargeAmount>4.0000</ram:ChargeAmount>
<ram:AppliedTradeAllowanceCharge>
<ram:ActualAmount>0.6667</ram:ActualAmount>
<!-- [PH] disabled due to Schematron check
<ram:Reason>Rabatt</ram:Reason>
-->
</ram:AppliedTradeAllowanceCharge>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,10 @@ VKE/Geb: 1
<ram:ChargeAmount>1.5000</ram:ChargeAmount>
<ram:AppliedTradeAllowanceCharge>
<ram:ActualAmount>0.05</ram:ActualAmount>
<!-- [PH] disabled due to Schematron check
<ram:Reason>Artikelrabatt 1: -2,00% Basis: -1,500 € Rabatt: 0,03 €/Stk.
Artikelrabatt 2: Basis: Rabatt: 0,02 €/Stk.</ram:Reason>
-->
</ram:AppliedTradeAllowanceCharge>
</ram:GrossPriceProductTradePrice>
<ram:NetPriceProductTradePrice>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ GLN 4304171000002
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">-5.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="BO">1.0000</ram:PackageQuantity>
<!-- [PH] changed from BO -->
<ram:PackageQuantity unitCode="C62">1.0000</ram:PackageQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
Expand Down Expand Up @@ -147,7 +148,8 @@ GLN 4304171000002
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">-2.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="CT">1.0000</ram:PackageQuantity>
<!-- [PH] changed from CT -->
<ram:PackageQuantity unitCode="C62">1.0000</ram:PackageQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ WEEE-Reg-Nr.: DE87654321
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">100.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="CT">4.0000</ram:PackageQuantity>
<!-- [PH] changed from CT -->
<ram:PackageQuantity unitCode="C62">4.0000</ram:PackageQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
Expand Down Expand Up @@ -160,7 +161,8 @@ WEEE-Reg-Nr.: DE87654321
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">50.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="CT">1.0000</ram:PackageQuantity>
<!-- [PH] changed from CT -->
<ram:PackageQuantity unitCode="C62">1.0000</ram:PackageQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
Expand Down Expand Up @@ -193,7 +195,8 @@ WEEE-Reg-Nr.: DE87654321
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">10.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="CT">1.0000</ram:PackageQuantity>
<!-- [PH] changed from CT -->
<ram:PackageQuantity unitCode="C62">1.0000</ram:PackageQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
Expand Down Expand Up @@ -231,7 +234,8 @@ WEEE-Reg-Nr.: DE87654321
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">15.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="BO">20.0000</ram:PackageQuantity>
<!-- [PH] changed from BO -->
<ram:PackageQuantity unitCode="C62">20.0000</ram:PackageQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
Expand Down Expand Up @@ -268,7 +272,8 @@ WEEE-Reg-Nr.: DE87654321
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">15.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="BC">1.0000</ram:PackageQuantity>
<!-- [PH] changed from BC -->
<ram:PackageQuantity unitCode="C62">1.0000</ram:PackageQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
Expand Down Expand Up @@ -329,7 +334,8 @@ WEEE-Reg-Nr.: DE87654321
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">2.0000</ram:BilledQuantity>
<ram:PackageQuantity unitCode="PX">1.0000</ram:PackageQuantity>
<!-- [PH] changed from PX -->
<ram:PackageQuantity unitCode="C62">1.0000</ram:PackageQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
Expand Down
Loading

0 comments on commit b87b299

Please sign in to comment.