From da7011ee0910101d0d3c410e01b582ef0cfa831d Mon Sep 17 00:00:00 2001 From: apardods Date: Fri, 20 Dec 2024 10:45:29 +0000 Subject: [PATCH 01/13] WIP: Add XMP metadata to ZUGFeRD --- assets/zugferd.xmp | 57 ++++++++++++++++++++++++++++++++++++++++++++++ pkg/pdf/pdf.go | 26 +++++++++++++++++++++ pkg/pdf/prince.go | 13 +++++++++++ 3 files changed, 96 insertions(+) create mode 100644 assets/zugferd.xmp 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) } From c288bf7dfcb7bcc75b738e3d816849a5f266a584 Mon Sep 17 00:00:00 2001 From: apardods Date: Fri, 20 Dec 2024 11:12:10 +0000 Subject: [PATCH 02/13] Add Zugferd Opt --- goblhtml.go | 7 +++++++ internal/options.go | 2 ++ 2 files changed, 9 insertions(+) diff --git a/goblhtml.go b/goblhtml.go index 9f5f03b..5acfdda 100644 --- a/goblhtml.go +++ b/goblhtml.go @@ -92,6 +92,13 @@ func WithEmbeddedStylesheets() Option { } } +// WithZugferd adds the Zugferd XMP metadata to the HTML document. +func WithZugferd() Option { + return func(o *internal.Opts) { + o.Zugferd = true + } +} + // Render takes the GOBL envelope and attempts to render an HTML document // from it. func Render(ctx context.Context, env *gobl.Envelope, opts ...Option) ([]byte, error) { diff --git a/internal/options.go b/internal/options.go index 9ff6844..b7437c4 100644 --- a/internal/options.go +++ b/internal/options.go @@ -36,6 +36,8 @@ type Opts struct { // are contained inside the HTML output. This is useful for PDF // output or to avoid additional requests. EmbedStylesheets bool + // Zugferd when true, adds the Zugferd XMP metadata to the PDF. + Zugferd bool } // WithOptions prepares the context with the options to use. From 905792a51ba7888df36ff674454b729757edb94b Mon Sep 17 00:00:00 2001 From: apardods Date: Fri, 20 Dec 2024 12:45:53 +0000 Subject: [PATCH 03/13] Normalize opt name,add example --- cmd/gobl.html/convert.go | 2 + examples/invoice-de-zugferd.json | 179 +++++++++++++++++++++++++++ examples/out/invoice-de-zugferd.html | 152 +++++++++++++++++++++++ pkg/pdf/pdf.go | 4 +- pkg/pdf/prince.go | 1 + 5 files changed, 336 insertions(+), 2 deletions(-) create mode 100644 examples/invoice-de-zugferd.json create mode 100755 examples/out/invoice-de-zugferd.html diff --git a/cmd/gobl.html/convert.go b/cmd/gobl.html/convert.go index 07672c0..375face 100644 --- a/cmd/gobl.html/convert.go +++ b/cmd/gobl.html/convert.go @@ -12,6 +12,7 @@ import ( type convertOpts struct { *rootOpts + Zugferd bool } func convert(o *rootOpts) *convertOpts { @@ -24,6 +25,7 @@ func (c *convertOpts) cmd() *cobra.Command { Short: "Convert a GOBL JSON into an HTML file", RunE: c.runE, } + cmd.Flags().BoolVar(&c.Zugferd, "zugferd", false, "Add Zugferd XMP metadata to the PDF") return cmd } diff --git a/examples/invoice-de-zugferd.json b/examples/invoice-de-zugferd.json new file mode 100644 index 0000000..7381cbc --- /dev/null +++ b/examples/invoice-de-zugferd.json @@ -0,0 +1,179 @@ +{ + "$schema": "https://gobl.org/draft-0/envelope", + "head": { + "uuid": "8a51fd30-2a27-11ee-be56-0242ac120002", + "dig": { + "alg": "sha256", + "val": "583130bdfd84c31d23f7bcdf778363ffdbc7eb132faf1180efb1be1fc438e069" + } + }, + "doc": { + "$schema": "https://gobl.org/draft-0/bill/invoice", + "$regime": "DE", + "$addons": [ + "eu-en16931-v2017" + ], + "uuid": "019231f1-9128-71fc-b0e2-820af3036d1b", + "type": "standard", + "series": "SAMPLE", + "code": "001", + "issue_date": "2024-02-13", + "currency": "EUR", + "supplier": { + "name": "Provide One GmbH", + "tax_id": { + "country": "DE", + "code": "111111125" + }, + "people": [ + { + "name": { + "given": "John", + "surname": "Doe" + } + } + ], + "addresses": [ + { + "num": "16", + "street": "Dietmar-Hopp-Allee", + "locality": "Walldorf", + "code": "69190", + "country": "DE" + } + ], + "emails": [ + { + "addr": "billing@example.com" + } + ], + "telephones": [ + { + "num": "+49100200300" + } + ] + }, + "customer": { + "name": "Sample Consumer", + "tax_id": { + "country": "DE", + "code": "282741168" + }, + "addresses": [ + { + "num": "25", + "street": "Werner-Heisenberg-Allee", + "locality": "München", + "code": "80939", + "country": "DE" + } + ], + "emails": [ + { + "addr": "email@sample.com" + } + ] + }, + "lines": [ + { + "i": 1, + "quantity": "20", + "item": { + "name": "Development services", + "price": "90.00", + "unit": "h" + }, + "sum": "1800.00", + "taxes": [ + { + "cat": "VAT", + "rate": "standard", + "percent": "19%" + } + ], + "total": "1800.00" + } + ], + "ordering": { + "code": "XR-2024-2", + "seller": { + "name": "Salescompany ltd.", + "tax_id": { + "country": "NO", + "code": "123456789MVA" + }, + "identities": [ + { + "label": "CompanyID", + "code": "123456789" + }, + { + "label": "0088", + "code": "1238764941386" + } + ], + "people": [ + { + "name": { + "given": "Antonio Salesmacher" + } + } + ], + "addresses": [ + { + "street": "Main street 34", + "street_extra": "Suite 123", + "locality": "Big city", + "region": "RegionA", + "code": "303", + "country": "NO" + } + ], + "emails": [ + { + "addr": "antonio@salescompany.no" + } + ], + "telephones": [ + { + "num": "46211230" + } + ] + } + }, + "payment": { + "terms": { + "detail": "lorem ipsum" + } + }, + "tax": { + "ext": { + "untdid-document-type": "380" + } + }, + "totals": { + "sum": "1800.00", + "total": "1800.00", + "taxes": { + "categories": [ + { + "code": "VAT", + "rates": [ + { + "key": "standard", + "base": "1800.00", + "percent": "19%", + "amount": "342.00" + } + ], + "amount": "342.00" + } + ], + "sum": "342.00" + }, + "tax": "342.00", + "total_with_tax": "2142.00", + "payable": "2142.00" + } + } +} diff --git a/examples/out/invoice-de-zugferd.html b/examples/out/invoice-de-zugferd.html new file mode 100755 index 0000000..04230b0 --- /dev/null +++ b/examples/out/invoice-de-zugferd.html @@ -0,0 +1,152 @@ + + + GOBL HTML Generator + + + + + + + + + +
+
+ Page 1 of 1 + +
+
+
+
+
+
Provide One GmbH
+

Invoice

+

SAMPLE-001

+
+
+

Summary

+
    +
  • Issue Date 2024-02-13
  • +
  • Currency Euro (EUR)
  • +
  • Order XR-2024-2
  • +
+
+
+
+
+

Supplier

+
+
Provide One GmbH
+
John Doe
+
Dietmar-Hopp-Allee 16, Walldorf, 69190 (Germany)
+
Tel: +49100200300
+
Email: billing@example.com
+
TIN: (DE) 111111125
+
+
+
+

Customer

+
+
Sample Consumer
+
Werner-Heisenberg-Allee 25, München, 80939 (Germany)
+
Email: email@sample.com
+
TIN: (DE) 282741168
+
+
+
+
+
+

Lines

+ + + + + + + + + + + + + + + + + + + + + + + +
#DescriptionQty.UnitPriceVATTotal
1Development services20h€90,0019%€1.800,00
+
+
+
+

Totals

+ + + + + + + + + + + + + + + +
Sum€1.800,00
Tax€342,00
Total to pay€2.142,00
+
+
+

Taxes

+ + + + + + + + + + + + + + + + + +
TaxBaseRateAmount
VAT€1.800,0019%€342,00
+
+
+
+

Payment

+
    +
    +
    +
    + +
    + + diff --git a/pkg/pdf/pdf.go b/pkg/pdf/pdf.go index 482acc6..13f80d2 100644 --- a/pkg/pdf/pdf.go +++ b/pkg/pdf/pdf.go @@ -112,8 +112,8 @@ func WithAttachment(a *Attachment) Option { } } -// WithXMPMetadata adds the XMP metadata to the conversion request. -func WithXMPMetadata() Option { +// WithZugferd adds the Zugferd XMP metadata to the conversion request. +func WithZugferd() Option { return func(o *options) { o.xmpMetadata = &XMPMetadata{ Data: loadXMP(), diff --git a/pkg/pdf/prince.go b/pkg/pdf/prince.go index 062e5be..5786433 100644 --- a/pkg/pdf/prince.go +++ b/pkg/pdf/prince.go @@ -68,6 +68,7 @@ func (pc *princeConvertor) HTML(_ context.Context, data []byte, opts ...Option) if j.PDF == nil { j.PDF = new(princepdf.PDF) } + j.PDF.PDFXMP = xmpFilename j.PDF.Attach = append(j.PDF.Attach, &princepdf.Attachment{ URL: xmpFilename, Filename: xmpFilename, From 3cee6a3b415c2b600009bbd5850defaca56eef28 Mon Sep 17 00:00:00 2001 From: apardods Date: Fri, 20 Dec 2024 13:06:53 +0000 Subject: [PATCH 04/13] fix tests --- cmd/gobl.html/convert.go | 2 +- examples/out/invoice-de-zugferd.html | 268 ++++++++++++++++++++------- pkg/pdf/pdf.go | 1 + 3 files changed, 201 insertions(+), 70 deletions(-) diff --git a/cmd/gobl.html/convert.go b/cmd/gobl.html/convert.go index 375face..d585310 100644 --- a/cmd/gobl.html/convert.go +++ b/cmd/gobl.html/convert.go @@ -52,7 +52,7 @@ func (c *convertOpts) runE(cmd *cobra.Command, args []string) error { return err } - data, err := goblhtml.Render(cmd.Context(), env) + data, err := goblhtml.Render(cmd.Context(), env, goblhtml.WithZugferd()) if err != nil { return fmt.Errorf("generating html: %w", err) } diff --git a/examples/out/invoice-de-zugferd.html b/examples/out/invoice-de-zugferd.html index 04230b0..0f5090b 100755 --- a/examples/out/invoice-de-zugferd.html +++ b/examples/out/invoice-de-zugferd.html @@ -1,24 +1,32 @@ - GOBL HTML Generator - - - - - - - + + GOBL HTML Generator + + + + + + + +
    - Page 1 of 1 + + Page + + 1 + + of + + 1 + +
    @@ -26,113 +34,238 @@
    -
    Provide One GmbH
    -

    Invoice

    -

    SAMPLE-001

    +
    +
    + Provide One GmbH +
    +
    +

    + Invoice +

    +

    + SAMPLE-001 +

    -

    Summary

    +

    + Summary +

      -
    • Issue Date 2024-02-13
    • -
    • Currency Euro (EUR)
    • -
    • Order XR-2024-2
    • +
    • + + Issue Date + + + 2024-02-13 + +
    • +
    • + + Currency + + + Euro (EUR) + +
    • +
    • + + Order + + + XR-2024-2 + +
    -

    Supplier

    +

    + Supplier +

    -
    Provide One GmbH
    -
    John Doe
    -
    Dietmar-Hopp-Allee 16, Walldorf, 69190 (Germany)
    -
    Tel: +49100200300
    -
    Email: billing@example.com
    -
    TIN: (DE) 111111125
    +
    + Provide One GmbH +
    +
    + John Doe +
    +
    + + Dietmar-Hopp-Allee 16, Walldorf, 69190 (Germany) + +
    +
    + Tel: +49100200300 +
    +
    + Email: billing@example.com +
    +
    + TIN: (DE) 111111125 +
    -

    Customer

    +

    + Customer +

    -
    Sample Consumer
    -
    Werner-Heisenberg-Allee 25, München, 80939 (Germany)
    -
    Email: email@sample.com
    -
    TIN: (DE) 282741168
    +
    + Sample Consumer +
    +
    + + Werner-Heisenberg-Allee 25, München, 80939 (Germany) + +
    +
    + Email: email@sample.com +
    +
    + TIN: (DE) 282741168 +
    -

    Lines

    +

    + Lines +

    - - - - - - - + + + + + + + - - - - - - - + + + + + + +
    #DescriptionQty.UnitPriceVATTotal + # + + Description + + Qty. + + Unit + + Price + + VAT + + Total +
    1Development services20h€90,0019%€1.800,00 + 1 + + + Development services + + + 20 + + h + + €90,00 + + 19% + + €1.800,00 +
    -

    Totals

    +

    + Totals +

    - - + + - - + + - - + +
    Sum€1.800,00 + Sum + + €1.800,00 +
    Tax€342,00 + Tax + + €342,00 +
    Total to pay€2.142,00 + Total to pay + + €2.142,00 +
    -

    Taxes

    +

    + Taxes +

    - - - - + + + + - - - - + + + +
    TaxBaseRateAmount + Tax + + Base + + Rate + + Amount +
    VAT€1.800,0019%€342,00 + VAT + + €1.800,00 + + 19% + + €342,00 +
    -

    Payment

    +

    + Payment +

      @@ -140,13 +273,10 @@

      Payment

      - + \ No newline at end of file diff --git a/pkg/pdf/pdf.go b/pkg/pdf/pdf.go index 13f80d2..d4ecfbf 100644 --- a/pkg/pdf/pdf.go +++ b/pkg/pdf/pdf.go @@ -158,5 +158,6 @@ func loadXMP() []byte { if err != nil { panic(err) } + fmt.Println(string(data)) return data } From 7b016451a2e6ba49b46d0ec3253370d60fadd4e1 Mon Sep 17 00:00:00 2001 From: apardods Date: Mon, 23 Dec 2024 13:48:15 +0000 Subject: [PATCH 05/13] Use go embed and remove attachment --- {assets => pkg/pdf/assets}/zugferd.xmp | 0 pkg/pdf/pdf.go | 12 +++++------- pkg/pdf/prince.go | 10 +++++----- 3 files changed, 10 insertions(+), 12 deletions(-) rename {assets => pkg/pdf/assets}/zugferd.xmp (100%) diff --git a/assets/zugferd.xmp b/pkg/pdf/assets/zugferd.xmp similarity index 100% rename from assets/zugferd.xmp rename to pkg/pdf/assets/zugferd.xmp diff --git a/pkg/pdf/pdf.go b/pkg/pdf/pdf.go index d4ecfbf..920a3c0 100644 --- a/pkg/pdf/pdf.go +++ b/pkg/pdf/pdf.go @@ -4,9 +4,9 @@ package pdf import ( "context" + _ "embed" "fmt" "io/fs" - "os" "path/filepath" ) @@ -57,6 +57,9 @@ type XMPMetadata struct { Filename string } +//go:embed assets/zugferd.xmp +var zugferdXMPData []byte + // WithURL sets the URL to use for the connection to a remote server if needed. func WithURL(url string) Config { return func(in any) { @@ -154,10 +157,5 @@ func prepareOptions(opts []Option) *options { } func loadXMP() []byte { - data, err := os.ReadFile("assets/zugferd.xmp") - if err != nil { - panic(err) - } - fmt.Println(string(data)) - return data + return zugferdXMPData } diff --git a/pkg/pdf/prince.go b/pkg/pdf/prince.go index 5786433..d5b66ee 100644 --- a/pkg/pdf/prince.go +++ b/pkg/pdf/prince.go @@ -69,11 +69,11 @@ func (pc *princeConvertor) HTML(_ context.Context, data []byte, opts ...Option) j.PDF = new(princepdf.PDF) } j.PDF.PDFXMP = xmpFilename - j.PDF.Attach = append(j.PDF.Attach, &princepdf.Attachment{ - URL: xmpFilename, - Filename: xmpFilename, - Description: "XMP Metadata File", - }) + // j.PDF.Attach = append(j.PDF.Attach, &princepdf.Attachment{ + // URL: xmpFilename, + // Filename: xmpFilename, + // Description: "XMP Metadata File", + // }) } return pc.client.Run(j) From 340d7edeaa3c8a43baafb790eea096337f2447dc Mon Sep 17 00:00:00 2001 From: apardods Date: Tue, 7 Jan 2025 11:07:19 +0000 Subject: [PATCH 06/13] Added logs --- pkg/pdf/pdf.go | 1 + pkg/pdf/prince.go | 3 +++ 2 files changed, 4 insertions(+) diff --git a/pkg/pdf/pdf.go b/pkg/pdf/pdf.go index 920a3c0..67bcf57 100644 --- a/pkg/pdf/pdf.go +++ b/pkg/pdf/pdf.go @@ -157,5 +157,6 @@ func prepareOptions(opts []Option) *options { } func loadXMP() []byte { + fmt.Printf("loading XMP metadata: %d bytes\n", len(zugferdXMPData)) return zugferdXMPData } diff --git a/pkg/pdf/prince.go b/pkg/pdf/prince.go index d5b66ee..7098d6d 100644 --- a/pkg/pdf/prince.go +++ b/pkg/pdf/prince.go @@ -2,6 +2,7 @@ package pdf import ( "context" + "fmt" "github.com/invopop/princepdf" ) @@ -63,6 +64,8 @@ func (pc *princeConvertor) HTML(_ context.Context, data []byte, opts ...Option) } if o.xmpMetadata != nil { + fmt.Printf("adding XMP metadata to PDF: %d bytes\n", len(o.xmpMetadata.Data)) + xmpFilename := "metadata.xmp" j.Files[xmpFilename] = o.xmpMetadata.Data if j.PDF == nil { From 08a9b94638ef2bb3ea18dc59dbc12feb21b17e6f Mon Sep 17 00:00:00 2001 From: apardods Date: Tue, 7 Jan 2025 11:24:34 +0000 Subject: [PATCH 07/13] Add logs --- go.mod | 1 + go.sum | 7 +++++++ pkg/pdf/pdf.go | 4 +++- pkg/pdf/prince.go | 4 ++-- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index be66145..2643b87 100644 --- a/go.mod +++ b/go.mod @@ -38,6 +38,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/rs/zerolog v1.33.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect diff --git a/go.sum b/go.sum index 92e9f9a..d09d10a 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,7 @@ github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPn github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -17,6 +18,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-resty/resty/v2 v2.12.0 h1:rsVL8P90LFvkUYq/V5BTVe203WfRIU4gvcf+yfzJzGA= github.com/go-resty/resty/v2 v2.12.0/go.mod h1:o0yGPrkS3lOe1+eFajk6kBW8ScXzwU3hD69/gt2yB/0= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -54,6 +56,7 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/piglig/go-qr v0.2.4 h1:G/fY3/Oq0NI1oc0lEhBv75QXUtIW/FmcL9l8D1jIo1M= @@ -64,6 +67,9 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.12.1-0.20240709150035-ccf4b4329d21 h1:igWZJluD8KtEtAgRyF4x6lqcxDry1ULztksMJh2mnQE= github.com/rogpeppe/go-internal v1.12.1-0.20240709150035-ccf4b4329d21/go.mod h1:RMRJLmBOqWacUkmJHRMiPKh1S1m3PA7Zh4W80/kWPpg= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= @@ -119,6 +125,7 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= diff --git a/pkg/pdf/pdf.go b/pkg/pdf/pdf.go index 67bcf57..dfaec84 100644 --- a/pkg/pdf/pdf.go +++ b/pkg/pdf/pdf.go @@ -8,6 +8,8 @@ import ( "fmt" "io/fs" "path/filepath" + + "github.com/rs/zerolog/log" ) // Config defines options used to configure the PDF convertor. @@ -157,6 +159,6 @@ func prepareOptions(opts []Option) *options { } func loadXMP() []byte { - fmt.Printf("loading XMP metadata: %d bytes\n", len(zugferdXMPData)) + log.Info().Msg("loading XMP metadata loadxmp()") return zugferdXMPData } diff --git a/pkg/pdf/prince.go b/pkg/pdf/prince.go index 7098d6d..1b61763 100644 --- a/pkg/pdf/prince.go +++ b/pkg/pdf/prince.go @@ -2,9 +2,9 @@ package pdf import ( "context" - "fmt" "github.com/invopop/princepdf" + "github.com/rs/zerolog/log" ) // The princeConvertor is by far the best option for converting HTML to PDF for GOBL documents. @@ -64,7 +64,7 @@ func (pc *princeConvertor) HTML(_ context.Context, data []byte, opts ...Option) } if o.xmpMetadata != nil { - fmt.Printf("adding XMP metadata to PDF: %d bytes\n", len(o.xmpMetadata.Data)) + log.Info().Msg("adding XMP metadata to PDF") xmpFilename := "metadata.xmp" j.Files[xmpFilename] = o.xmpMetadata.Data From d567b2b62e3c379848513c8799fd480d18edc6d9 Mon Sep 17 00:00:00 2001 From: apardods Date: Wed, 8 Jan 2025 11:31:31 +0000 Subject: [PATCH 08/13] Add XMP to HTML instead of PDF --- components/envelope.templ | 2 + components/envelope_templ.go | 7 +- components/regimes/de/assets/zugferd.xmp | 57 +++++++++ components/regimes/de/de.go | 3 + components/regimes/de/zugferd.templ | 141 ++++++++++++++++++++++ components/regimes/de/zugferd_templ.go | 143 +++++++++++++++++++++++ pkg/pdf/pdf.go | 32 +++-- pkg/pdf/prince.go | 30 ++--- 8 files changed, 384 insertions(+), 31 deletions(-) create mode 100644 components/regimes/de/assets/zugferd.xmp create mode 100644 components/regimes/de/de.go create mode 100644 components/regimes/de/zugferd.templ create mode 100644 components/regimes/de/zugferd_templ.go diff --git a/components/envelope.templ b/components/envelope.templ index 8004adc..e19491c 100644 --- a/components/envelope.templ +++ b/components/envelope.templ @@ -14,6 +14,7 @@ import ( "github.com/invopop/gobl.html/components/org" "github.com/invopop/gobl.html/assets" "github.com/invopop/gobl.html/internal" + "github.com/invopop/gobl.html/components/regimes/de" ) templ Envelope(env *gobl.Envelope) { @@ -26,6 +27,7 @@ templ Envelope(env *gobl.Envelope) { @stylesheets() + @de.ZugferdMetadata(env)
      diff --git a/components/envelope_templ.go b/components/envelope_templ.go index c35d594..ebf7726 100644 --- a/components/envelope_templ.go +++ b/components/envelope_templ.go @@ -18,6 +18,7 @@ import ( "github.com/invopop/gobl.html/components/bill/invoice" "github.com/invopop/gobl.html/components/notes" "github.com/invopop/gobl.html/components/org" + "github.com/invopop/gobl.html/components/regimes/de" "github.com/invopop/gobl.html/internal" "github.com/invopop/gobl/bill" "github.com/invopop/gobl/note" @@ -53,6 +54,10 @@ func Envelope(env *gobl.Envelope) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } + templ_7745c5c3_Err = de.ZugferdMetadata(env).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
      ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err @@ -133,7 +138,7 @@ func stylesheets() templ.Component { var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(ss) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/envelope.templ`, Line: 58, Col: 36} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/envelope.templ`, Line: 60, Col: 36} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { diff --git a/components/regimes/de/assets/zugferd.xmp b/components/regimes/de/assets/zugferd.xmp new file mode 100644 index 0000000..6fdc072 --- /dev/null +++ b/components/regimes/de/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/components/regimes/de/de.go b/components/regimes/de/de.go new file mode 100644 index 0000000..1928dce --- /dev/null +++ b/components/regimes/de/de.go @@ -0,0 +1,3 @@ +// Package de provides additional templates and helper methods +// for the German tax regime. +package de diff --git a/components/regimes/de/zugferd.templ b/components/regimes/de/zugferd.templ new file mode 100644 index 0000000..890be05 --- /dev/null +++ b/components/regimes/de/zugferd.templ @@ -0,0 +1,141 @@ +package de + +import ( + "github.com/invopop/gobl" + "github.com/invopop/gobl/bill" + "github.com/invopop/gobl/l10n" +) + +// ZugferdMetadata adds the Zugferd metadata to the envelope. +templ ZugferdMetadata(env *gobl.Envelope) { + if inv, ok := env.Extract().(*bill.Invoice); ok { + if inv.Regime.Country == l10n.DE.Tax() { + if xmp := getXMP(); xmp != "" { + @generateXMPMetadata(xmp) + } + } + } +} + +templ generateXMPMetadata(xmp string) { + +} + +func getXMP() string { + // Load the XMP metadata template from the assets file + return ` + + + + + + + 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/components/regimes/de/zugferd_templ.go b/components/regimes/de/zugferd_templ.go new file mode 100644 index 0000000..aa7593d --- /dev/null +++ b/components/regimes/de/zugferd_templ.go @@ -0,0 +1,143 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.793 +package de + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import ( + "github.com/invopop/gobl" + "github.com/invopop/gobl/bill" + "github.com/invopop/gobl/l10n" +) + +// ZugferdMetadata adds the Zugferd metadata to the envelope. +func ZugferdMetadata(env *gobl.Envelope) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + if inv, ok := env.Extract().(*bill.Invoice); ok { + if inv.Regime.Country == l10n.DE.Tax() { + if xmp := getXMP(); xmp != "" { + templ_7745c5c3_Err = generateXMPMetadata(xmp).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + } + } + return templ_7745c5c3_Err + }) +} + +func generateXMPMetadata(xmp string) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var2 := templ.GetChildren(ctx) + if templ_7745c5c3_Var2 == nil { + templ_7745c5c3_Var2 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func getXMP() string { + // Load the XMP metadata template from the assets file + return ` + + + + + + + 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 + + + + + + + + + + +` +} + +var _ = templruntime.GeneratedTemplate diff --git a/pkg/pdf/pdf.go b/pkg/pdf/pdf.go index dfaec84..4e71685 100644 --- a/pkg/pdf/pdf.go +++ b/pkg/pdf/pdf.go @@ -7,9 +7,10 @@ import ( _ "embed" "fmt" "io/fs" - "path/filepath" - "github.com/rs/zerolog/log" + // "os" + "path/filepath" + // "github.com/rs/zerolog/log" ) // Config defines options used to configure the PDF convertor. @@ -27,7 +28,7 @@ type options struct { metadata *Metadata styles []*Stylesheet attachments []*Attachment - xmpMetadata *XMPMetadata + xmpMetadata bool } // Metadata contains additional information to add to the PDF @@ -54,13 +55,12 @@ type Attachment struct { } // XMPMetadata is used to add XMP metadata to the PDF. -type XMPMetadata struct { - Data []byte - Filename string -} +// type XMPMetadata struct { +// Data []byte +// } -//go:embed assets/zugferd.xmp -var zugferdXMPData []byte +// //go:embed assets/zugferd.xmp +// var zugferdXMPData []byte // WithURL sets the URL to use for the connection to a remote server if needed. func WithURL(url string) Config { @@ -120,10 +120,7 @@ func WithAttachment(a *Attachment) Option { // WithZugferd adds the Zugferd XMP metadata to the conversion request. func WithZugferd() Option { return func(o *options) { - o.xmpMetadata = &XMPMetadata{ - Data: loadXMP(), - Filename: "zugferd.xmp", - } + o.xmpMetadata = true } } @@ -158,7 +155,8 @@ func prepareOptions(opts []Option) *options { return o } -func loadXMP() []byte { - log.Info().Msg("loading XMP metadata loadxmp()") - return zugferdXMPData -} +// func loadXMP() []byte { +// log.Info().Msg("loading XMP metadata loadxmp()") +// fmt.Fprintf(os.Stderr, "loading XMP()") +// return zugferdXMPData +// } diff --git a/pkg/pdf/prince.go b/pkg/pdf/prince.go index 1b61763..3506719 100644 --- a/pkg/pdf/prince.go +++ b/pkg/pdf/prince.go @@ -2,9 +2,10 @@ package pdf import ( "context" + "fmt" + "os" "github.com/invopop/princepdf" - "github.com/rs/zerolog/log" ) // The princeConvertor is by far the best option for converting HTML to PDF for GOBL documents. @@ -63,20 +64,23 @@ func (pc *princeConvertor) HTML(_ context.Context, data []byte, opts ...Option) } } - if o.xmpMetadata != nil { - log.Info().Msg("adding XMP metadata to PDF") + if o.xmpMetadata { + fmt.Fprintf(os.Stderr, "adding XMP metadata to PDF\n") + j.Input.Javascript = true - xmpFilename := "metadata.xmp" - j.Files[xmpFilename] = o.xmpMetadata.Data - if j.PDF == nil { - j.PDF = new(princepdf.PDF) + // xmpFilename := "metadata.xmp" + // j.Files[xmpFilename] = o.xmpMetadata.Data + // if j.PDF == nil { + // j.PDF = new(princepdf.PDF) + // } + // j.PDF.PDFXMP = xmpFilename + + // Add visible marker in metadata + if j.Metadata == nil { + j.Metadata = &princepdf.Metadata{} } - j.PDF.PDFXMP = xmpFilename - // j.PDF.Attach = append(j.PDF.Attach, &princepdf.Attachment{ - // URL: xmpFilename, - // Filename: xmpFilename, - // Description: "XMP Metadata File", - // }) + j.Metadata.Creator = "GOBL with ZUGFeRD/Factur-X" + j.Metadata.Keywords = "ZUGFeRD enabled, XMP metadata added" } return pc.client.Run(j) From 6acc31242ec93143436b4b3486a15ef9350d112c Mon Sep 17 00:00:00 2001 From: apardods Date: Wed, 8 Jan 2025 11:44:25 +0000 Subject: [PATCH 09/13] Update to GOBL 0.208 --- go.mod | 21 ++++++++++----------- go.sum | 51 ++++++++++++++++++++++----------------------------- 2 files changed, 32 insertions(+), 40 deletions(-) diff --git a/go.mod b/go.mod index 2643b87..9668c6d 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/a-h/templ v0.2.793 github.com/go-resty/resty/v2 v2.12.0 github.com/invopop/ctxi18n v0.9.0 - github.com/invopop/gobl v0.207.0 + github.com/invopop/gobl v0.208.0 github.com/invopop/princepdf v0.0.0-20240408123340-585be3cab91a github.com/labstack/echo/v4 v4.12.0 github.com/piglig/go-qr v0.2.4 @@ -19,35 +19,34 @@ require ( ) require ( - cloud.google.com/go v0.110.2 // indirect - github.com/Masterminds/semver/v3 v3.2.1 // indirect + cloud.google.com/go v0.118.0 // indirect + github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/google/uuid v1.6.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/invopop/jsonschema v0.12.0 // indirect - github.com/invopop/validation v0.7.0 // indirect + github.com/invopop/jsonschema v0.13.0 // indirect + github.com/invopop/validation v0.8.0 // indirect github.com/invopop/yaml v0.3.1 // indirect github.com/joho/godotenv v1.5.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/labstack/gommon v0.4.2 // indirect github.com/magefile/mage v1.15.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/rs/zerolog v1.33.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect - golang.org/x/crypto v0.26.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/crypto v0.32.0 // indirect + golang.org/x/net v0.33.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index d09d10a..34855a8 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ -cloud.google.com/go v0.110.2 h1:sdFPBr6xG9/wkBbfhmUz/JmZC7X6LavQgcrVINrKiVA= -cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw= -github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= -github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +cloud.google.com/go v0.118.0 h1:tvZe1mgqRxpiVa3XlIGMiPcEUbP1gNXELgD4y/IXmeQ= +cloud.google.com/go v0.118.0/go.mod h1:zIt2pkedt/mo+DQjcT4/L3NDxzHPR29j5HcclNH+9PM= +github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= +github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/a-h/templ v0.2.793 h1:Io+/ocnfGWYO4VHdR0zBbf39PQlnzVCVVD+wEEs6/qY= github.com/a-h/templ v0.2.793/go.mod h1:lq48JXoUvuQrU0VThrK31yFwdRjTCnIE5bcPCM9IP1w= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= @@ -10,7 +10,6 @@ github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPn github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -18,7 +17,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-resty/resty/v2 v2.12.0 h1:rsVL8P90LFvkUYq/V5BTVe203WfRIU4gvcf+yfzJzGA= github.com/go-resty/resty/v2 v2.12.0/go.mod h1:o0yGPrkS3lOe1+eFajk6kBW8ScXzwU3hD69/gt2yB/0= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -28,19 +26,18 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/invopop/ctxi18n v0.9.0 h1:BIia4u4OngaHVn/7gvK0w6lccOXVtad8xU0KgJ+mnVA= github.com/invopop/ctxi18n v0.9.0/go.mod h1:1Osw+JGYA+anHt0Z4reF36r5FtGHYjGQ+m1X7keIhPc= -github.com/invopop/gobl v0.207.0 h1:Gv6aUYKLdwuAw9HOhkk8eUztsYXPbPy6e/DBoBUDXmI= -github.com/invopop/gobl v0.207.0/go.mod h1:DmPohPel8b3ta4nDKnXRNzWQlB89cN74e0/WwPUEZUU= -github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= -github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= +github.com/invopop/gobl v0.208.0 h1:qy5GHXELMy7qBtvgLL8m4d/aBgBaxq0bdAaae4a2luE= +github.com/invopop/gobl v0.208.0/go.mod h1:DmPohPel8b3ta4nDKnXRNzWQlB89cN74e0/WwPUEZUU= +github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= +github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/invopop/princepdf v0.0.0-20240408123340-585be3cab91a h1:xt18LlIfizLkFgLi+vK/m2SWOsAbQwVwQgbkzxKY0eU= github.com/invopop/princepdf v0.0.0-20240408123340-585be3cab91a/go.mod h1:iYAJLConbhJ67An65H7Ei/o/ZGDvIQfyLA5JhxMQ1qY= -github.com/invopop/validation v0.7.0 h1:NBPLqvYGmLZLQuk5jh0PbaBBetJW7f2VEk/BTWJkGBU= -github.com/invopop/validation v0.7.0/go.mod h1:nLLeXYPGwUNfdCdJo7/q3yaHO62LSx/3ri7JvgKR9vg= +github.com/invopop/validation v0.8.0 h1:e5hXHGnONHImgJdonIpNbctg1hlWy1ncaHoVIQ0JWuw= +github.com/invopop/validation v0.8.0/go.mod h1:nLLeXYPGwUNfdCdJo7/q3yaHO62LSx/3ri7JvgKR9vg= github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -51,12 +48,11 @@ github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0 github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg= github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/piglig/go-qr v0.2.4 h1:G/fY3/Oq0NI1oc0lEhBv75QXUtIW/FmcL9l8D1jIo1M= @@ -67,9 +63,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.12.1-0.20240709150035-ccf4b4329d21 h1:igWZJluD8KtEtAgRyF4x6lqcxDry1ULztksMJh2mnQE= github.com/rogpeppe/go-internal v1.12.1-0.20240709150035-ccf4b4329d21/go.mod h1:RMRJLmBOqWacUkmJHRMiPKh1S1m3PA7Zh4W80/kWPpg= -github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= -github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= @@ -98,8 +91,8 @@ golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -110,8 +103,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -125,11 +118,10 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -142,10 +134,11 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= +golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= From 0c05cfd17f99d517013bd7fcfc4ee36059697d25 Mon Sep 17 00:00:00 2001 From: apardods Date: Wed, 8 Jan 2025 11:47:57 +0000 Subject: [PATCH 10/13] Update templ note --- components/bill/invoice/notes.templ | 3 +-- components/bill/invoice/notes_templ.go | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/components/bill/invoice/notes.templ b/components/bill/invoice/notes.templ index 0d15c0e..36182ff 100644 --- a/components/bill/invoice/notes.templ +++ b/components/bill/invoice/notes.templ @@ -8,7 +8,6 @@ import ( "github.com/invopop/ctxi18n/i18n" "github.com/invopop/gobl.html/components/t" "github.com/invopop/gobl/bill" - "github.com/invopop/gobl/cbc" "github.com/invopop/gobl/org" "github.com/yuin/goldmark" "github.com/yuin/goldmark/extension" @@ -107,7 +106,7 @@ templ noteRegSummary(reg *org.Registration) { } -func renderNote(note *cbc.Note) string { +func renderNote(note *org.Note) string { txt := note.Text if note.Code != "" { txt = fmt.Sprintf("`%s` · %s", note.Code, txt) diff --git a/components/bill/invoice/notes_templ.go b/components/bill/invoice/notes_templ.go index 9cb714a..6dac135 100644 --- a/components/bill/invoice/notes_templ.go +++ b/components/bill/invoice/notes_templ.go @@ -16,7 +16,6 @@ import ( "github.com/invopop/ctxi18n/i18n" "github.com/invopop/gobl.html/components/t" "github.com/invopop/gobl/bill" - "github.com/invopop/gobl/cbc" "github.com/invopop/gobl/org" "github.com/yuin/goldmark" "github.com/yuin/goldmark/extension" @@ -204,7 +203,7 @@ func noteRegSummary(reg *org.Registration) templ.Component { var templ_7745c5c3_Var5 string templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(reg.Office) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/bill/invoice/notes.templ`, Line: 68, Col: 17} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/bill/invoice/notes.templ`, Line: 67, Col: 17} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { @@ -335,7 +334,7 @@ func noteRegSummary(reg *org.Registration) templ.Component { var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(reg.Other) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/bill/invoice/notes.templ`, Line: 103, Col: 16} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/bill/invoice/notes.templ`, Line: 102, Col: 16} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { @@ -360,7 +359,7 @@ func noteRegSummary(reg *org.Registration) templ.Component { }) } -func renderNote(note *cbc.Note) string { +func renderNote(note *org.Note) string { txt := note.Text if note.Code != "" { txt = fmt.Sprintf("`%s` · %s", note.Code, txt) From 9d1bbe54fcf78df04eedf54a1121c93ce0b6043e Mon Sep 17 00:00:00 2001 From: apardods Date: Wed, 8 Jan 2025 13:54:59 +0000 Subject: [PATCH 11/13] Formatting --- components/regimes/de/assets/zugferd.xmp | 57 ------------------- components/regimes/de/zugferd.templ | 67 +--------------------- components/regimes/de/zugferd_templ.go | 71 ++---------------------- pkg/pdf/pdf.go | 2 +- 4 files changed, 7 insertions(+), 190 deletions(-) delete mode 100644 components/regimes/de/assets/zugferd.xmp diff --git a/components/regimes/de/assets/zugferd.xmp b/components/regimes/de/assets/zugferd.xmp deleted file mode 100644 index 6fdc072..0000000 --- a/components/regimes/de/assets/zugferd.xmp +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - 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/components/regimes/de/zugferd.templ b/components/regimes/de/zugferd.templ index 890be05..624ee77 100644 --- a/components/regimes/de/zugferd.templ +++ b/components/regimes/de/zugferd.templ @@ -10,14 +10,12 @@ import ( templ ZugferdMetadata(env *gobl.Envelope) { if inv, ok := env.Extract().(*bill.Invoice); ok { if inv.Regime.Country == l10n.DE.Tax() { - if xmp := getXMP(); xmp != "" { - @generateXMPMetadata(xmp) - } + @generateXMPMetadata() } } } -templ generateXMPMetadata(xmp string) { +templ generateXMPMetadata() { } - -func getXMP() string { - // Load the XMP metadata template from the assets file - return ` - - - - - - - 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/components/regimes/de/zugferd_templ.go b/components/regimes/de/zugferd_templ.go index aa7593d..89d89e6 100644 --- a/components/regimes/de/zugferd_templ.go +++ b/components/regimes/de/zugferd_templ.go @@ -38,11 +38,9 @@ func ZugferdMetadata(env *gobl.Envelope) templ.Component { ctx = templ.ClearChildren(ctx) if inv, ok := env.Extract().(*bill.Invoice); ok { if inv.Regime.Country == l10n.DE.Tax() { - if xmp := getXMP(); xmp != "" { - templ_7745c5c3_Err = generateXMPMetadata(xmp).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } + templ_7745c5c3_Err = generateXMPMetadata().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err } } } @@ -50,7 +48,7 @@ func ZugferdMetadata(env *gobl.Envelope) templ.Component { }) } -func generateXMPMetadata(xmp string) templ.Component { +func generateXMPMetadata() templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -79,65 +77,4 @@ func generateXMPMetadata(xmp string) templ.Component { }) } -func getXMP() string { - // Load the XMP metadata template from the assets file - return ` - - - - - - - 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 - - - - - - - - - - -` -} - var _ = templruntime.GeneratedTemplate diff --git a/pkg/pdf/pdf.go b/pkg/pdf/pdf.go index 4e71685..c980709 100644 --- a/pkg/pdf/pdf.go +++ b/pkg/pdf/pdf.go @@ -4,7 +4,7 @@ package pdf import ( "context" - _ "embed" + // _ "embed" "fmt" "io/fs" From 2487185b1dc6cfb669d94333606749b1b80f05f3 Mon Sep 17 00:00:00 2001 From: apardods Date: Wed, 8 Jan 2025 14:08:19 +0000 Subject: [PATCH 12/13] Add log metadata --- components/regimes/de/zugferd.templ | 1 + components/regimes/de/zugferd_templ.go | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/components/regimes/de/zugferd.templ b/components/regimes/de/zugferd.templ index 624ee77..e69c074 100644 --- a/components/regimes/de/zugferd.templ +++ b/components/regimes/de/zugferd.templ @@ -11,6 +11,7 @@ templ ZugferdMetadata(env *gobl.Envelope) { if inv, ok := env.Extract().(*bill.Invoice); ok { if inv.Regime.Country == l10n.DE.Tax() { @generateXMPMetadata() + } } } diff --git a/components/regimes/de/zugferd_templ.go b/components/regimes/de/zugferd_templ.go index 89d89e6..6fadbd5 100644 --- a/components/regimes/de/zugferd_templ.go +++ b/components/regimes/de/zugferd_templ.go @@ -42,6 +42,10 @@ func ZugferdMetadata(env *gobl.Envelope) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } } } return templ_7745c5c3_Err From e36275b906de2f88d40cb6b58e18aa5937758743 Mon Sep 17 00:00:00 2001 From: apardods Date: Wed, 8 Jan 2025 16:40:06 +0000 Subject: [PATCH 13/13] Comment everything out --- cmd/gobl.html/convert.go | 6 +- components/envelope.templ | 4 +- components/envelope_templ.go | 6 +- components/regimes/de/zugferd.templ | 79 ------------------------ components/regimes/de/zugferd_templ.go | 84 -------------------------- pkg/pdf/assets/zugferd.xmp | 57 ----------------- pkg/pdf/pdf.go | 12 ++-- pkg/pdf/prince.go | 36 +++++------ 8 files changed, 30 insertions(+), 254 deletions(-) delete mode 100644 components/regimes/de/zugferd.templ delete mode 100644 components/regimes/de/zugferd_templ.go delete mode 100644 pkg/pdf/assets/zugferd.xmp diff --git a/cmd/gobl.html/convert.go b/cmd/gobl.html/convert.go index d585310..ef280d0 100644 --- a/cmd/gobl.html/convert.go +++ b/cmd/gobl.html/convert.go @@ -12,7 +12,7 @@ import ( type convertOpts struct { *rootOpts - Zugferd bool + // Zugferd bool } func convert(o *rootOpts) *convertOpts { @@ -25,7 +25,7 @@ func (c *convertOpts) cmd() *cobra.Command { Short: "Convert a GOBL JSON into an HTML file", RunE: c.runE, } - cmd.Flags().BoolVar(&c.Zugferd, "zugferd", false, "Add Zugferd XMP metadata to the PDF") + // cmd.Flags().BoolVar(&c.Zugferd, "zugferd", false, "Add Zugferd XMP metadata to the PDF") return cmd } @@ -52,7 +52,7 @@ func (c *convertOpts) runE(cmd *cobra.Command, args []string) error { return err } - data, err := goblhtml.Render(cmd.Context(), env, goblhtml.WithZugferd()) + data, err := goblhtml.Render(cmd.Context(), env) //, goblhtml.WithZugferd()) if err != nil { return fmt.Errorf("generating html: %w", err) } diff --git a/components/envelope.templ b/components/envelope.templ index e19491c..91a333f 100644 --- a/components/envelope.templ +++ b/components/envelope.templ @@ -14,7 +14,7 @@ import ( "github.com/invopop/gobl.html/components/org" "github.com/invopop/gobl.html/assets" "github.com/invopop/gobl.html/internal" - "github.com/invopop/gobl.html/components/regimes/de" + // "github.com/invopop/gobl.html/components/regimes/de" ) templ Envelope(env *gobl.Envelope) { @@ -27,7 +27,7 @@ templ Envelope(env *gobl.Envelope) { @stylesheets() - @de.ZugferdMetadata(env) + // @de.ZugferdMetadata(env)
      diff --git a/components/envelope_templ.go b/components/envelope_templ.go index ebf7726..7c00b8f 100644 --- a/components/envelope_templ.go +++ b/components/envelope_templ.go @@ -18,11 +18,11 @@ import ( "github.com/invopop/gobl.html/components/bill/invoice" "github.com/invopop/gobl.html/components/notes" "github.com/invopop/gobl.html/components/org" - "github.com/invopop/gobl.html/components/regimes/de" "github.com/invopop/gobl.html/internal" "github.com/invopop/gobl/bill" "github.com/invopop/gobl/note" gorg "github.com/invopop/gobl/org" + // "github.com/invopop/gobl.html/components/regimes/de" ) func Envelope(env *gobl.Envelope) templ.Component { @@ -54,10 +54,6 @@ func Envelope(env *gobl.Envelope) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = de.ZugferdMetadata(env).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
      ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err diff --git a/components/regimes/de/zugferd.templ b/components/regimes/de/zugferd.templ deleted file mode 100644 index e69c074..0000000 --- a/components/regimes/de/zugferd.templ +++ /dev/null @@ -1,79 +0,0 @@ -package de - -import ( - "github.com/invopop/gobl" - "github.com/invopop/gobl/bill" - "github.com/invopop/gobl/l10n" -) - -// ZugferdMetadata adds the Zugferd metadata to the envelope. -templ ZugferdMetadata(env *gobl.Envelope) { - if inv, ok := env.Extract().(*bill.Invoice); ok { - if inv.Regime.Country == l10n.DE.Tax() { - @generateXMPMetadata() - - } - } -} - -templ generateXMPMetadata() { - -} diff --git a/components/regimes/de/zugferd_templ.go b/components/regimes/de/zugferd_templ.go deleted file mode 100644 index 6fadbd5..0000000 --- a/components/regimes/de/zugferd_templ.go +++ /dev/null @@ -1,84 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.2.793 -package de - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -import ( - "github.com/invopop/gobl" - "github.com/invopop/gobl/bill" - "github.com/invopop/gobl/l10n" -) - -// ZugferdMetadata adds the Zugferd metadata to the envelope. -func ZugferdMetadata(env *gobl.Envelope) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - if inv, ok := env.Extract().(*bill.Invoice); ok { - if inv.Regime.Country == l10n.DE.Tax() { - templ_7745c5c3_Err = generateXMPMetadata().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - } - return templ_7745c5c3_Err - }) -} - -func generateXMPMetadata() templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var2 := templ.GetChildren(ctx) - if templ_7745c5c3_Var2 == nil { - templ_7745c5c3_Var2 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return templ_7745c5c3_Err - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/pkg/pdf/assets/zugferd.xmp b/pkg/pdf/assets/zugferd.xmp deleted file mode 100644 index 6fdc072..0000000 --- a/pkg/pdf/assets/zugferd.xmp +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - 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 c980709..2f4c3e8 100644 --- a/pkg/pdf/pdf.go +++ b/pkg/pdf/pdf.go @@ -28,7 +28,7 @@ type options struct { metadata *Metadata styles []*Stylesheet attachments []*Attachment - xmpMetadata bool + // xmpMetadata bool } // Metadata contains additional information to add to the PDF @@ -118,11 +118,11 @@ func WithAttachment(a *Attachment) Option { } // WithZugferd adds the Zugferd XMP metadata to the conversion request. -func WithZugferd() Option { - return func(o *options) { - o.xmpMetadata = true - } -} +// func WithZugferd() Option { +// return func(o *options) { +// o.xmpMetadata = true +// } +// } // Convertor defines the interface expected to be able to convert sources into PDF type Convertor interface { diff --git a/pkg/pdf/prince.go b/pkg/pdf/prince.go index 3506719..16848a9 100644 --- a/pkg/pdf/prince.go +++ b/pkg/pdf/prince.go @@ -2,8 +2,8 @@ package pdf import ( "context" - "fmt" - "os" + // "fmt" + // "os" "github.com/invopop/princepdf" ) @@ -64,24 +64,24 @@ func (pc *princeConvertor) HTML(_ context.Context, data []byte, opts ...Option) } } - if o.xmpMetadata { - fmt.Fprintf(os.Stderr, "adding XMP metadata to PDF\n") - j.Input.Javascript = true + // if o.xmpMetadata { + // fmt.Fprintf(os.Stderr, "adding XMP metadata to PDF\n") + // j.Input.Javascript = true - // xmpFilename := "metadata.xmp" - // j.Files[xmpFilename] = o.xmpMetadata.Data - // if j.PDF == nil { - // j.PDF = new(princepdf.PDF) - // } - // j.PDF.PDFXMP = xmpFilename + // // xmpFilename := "metadata.xmp" + // // j.Files[xmpFilename] = o.xmpMetadata.Data + // // if j.PDF == nil { + // // j.PDF = new(princepdf.PDF) + // // } + // // j.PDF.PDFXMP = xmpFilename - // Add visible marker in metadata - if j.Metadata == nil { - j.Metadata = &princepdf.Metadata{} - } - j.Metadata.Creator = "GOBL with ZUGFeRD/Factur-X" - j.Metadata.Keywords = "ZUGFeRD enabled, XMP metadata added" - } + // // Add visible marker in metadata + // if j.Metadata == nil { + // j.Metadata = &princepdf.Metadata{} + // } + // j.Metadata.Creator = "GOBL with ZUGFeRD/Factur-X" + // j.Metadata.Keywords = "ZUGFeRD enabled, XMP metadata added" + // } return pc.client.Run(j) }