directmail/directspool/pdfenhancer and ZUGFeRD

Table of contents

overview: what is ZUGFerD?

In addition to transporting the document, the PDF standard PDF/A-3 allows the invoice data to be delivered in XML format at the same time. This is done as an internal "attachment" of a PDF file, so to speak. The recipient is thus enabled to export the important data of an invoice to a database. There is no need for manual data entry by reading from the receipt.

Some large companies have already made this method of data transfer a requirement when writing invoices in the form of a PDF file, or have announced it as a requirement for the near future.

DirectSpool (formerly Automail) has been extended to retrieve the invoice data from the spool file (SPLF) and add it to the PDF file as XML data. No programming is required for the sender. The recipient can use Adobe Reader to view the document and use the "paperclip" icon to export the XML data (more on this below).

FeRD or ZUGFeRD?

The terms FeRD (Forum elektronische Rechnung Deutschland) and ZUGFeRD (Zentraler User Guide vom Forum elektronische Rechnung Deutschland) generally mean the same thing

The Forum has created a ZUGFeRD process description that is intended to serve as a standard or orientation for companies of all kinds so that data can be exchanged from sender to recipient quickly and without errors via digital means. This is part of the digitization efforts of the German economy.

For more information on the "ZUGFeRD" system, visit https://www.zugferd-tech.de/.

Variants: BASE / EXTENDED / COMFORT

The ZUGFeRD standard recognizes different "profiles". directmail currently supports BASE, EXTENDED and COMFORT

Each of these profiles offers "space" for invoice data

In addition, the profiles XRECHNUNG and BASIC WL are defined

Extract from ZUGFeRD-2.1.1 - Specification.pdf - see: https://www.ferd-net.de/standards/zugferd-2.1.1/index.html

For the successful use of ZUGFeRD in directmail, it is first necessary to agree with the business partners on the profile to be used: which data should be transferred?

The EXTENDED profile meets all requirements in most cases.

Requirements for using directmail for ZUGFeRD

  • DirectSpool/DirectMail version 5.50 or higher
  • Toolmaker license for ZUGFeRD XML (possibly also for XMR)
  • Spool files with SCS or IPDS data stream (standard)
  • Output format *EPDF
  • Value *ZUGFERD in the PDF form specifications at Parameter Create PDF/A
  • Font file in IFS under /Toolmaker/DirectMail400/Fonts (e.g. cour.ttf)
  • Files ZUG.XML and ZUG.XMP in IFS under /Toolmaker/DirectMail400/Zugferd



Define indexes for ZUGFeRD

As usual in DirectSpool, variable data is retrieved by definition from the spool file and stored as indexes (example &RGNR). In addition, values can be read from a file via SQL and also defined as indices.

On the part of ZUGFeRD there are fixed predefined fields for both the header and the post data of an invoice, to which the collected indices from the SPLF are assigned via a convenient function. The use of constant values and date routines for format conversion are also possible.

Based on a working Automail definition, the following describes how to activate the ZUGFeRD function and assign the indices.

Call DirectSpool (Automail) with WRKATMDEF. Then press key F7 ZUGFeRD Definition




X-File Template - defines the embedding structure for the PDF

X-ADD Template - zug.xmp defines the pattern for the Zugferd structure

Start Position / End Position - defines the duplication of the positions. E.g. invoice positions

API program - a program can be defined in which the XML will be generated

The program must be in the DIRMAIL library and have any new name

Below is a sample API program:

Sample API program
        CTL-OPT DEBUG(*YES)   OPTION(*NODEBUGIO)  ;
        CTL-OPT DECEDIT('0,') DATEDIT(*DMY.)                    ;
       //********************************************************************
       //   Example ZugFeRD API Programm                                    *
       //                                                                   *
       // Autor: Roman Tutschka   07.2019                                   *
       //********************************************************************
       //  CREATE  COMMANDS:
       // Replace PGMLIB , SRCLIB , PGMNAM with your own Names
       // PGMLIB is normaly DIRMAIL  use an NEW !!! Programm Name 
       // COMMANDS:
       // ADDLIBLE DIRMAIL 
       //
       // CRTSQLRPGI OBJ(PGMLIB/PGMNAM) SRCFILE(SRCLIB/QRPGLESRC) 
       // SRCMBR(PGMNAM) COMMIT(*NONE) OBJTYPE(*MODULE) USER(*CURRENT) 
       // REPLACE(*YES) DBGVIEW(*SOURCE) 
       //
       // CRTPGM PGM(PGMLIB/PGMNAM) BNDSRVPGM((DIRMAIL/DMLIB))
       //
       // Entry
    ?   DCL-PR  DMWRKZUX ;
         ID   PACKED(11:0);       // Identifikation
         SEGMENT   PACKED(9:0);   // Identifikation
         PXML POINTER ;           // Returns Pointer for embedded XML
         siz INT(10) ;            // Returns Size of the XML
        END-PR;
       // Internal Definition
    ?   DCL-PI  DMWRKZUX ;
         ID   PACKED(11:0);       // Identifikation
         SEGMENT   PACKED(9:0);   // Identifikation
         PXML POINTER ;      // Returns Pointer for embedded XML
         siz INT(10) ;       // Size of the XML
        END-PI;

      
       DCL-PR dm_etoa  INT(10) extproc('dm_etoa') ;
        buffer      CHAR(32767) options(*varsize)  ;
        bufferlen   INT(10)  value ;    
       END-PR;

        DCL-S PRETCHAR char(999999)  based(PXML) ;
       //
        DCL-DS DSHDR EXTNAME('DMEXCHDR') END-DS;             // Datastucture for Header Information
        DCL-DS DSZUG EXTNAME('DMATMZUG') QUALIFIED END-DS;   // Datastucture for ZUGFERD Information
        DCL-DS DSIDX EXTNAME('DMEXCIDX') QUALIFIED END-DS;   // Datastucture for INDEX Information
        DCL-S INDEXNAM LIKE(DSIDX.EINAM)  ;   // Name of the Index
       //********************************************************************
       // Main Programm
       //********************************************************************
         PXML = %ALLOC(10000000);       // Allocate MAX space for Return FREED in DIRMAIL

         // Read DIRMAIL Header Information OPTIONAL
         EXEC SQL  SELECT * INTO :DSHDR FROM DMEXCHDR
           WHERE   EASEQ = :ID ;
         // Read Indexes Values from DIRMAIL
         clear DSIDX;  // init
         INDEXNAM = 'RGNR';  //  Example in this case the result 
         // is the Value from the DIRMAIL Index for Example the Invoice Number 
         EXEC SQL SELECT I.* INTO :DSIDX  from DMEXCSEG as S 
           join DMEXCIDX as I on ESSEQ = EISEQ
           WHERE   ESSEQ = :ID AND ESNUM = :SEGMENT  AND
           EIPAG >= ESSTR AND EIPAG <= ESEND
            AND  EINAM = :INDEXNAM
            FETCH FIRST 1 ROWS ONLY;
         // Result value for the example Index ''RGNR'' in in DSIDX.DSIDX   

         // Create Embedded XML
         // EXAMLE  Value
         IF SQLCOD = 0;
           // Example embed INVOICE Number INDEXNAM RGNR exist 
           PRETCHAR = DSIDX.EIVAL ;     // Example embed INVOICE Number INDEXNAM
         ELSE;
           // Example embed INVOICE Number INDEXNAM RGNR do not exist 
           PRETCHAR = 'RETURN XML'  ;  // Example
         ENDIF;
         // Convert to ASCII  needed if the valoue is in EBDIC
         dm_etoa(PRETCHAR: %LEN(%TRIM(PRETCHAR))) ;
         siz = %LEN(%TRIM(PRETCHAR))     ;
         // if the Value of the XML is in ASCII only  return the address of PXML
         // and the Size of DATA

         return;

ZUGFeRD definitions and default values

After pressing Enter, the following dialog program appears, allowing you to enter and save the default values for each FeRD field.

Notes on the columns:

Type: H=Header (header info of the invoice), P=Items (e.g. for article line)

Variable Name: The name defined by the ZUGFeRD organization for a feature

Default Value: A constantvalue for a characteristic, specified by you for your company

XML Format: If required, the function for decimal and date formats can be selected here with F4. The displayed possibilities are defined in the parameter control file of WOPiXX under ZUGFORMAT.

Origin format: Specify if absolutely necessary. Normally the date format is recognized automatically. The format can also be selected here with F4. The displayed options are defined in the parameter control file of WOPiXX under ZUGOFORMAT.

Sequence: Sequence for the representation in this display.

If the variable names are not understandable, the view can be switched with F11 and a designation can be shown.

Check required indices

All variable values from the spool file that are to be included in the PDF file as XML data must have been defined as indices. Example:

The topic Define and Condition Indexes is assumed to be known (see chapter "Create Index" on the directspool documentation page). The picture shows the graphical representation of the defined indices in reverse display and their condition constants by means of underlining. The colors may differ. The details are shown in the following image.

The listing and administration of the index entries can be reached via pulldown menu Index and item 4 Work with indexes. Each index name can be used in the desired places in the automail definition by prefixing it with &.

ZUGFeRD Assignments

The following screen is used to map the individual indexes from the spool file to the fixed field names of the XML structure. It can be reached via the pulldown menu Extras and item 3.

All ZUGFeRD default values are displayed (description see above) and one can now select the indices from a list of 1 with F4 for the still empty lines. An index can be recognized by the leading character & (examples &RGDAT, &KDNR, &RGNR).

If the variable names are not understandable, the view can be switched with F11 and a designation can be shown.

Format of the PDF file

Within the directspool definition it must be checked if the spool output format is set correctly, it must be *EPDF.

In directspool (Automail) you find this window under the pulldown menu Email at 3. output format.

PDF form specifications - Parameters font and PDF/A *ZUGFERD

Under the item 5. form/paper in the menu Email 2 parameters must be set.

Font - must contain the name of a font file

This is usually COUR.TTF (this font is from the Windows environment and is not supplied by Toolmaker)

The font file must be located in the IFS directory under

/Toolmaker/Directmail400/Fonts

.

Reason: Font files may be subject to copyrights! If no font file is provided and specified here, an error will occur. The special value *COURIER generally specified here is not sufficient because the PDF/A format forces the font file to be embedded.

Create PDF/A - *ZUGFERD must be specified here so that the XML data is also inserted in the PDF file.

Save definition

After all required indexes have been assigned to the ZUGFeRD variables, the definition can be saved with F3 and J=Yes.



The XADD files

Edit an XADD file

Call DirectSpool (Automail) with WRKATMDEF. Then press key F7 ZUGFeRD Definition

Select choice 8 for the file you want to modify

This opens the editor with this file. You can now make the pending changes.




Not allowed special characters (&, <, >, " and ')

There are five characters that are not allowed in XML files. In their place you have to enter a so-called "escape" sequence. These are:

CharactersEscape sequence
"&quot;
'

&apos;

<&lt;
>&gt;
&&amp;

(see e.g. https://stackoverflow. com/questions/1091945/what-characters-do-i-need-to-escape-in-xml-documents)

The ampersand (&) is corrected automatically

Example in a spoolmail definition, an index is fetched from a database file. The field contains the name of a company:

ACME GmbH & Co. KG

If this string would be taken over "as is" into the XML file, a syntax error would occur.

However, Directspool automatically corrects the string during the transfer and converts it to:

<ram:SellerTradeParty>
<ram:Name>ACME GmbH &amp; Co KG</ram:Name>

So there is no special need for action for the developer of the directspool definition.

Special cases: surround the string with <![CDATA[....]]>

The sequence <![CDATA[<any_text> ]]> ensures that special characters can be specified in <any_text>. The XML parser ignores these. This allows the contents of the field to be output without modification.

Solution with <![CDATA
<ram:SellerTradeParty>
  <ram:Name>
     <![CDATA[
         Artikel "Kerzenständer 30cm" nicht lieferbar
     ]]> 
  </ram:Name>
...

Further hints for <![CDATA: (https://stackoverflow.com/questions/2784183/what-does-cdata-in-xml-mean)




Check result

Assuming that this is a working automail definition that has now been extended to include the ZUGFeRD feature, a matching spool file can be inserted into the monitored OUTQ and the result of the conversion can be checked The process you have defined can be an e-mail with a PDF attachment, a PDF file exported to IFS or an archived PDF file.

Export XML file from PDF document

Double click the PDF file. Adobe Reader should open and display the contents. Nothing has changed in this display, but it is shown in the left, vertical toolbar a paperclip displayed

Click on it and check the list of file attachments. Double-click the ZUGFeRD XML file - the application associated with the XML extension will open and display the XML code. You may see a warning about potential risks when opening the file.


With right click on the name of the file you can save the XML file in a directory.

Hints

If you receive e.g. invoices from your suppliers in PDF/A-3 format, the procedure for exporting the XML attachment is exactly the same as described above

On IBM i it is possible to export and process an XML file automatically in IFS. More information about this:


Editing XML with a PC editor

Some editor programs for PCs offer the possibility to display XML files "reasonably" and also to check the syntax.

For example Notepad++

For example, there are so-called "plug-ins" for the open source software Notepad++ (https://notepad-plus-plus.org/) for these purposes. Here would be

  • XML Tools - Clean display, syntax checking
  • Npp Xml Treeview - display of XML file as tree


ZUGFeRD validation portals

www.din-zugferd-validation.org

At www.din-zugferd-validat ion.org there is a possibility to validate an XML file.

It is necessary to register there. Registration and validation of ZUGFeRD XML files is free of charge (as of Dec. 2020).

Disclaimer: We have no influence on the content of this website and do not assume any liability for it.

https://portal3.gefeg.com/invoice/validation

To this portal you can submit the complete PDF file in which the ZUGFeRD XML file is embedded.

It is also necessary to register here.





Export API DMEXPPDA for PDF/A-3 files

This interface is licensed separately and can be unlocked with the license code XMR from Toolmaker.

You have received a PDF/A-3 file If you want to automate the export of the XML data in the IBM i world and process the XML data immediately, you can call the DirectSpool API program DMEXPPDA from your application and pass 3 parameters

RPGLE example (test program excerpt):
// Definitions
DCL-S ifsobj char(250) inz('/A/Zugferd_Testhw1_QPRINT.PDF') ;
DCL-S ifsout char(250) inz('/A/Zugferd_Testhw1_OUTPUT.xml') ;
DCL-S retcod char(80) inz ;
Dcl-Pr DMexppda ExtPgm('DMEXPPDA') ;
PDFDocument CHAR(250) ;
resultFile CHAR(250) ;
returnCode CHAR(80) ;
End-Pr ;
// Call the program
DMexppda(ifsobj:ifsout:retcod) ;
if retcod = *blank ;
// PDF attachment has been exported
Else ;
// error handling
Endif ;