diff --git a/assets/zugferd.xmp b/assets/zugferd.xmp new file mode 100644 index 0000000..6fdc072 --- /dev/null +++ b/assets/zugferd.xmp @@ -0,0 +1,57 @@ + + + + + + + + ZUGFeRD PDFA Extension Schema + urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0# + fx + + + + DocumentFileName + Text + external + name of the embedded XML invoice file + + + DocumentType + Text + external + INVOICE + + + Version + Text + external + The actual version of the ZUGFeRD data + + + ConformanceLevel + Text + external + The conformance level of the ZUGFeRD data + + + + + + + + + + + diff --git a/pkg/pdf/pdf.go b/pkg/pdf/pdf.go index 6e0f81f..482acc6 100644 --- a/pkg/pdf/pdf.go +++ b/pkg/pdf/pdf.go @@ -6,6 +6,7 @@ import ( "context" "fmt" "io/fs" + "os" "path/filepath" ) @@ -24,6 +25,7 @@ type options struct { metadata *Metadata styles []*Stylesheet attachments []*Attachment + xmpMetadata *XMPMetadata } // Metadata contains additional information to add to the PDF @@ -49,6 +51,12 @@ type Attachment struct { Description string } +// XMPMetadata is used to add XMP metadata to the PDF. +type XMPMetadata struct { + Data []byte + Filename string +} + // WithURL sets the URL to use for the connection to a remote server if needed. func WithURL(url string) Config { return func(in any) { @@ -104,6 +112,16 @@ func WithAttachment(a *Attachment) Option { } } +// WithXMPMetadata adds the XMP metadata to the conversion request. +func WithXMPMetadata() Option { + return func(o *options) { + o.xmpMetadata = &XMPMetadata{ + Data: loadXMP(), + Filename: "zugferd.xmp", + } + } +} + // Convertor defines the interface expected to be able to convert sources into PDF type Convertor interface { // HTML is the default implementation that takes a raw HTML file and converts it @@ -134,3 +152,11 @@ func prepareOptions(opts []Option) *options { } return o } + +func loadXMP() []byte { + data, err := os.ReadFile("assets/zugferd.xmp") + if err != nil { + panic(err) + } + return data +} diff --git a/pkg/pdf/prince.go b/pkg/pdf/prince.go index 61f0887..062e5be 100644 --- a/pkg/pdf/prince.go +++ b/pkg/pdf/prince.go @@ -62,5 +62,18 @@ func (pc *princeConvertor) HTML(_ context.Context, data []byte, opts ...Option) } } + if o.xmpMetadata != nil { + xmpFilename := "metadata.xmp" + j.Files[xmpFilename] = o.xmpMetadata.Data + if j.PDF == nil { + j.PDF = new(princepdf.PDF) + } + j.PDF.Attach = append(j.PDF.Attach, &princepdf.Attachment{ + URL: xmpFilename, + Filename: xmpFilename, + Description: "XMP Metadata File", + }) + } + return pc.client.Run(j) }