FileMaker with ZUGFeRD 2.0 and Factur-X
With the last DynaPDF update we got new support for ZUGFeRD 2.0 and Factur-X, two standards to deliver invoices as PDF files with embedded XML data. We supported ZUGFeRD 1.0 before and now upgraded code to support version 2, too.
So here is a little FileMaker script to convert an existing PDF into a ZUGFeRD 2.0 document. Before you start, please assemble the XML for the invoice and know whether it's Minimum, Basic, Comfort or Extended level. So the script here initializes DynaPDF library if needed and then creates a new PDF environment. We set import flags to import all content and prepare for PDF/A. If needed, you could skip some content like annotations directly here.
# Initialize DynaPDF if needed
If [ MBS("DynaPDF.IsInitialized") ≠ 1 ]
Perform Script [ Specified: From list ; “InitDynaPDF” ; Parameter: ]
End If
# Make new PDF environments
Set Variable [ $pdf ; Value: MBS("DynaPDF.New") ]
# Set import flags with Prepare For PDF/A enabled
Set Variable [ $r ; Value: MBS( "DynaPDF.SetImportFlags"; $pdf; "ImportAll¶ImportAsPage¶PrepareForPDFA" ) ]
Next we load an existing PDF from a container field. Of course you can also use functions to create new pages here or open an import PDF from a file on disk. The next line imports the whole PDF file we opened into our work PDF. If you repeat the open and import step, you can merge several documents here. If you need only one page, you can use DynaPDF.ImportPDFPage function.
# Load PDF from container
Set Variable [ $r ; Value: MBS("DynaPDF.OpenPDFFromContainer"; $pdf; ZUGFeRD Invoice::Invoice Template) ]
# Import all pages
Set Variable [ $r ; Value: MBS("DynaPDF.ImportPDFFile"; $pdf) ]
Per PDF/A requirement, we add here the language setting and a structure tree:
# PDF/A requires a language set
Set Variable [ $r ; Value: MBS("DynaPDF.SetLanguage"; $pdf; "en-US") ]
# PDF/A requires a structure tree
Set Variable [ $r ; Value: MBS("DynaPDF.CreateStructureTree"; $pdf) ]
If the PDF contains colorspaces which are not backed by an ICC Profile, we pass in replacement profiles to the PDF engine. So if there is a colorspace missing the profile, it will be using one of our replacement profiles for RGB, Gray or CMYK.
# Set replacements for missing ICC profiles
Set Variable [ $r ; Value: MBS("DynaPDF.SetReplaceICCProfileData"; $pdf; "rgb"; ZUGFeRD Invoice::RGB ICC Profile) ]
Set Variable [ $r ; Value: MBS("DynaPDF.SetReplaceICCProfileData"; $pdf; "gray"; ZUGFeRD Invoice::Gray ICC Profile) ]
Set Variable [ $r ; Value: MBS("DynaPDF.SetReplaceICCProfileData"; $pdf; "cmyk"; ZUGFeRD Invoice::CMYK ICC Profile) ]
Next we attach the XML invoice to the PDF. You can pass attachments as container, file or text, but please use the corresponding function. Here we pass it as text from a field, specify UTF-8 encoding and the ZUGFeRD specific file name. The attachment is associated with the main catalog as an alternative version.
# add xml with invoice data
Set Variable [ $FileHandle ; Value: MBS("DynaPDF.AttachFileText"; $pdf; ZUGFeRD Invoice::Invoice XML; "UTF-8"; "ZUGFeRD-invoice.xml"; "Invoice as XML") ]
Set Variable [ $r ; Value: MBS("DynaPDF.AssociateEmbFile"; $pdf; "Catalog"; -1; "Alternative"; $FileHandle) ]
Now we do the conformance check. If you licensed the PDF/A converter from us (Add-on for DynaPDF Pro), you get the PDF fixed if needed. If the PDF was already PDF/A, this should return okay and tel you which output indent is recommended. We than add the ICC Profile for RGB or CMYK to indicate how the PDF likes to be viewed.
# Check if this PDF conforms to PDF/A-3b
Set Variable [ $c ; Value: MBS("DynaPDF.CheckConformance"; $pdf; "ZUGFeRD2 Basic"; "Default") ]
If [ $c = 1 ]
# A RGB ICC profile must be added to the document
Set Variable [ $r ; Value: MBS("DynaPDF.AddOutputIntentEx"; $pdf; ZUGFeRD Invoice::RGB ICC Profile) ]
Else If [ $c = 2 ]
# A CMYK ICC profile must be added to the document
Set Variable [ $r ; Value: MBS("DynaPDF.AddOutputIntentEx"; $pdf; ZUGFeRD Invoice::CMYK ICC Profile) ]
Else If [ $c = 3 ]
# A Gray, RGB, or CMYK ICC profile must be added to the document
Set Variable [ $r ; Value: MBS("DynaPDF.AddOutputIntentEx"; $pdf; ZUGFeRD Invoice::RGB ICC Profile) ]
End If
Finally we save the PDF in a field, commit the record and cleanup the PDF environment.
# save to container
Set Variable [ $PDFData ; Value: MBS("DynaPDF.Save"; $pdf; "invoice.pdf") ]
Set Field [ ZUGFeRD Invoice::Output PDF ; $PDFData ]
Commit Records/Requests [ With dialog: On ]
# cleanup memory
Set Variable [ $r ; Value: MBS("DynaPDF.Release"; $pdf) ]
We hope you enjoy this blog post. Please check the example databases included with MBS FileMaker Plugin 9.3.