Removed server. Moved libraryBasic to library and libraryExtended to validator to prevent confusion with profiles.
This commit is contained in:
198
validator/README.md
Normal file
198
validator/README.md
Normal file
@@ -0,0 +1,198 @@
|
||||
# ZUV
|
||||
ZUV (ZUgferd+[VeraPDF](http://VeraPDF.org)) is an open-source e-invoice validator for the [ZUGFeRD](https://www.ferd-net.de/zugferd/specification/index.html)/[Factur-X](http://fnfe-mpe.org/factur-x/) standard.
|
||||
|
||||
It checks both PDF/A-3 compliance (based on VeraPDF) and ZUGFeRD version 1 respectively 2/2.1 XMLs for correctness.
|
||||
The XML check is done by validating against the official ZUGFeRD schematron file for v1 and v2.1 and additionally the EN16931 UN/CEFACT SCRDM v16B uncoupled schematron from the [CEN](https://github.com/CenPC434/validation).
|
||||
|
||||
|
||||
## Build
|
||||
In the pom.xml directory compile the jar with `./mvnw clean package`
|
||||
|
||||
To prepare the schematron files they have to be converted to XSLT files, which is done with a XSLT transformation
|
||||
itself.
|
||||
Get [Saxon](http://saxon.sourceforge.net/#F9.9HE) and the [XSLT](https://github.com/Schematron/stf/tree/master/iso-schematron-xslt2) to convert schematron to XSLT
|
||||
and run
|
||||
`java -jar ./saxon9he.jar -o:minimum.xsl -s:zugferd2p0_basicwl_minimum.sch ./schematron_to_xslt/iso-schematron-xslt2/iso_svrl_for_xslt1.xsl`
|
||||
to do so.
|
||||
|
||||
To create a new en16931 run
|
||||
`
|
||||
git clone https://github.com/ConnectingEurope/eInvoicing-EN16931.git
|
||||
mvn -f pom-xslt.xml package
|
||||
`
|
||||
|
||||
|
||||
|
||||
|
||||
## Run
|
||||
|
||||
To check a file for ZUGFeRD conformance use
|
||||
|
||||
`java -jar ZUV-0.9.0.jar --action validate -f <filename of ZUGFeRD PDF.pdf>`
|
||||
|
||||
You can provide either the complete PDF which will be checked for XML and PDF correctness, or just a XML file, which of course
|
||||
will only be checked for XML correctness.
|
||||
|
||||
|
||||
## Output
|
||||
A valid file looks like this
|
||||
```
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<validation filename="Facture_UE_MINIMUM.pdf" datetime="2020-03-23 12:34:54">
|
||||
<pdf>
|
||||
<report>
|
||||
<buildInformation>
|
||||
<releaseDetails id="core" version="1.12.1" buildDate="2018-05-08T18:57:00+02:00"/>
|
||||
<releaseDetails id="validation-model" version="1.12.1" buildDate="2018-05-08T20:39:00+02:00"/>
|
||||
</buildInformation>
|
||||
<jobs>
|
||||
<job>
|
||||
<item size="101181">
|
||||
<name>/Users/jstaerk/workspace/zugferd/helper_files/../foreign_samples/fx/Facture_UE_MINIMUM.pdf</name>
|
||||
</item>
|
||||
<validationReport profileName="PDF/A-3B validation profile" statement="PDF file is compliant with Validation Profile requirements." isCompliant="true">
|
||||
<details passedRules="123" failedRules="0" passedChecks="11082" failedChecks="0"/>
|
||||
</validationReport>
|
||||
<duration start="1584963295227" finish="1584963296646">00:00:01.419</duration>
|
||||
</job>
|
||||
</jobs>
|
||||
<batchSummary totalJobs="1" failedToParse="0" encrypted="0">
|
||||
<validationReports compliant="1" nonCompliant="0" failedJobs="0">1</validationReports>
|
||||
<featureReports failedJobs="0">0</featureReports>
|
||||
<repairReports failedJobs="0">0</repairReports>
|
||||
<duration start="1584963294997" finish="1584963296679">00:00:01.682</duration>
|
||||
</batchSummary>
|
||||
</report>
|
||||
<info>
|
||||
<signature>Factur/X Python</signature>
|
||||
<duration unit="ms">2361</duration>
|
||||
</info>
|
||||
<summary status="valid"/>
|
||||
</pdf>
|
||||
<xml>
|
||||
<info>
|
||||
<version>2</version>
|
||||
<profile>urn:factur-x.eu:1p0:minimum</profile>
|
||||
<validator version="0.8.4-RESTRICTED"/>
|
||||
<rules>
|
||||
<fired>26</fired>
|
||||
<failed>0</failed>
|
||||
</rules>
|
||||
<duration unit="ms">2772</duration>
|
||||
</info>
|
||||
<summary status="valid"/>
|
||||
</xml>
|
||||
<summary status="valid"/>
|
||||
</validation>
|
||||
```
|
||||
Invalid files with errors e.g. in the XML part can look like this
|
||||
```
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<validation filename="Facture_UE_EXTENDED.pdf" datetime="2020-03-23 12:34:43">
|
||||
<pdf>
|
||||
<report>
|
||||
<buildInformation>
|
||||
<releaseDetails id="core" version="1.12.1" buildDate="2018-05-08T18:57:00+02:00"/>
|
||||
<releaseDetails id="validation-model" version="1.12.1" buildDate="2018-05-08T20:39:00+02:00"/>
|
||||
</buildInformation>
|
||||
<jobs>
|
||||
<job>
|
||||
<item size="109172">
|
||||
<name>/Users/jstaerk/workspace/zugferd/helper_files/../foreign_samples/fx/Facture_UE_EXTENDED.pdf</name>
|
||||
</item>
|
||||
<validationReport profileName="PDF/A-3B validation profile" statement="PDF file is compliant with Validation Profile requirements." isCompliant="true">
|
||||
<details passedRules="123" failedRules="0" passedChecks="11082" failedChecks="0"/>
|
||||
</validationReport>
|
||||
<duration start="1584963283448" finish="1584963284790">00:00:01.342</duration>
|
||||
</job>
|
||||
</jobs>
|
||||
<batchSummary totalJobs="1" failedToParse="0" encrypted="0">
|
||||
<validationReports compliant="1" nonCompliant="0" failedJobs="0">1</validationReports>
|
||||
<featureReports failedJobs="0">0</featureReports>
|
||||
<repairReports failedJobs="0">0</repairReports>
|
||||
<duration start="1584963283223" finish="1584963284825">00:00:01.602</duration>
|
||||
</batchSummary>
|
||||
</report>
|
||||
<info>
|
||||
<signature>Factur/X Python</signature>
|
||||
<duration unit="ms">2296</duration>
|
||||
</info>
|
||||
<summary status="valid"/>
|
||||
</pdf>
|
||||
<xml>
|
||||
<info>
|
||||
<version>2</version>
|
||||
<profile>urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended</profile>
|
||||
<validator version="0.8.4-RESTRICTED"/>
|
||||
<rules>
|
||||
<fired>97</fired>
|
||||
<failed>1</failed>
|
||||
</rules>
|
||||
<duration unit="ms">8546</duration>
|
||||
</info>
|
||||
<messages>
|
||||
<error type="4" location="/*[local-name()='CrossIndustryInvoice' and namespace-uri()='urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100']/*[local-name()='SupplyChainTradeTransaction' and namespace-uri()='urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100']/*[local-name()='ApplicableHeaderTradeSettlement' and namespace-uri()='urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100']/*[local-name()='ApplicableTradeTax' and namespace-uri()='urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100']/*[local-name()='CategoryCode' and namespace-uri()='urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100']" criterion="(/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeDelivery/ram:ActualDeliverySupplyChainEvent/ram:OccurrenceDateTime/udt:DateTimeString) or (../../ram:BillingSpecifiedPeriod/ram:StartDateTime) or (../../ram:BillingSpecifiedPeriod/ram:EndDateTime)">In an Invoice with a VAT breakdown (BG-23) where the VAT category code (BT-118) is "Intra-community supply" the Actual delivery date (BT-72) or the Invoicing period (BG-14) shall not be blank.</error>
|
||||
</messages>
|
||||
<summary status="invalid"/>
|
||||
</xml>
|
||||
<messages></messages>
|
||||
<summary status="invalid"/>
|
||||
</validation>
|
||||
```
|
||||
|
||||
## Embed
|
||||
|
||||
Feel free to embed this into your java software, send me a PR to use it as a library, or exec it and parse it's output to put on the web.
|
||||
|
||||
For exec, you might try something like
|
||||
```
|
||||
exec('java -Dfile.encoding=UTF-8 -jar /path/to/ZUV-0.9.0.jar --action validate -f '.escapeshellarg($uploadfile).' 2>/dev/null', $output);
|
||||
```
|
||||
* Redirecting stderr away (some logging messages might otherwise disturb XML well formedness)
|
||||
* Escaping any file names in case you use original file names at all (apart from security concerns please take into account that they might contain spaces)
|
||||
* Signal java to use UTF-8 even when otherwise it would not: You might run into trouble with XML files starting with a BOM otherwise and when you exec, keep in mind that you lose all env vars.
|
||||
|
||||
## License
|
||||
|
||||
Permissive Open Source APL2, see LICENSE
|
||||
|
||||
## Codes
|
||||
|
||||
| section | meaning |
|
||||
|---|---|
|
||||
| 1 | file not found |
|
||||
| 2 | additional data schema validation fails |
|
||||
| 3 | xml data not found |
|
||||
| 4 | schematron rule failed |
|
||||
| 5 | file too small |
|
||||
| 6 | VeraPDFException |
|
||||
| 7 | IOException PDF |
|
||||
| 8 | File does not look like PDF nor XML (contains neither %PDF nor <?xml) |
|
||||
| 9 | IOException XML |
|
||||
| 11 | XMP Metadata: ConformanceLevel not found |
|
||||
| 12 | XMP Metadata: ConformanceLevel contains invalid value |
|
||||
| 13 | XMP Metadata: DocumentType not found |
|
||||
| 14 | XMP Metadata: DocumentType invalid |
|
||||
| 15 | XMP Metadata: Version not found |
|
||||
| 16 | XMP Metadata: Version contains invalid value |
|
||||
| 18 | schema validation failed |
|
||||
| 19 | XMP Metadata: DocumentFileName contains invalid value |
|
||||
| 20 | not a pdf |
|
||||
| 21 | XMP Metadata: DocumentFileName not found") |
|
||||
| 22 | generic XML validation exception |
|
||||
| 23 | Not a PDF/A-3 |
|
||||
| 24 | Issues in CEN EN16931 Schematron Check |
|
||||
| 25 | Unsupported profile type |
|
||||
| 26 | No rules matched, XML to minimal? |
|
||||
|
||||
## History
|
||||
|
||||
see the [history file](History.md)
|
||||
|
||||
|
||||
## Authors
|
||||
|
||||
Jochen Staerk "Mustangproject Chief ZUGFeRD amatuer" <jochen@zugferd.org>
|
||||
|
||||
Reference in New Issue
Block a user