From dc94abeed9881ebe1e5af199f2241af72b353521 Mon Sep 17 00:00:00 2001 From: apardods Date: Wed, 4 Dec 2024 08:43:43 +0000 Subject: [PATCH 01/16] Added check for en16931 addon --- internal/gtou/gtou.go | 6 ++++++ test/data/gtou/correction-invoice.json | 3 +++ test/data/gtou/credit-note.json | 3 +++ test/data/gtou/invoice-complete.json | 3 +++ test/data/gtou/invoice-de-de.json | 3 +++ test/data/gtou/invoice-minimal.json | 3 +++ test/data/gtou/invoice-without-buyers-tax-id.json | 3 +++ test/data/gtou/self-billed-invoice.json | 3 +++ 8 files changed, 27 insertions(+) diff --git a/internal/gtou/gtou.go b/internal/gtou/gtou.go index 7b547aa..c95827b 100644 --- a/internal/gtou/gtou.go +++ b/internal/gtou/gtou.go @@ -3,9 +3,11 @@ package gtou import ( "fmt" + "slices" "github.com/invopop/gobl" "github.com/invopop/gobl.ubl/document" + "github.com/invopop/gobl/addons/eu/en16931" "github.com/invopop/gobl/bill" "github.com/invopop/gobl/cal" "github.com/invopop/gobl/catalogues/untdid" @@ -36,6 +38,10 @@ func Convert(env *gobl.Envelope) (*document.Invoice, error) { func (c *Converter) newDocument(inv *bill.Invoice) error { + if !slices.Contains(inv.GetAddons(), en16931.V2017) { + return fmt.Errorf("invoice must contain EN16931 addon") + } + // Create the UBL document c.doc = &document.Invoice{ CACNamespace: document.CAC, diff --git a/test/data/gtou/correction-invoice.json b/test/data/gtou/correction-invoice.json index d922720..ec73771 100644 --- a/test/data/gtou/correction-invoice.json +++ b/test/data/gtou/correction-invoice.json @@ -10,6 +10,9 @@ "doc": { "$schema": "https://gobl.org/draft-0/bill/invoice", "$regime": "DE", + "$addons": [ + "eu-en16931-v2017" + ], "uuid": "019231f1-90f1-7101-ae31-2df13f03971a", "type": "corrective", "series": "COR", diff --git a/test/data/gtou/credit-note.json b/test/data/gtou/credit-note.json index dac62dc..2aad710 100644 --- a/test/data/gtou/credit-note.json +++ b/test/data/gtou/credit-note.json @@ -10,6 +10,9 @@ "doc": { "$schema": "https://gobl.org/draft-0/bill/invoice", "$regime": "DE", + "$addons": [ + "eu-en16931-v2017" + ], "uuid": "019231f1-910c-73d9-9493-a58fdccf14e9", "type": "credit-note", "series": "CN", diff --git a/test/data/gtou/invoice-complete.json b/test/data/gtou/invoice-complete.json index 75aa047..7b347b5 100644 --- a/test/data/gtou/invoice-complete.json +++ b/test/data/gtou/invoice-complete.json @@ -10,6 +10,9 @@ "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", diff --git a/test/data/gtou/invoice-de-de.json b/test/data/gtou/invoice-de-de.json index c9cd0c6..fb76316 100644 --- a/test/data/gtou/invoice-de-de.json +++ b/test/data/gtou/invoice-de-de.json @@ -10,6 +10,9 @@ "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", diff --git a/test/data/gtou/invoice-minimal.json b/test/data/gtou/invoice-minimal.json index 8707462..8df06cc 100644 --- a/test/data/gtou/invoice-minimal.json +++ b/test/data/gtou/invoice-minimal.json @@ -10,6 +10,9 @@ "doc": { "$schema": "https://gobl.org/draft-0/bill/invoice", "$regime": "DE", + "$addons": [ + "eu-en16931-v2017" + ], "uuid": "018f7cec-556a-72d7-8959-b6de406b87ab", "type": "standard", "series": "SAMPLE", diff --git a/test/data/gtou/invoice-without-buyers-tax-id.json b/test/data/gtou/invoice-without-buyers-tax-id.json index 0304e50..2adff78 100644 --- a/test/data/gtou/invoice-without-buyers-tax-id.json +++ b/test/data/gtou/invoice-without-buyers-tax-id.json @@ -10,6 +10,9 @@ "doc": { "$schema": "https://gobl.org/draft-0/bill/invoice", "$regime": "DE", + "$addons": [ + "eu-en16931-v2017" + ], "uuid": "019231f1-9168-70de-b1c8-9ea4d7294ef2", "type": "standard", "series": "SAMPLE", diff --git a/test/data/gtou/self-billed-invoice.json b/test/data/gtou/self-billed-invoice.json index 1724827..7155181 100644 --- a/test/data/gtou/self-billed-invoice.json +++ b/test/data/gtou/self-billed-invoice.json @@ -10,6 +10,9 @@ "doc": { "$schema": "https://gobl.org/draft-0/bill/invoice", "$regime": "DE", + "$addons": [ + "eu-en16931-v2017" + ], "$tags": [ "self-billed" ], From 4138a64155df70ecf6c9fa7c6054a0788ffdfab8 Mon Sep 17 00:00:00 2001 From: apardods Date: Wed, 4 Dec 2024 09:17:00 +0000 Subject: [PATCH 02/16] Check for extensions instead of addon --- internal/gtou/gtou.go | 18 ++++++++++++------ internal/gtou/lines.go | 3 +++ internal/gtou/payment.go | 5 +++++ test/data/gtou/invoice-complete.json | 5 ++++- test/data/gtou/out/invoice-complete.xml | 2 +- 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/internal/gtou/gtou.go b/internal/gtou/gtou.go index c95827b..8b2535b 100644 --- a/internal/gtou/gtou.go +++ b/internal/gtou/gtou.go @@ -3,11 +3,9 @@ package gtou import ( "fmt" - "slices" "github.com/invopop/gobl" "github.com/invopop/gobl.ubl/document" - "github.com/invopop/gobl/addons/eu/en16931" "github.com/invopop/gobl/bill" "github.com/invopop/gobl/cal" "github.com/invopop/gobl/catalogues/untdid" @@ -38,8 +36,9 @@ func Convert(env *gobl.Envelope) (*document.Invoice, error) { func (c *Converter) newDocument(inv *bill.Invoice) error { - if !slices.Contains(inv.GetAddons(), en16931.V2017) { - return fmt.Errorf("invoice must contain EN16931 addon") + tc, err := getTypeCode(inv) + if err != nil { + return err } // Create the UBL document @@ -55,7 +54,7 @@ func (c *Converter) newDocument(inv *bill.Invoice) error { CustomizationID: document.CustomizationID, ID: invoiceNumber(inv.Series, inv.Code), IssueDate: formatDate(inv.IssueDate), - InvoiceTypeCode: inv.Tax.Ext[untdid.ExtKeyDocumentType].String(), + InvoiceTypeCode: tc, DocumentCurrencyCode: string(inv.Currency), AccountingSupplierParty: document.SupplierParty{Party: c.newParty(inv.Supplier)}, AccountingCustomerParty: document.CustomerParty{Party: c.newParty(inv.Customer)}, @@ -68,7 +67,7 @@ func (c *Converter) newDocument(inv *bill.Invoice) error { } } - err := c.newOrdering(inv.Ordering) + err = c.newOrdering(inv.Ordering) if err != nil { return err } @@ -101,6 +100,13 @@ func (c *Converter) newDocument(inv *bill.Invoice) error { return nil } +func getTypeCode(inv *bill.Invoice) (string, error) { + if inv.Tax == nil || inv.Tax.Ext == nil || inv.Tax.Ext[untdid.ExtKeyDocumentType].String() == "" { + return "", fmt.Errorf("invoice must contain tax extensions") + } + return inv.Tax.Ext[untdid.ExtKeyDocumentType].String(), nil +} + func invoiceNumber(series cbc.Code, code cbc.Code) string { if series == "" { return code.String() diff --git a/internal/gtou/lines.go b/internal/gtou/lines.go index 306ae62..d93b900 100644 --- a/internal/gtou/lines.go +++ b/internal/gtou/lines.go @@ -102,6 +102,9 @@ func (c *Converter) newLines(inv *bill.Invoice) error { if len(l.Item.Identities) > 0 { for _, id := range l.Item.Identities { + if id.Ext == nil || id.Ext[iso.ExtKeySchemeID].String() == "" { + continue + } s := id.Ext[iso.ExtKeySchemeID].String() it.StandardItemIdentification = &document.ItemIdentification{ ID: &document.IDType{ diff --git a/internal/gtou/payment.go b/internal/gtou/payment.go index d241181..46eebe4 100644 --- a/internal/gtou/payment.go +++ b/internal/gtou/payment.go @@ -1,6 +1,8 @@ package gtou import ( + "fmt" + "github.com/invopop/gobl.ubl/document" "github.com/invopop/gobl/bill" "github.com/invopop/gobl/catalogues/untdid" @@ -12,6 +14,9 @@ func (c *Converter) newPayment(pymt *bill.Payment) error { } if pymt.Instructions != nil { ref := pymt.Instructions.Ref.String() + if pymt.Instructions.Ext == nil || pymt.Instructions.Ext[untdid.ExtKeyPaymentMeans].String() == "" { + return fmt.Errorf("payment must contain payment means extension") + } c.doc.PaymentMeans = []document.PaymentMeans{ { PaymentMeansCode: document.IDType{Value: pymt.Instructions.Ext[untdid.ExtKeyPaymentMeans].String()}, diff --git a/test/data/gtou/invoice-complete.json b/test/data/gtou/invoice-complete.json index 7b347b5..c45303f 100644 --- a/test/data/gtou/invoice-complete.json +++ b/test/data/gtou/invoice-complete.json @@ -180,7 +180,10 @@ "iban": "NO9386011117947", "bic": "DNBANOKK" } - ] + ], + "ext": { + "untdid-payment-means": "30" + } } }, "delivery": { diff --git a/test/data/gtou/out/invoice-complete.xml b/test/data/gtou/out/invoice-complete.xml index e59b32d..b737a9b 100755 --- a/test/data/gtou/out/invoice-complete.xml +++ b/test/data/gtou/out/invoice-complete.xml @@ -94,7 +94,7 @@ - + 30 0003434323213231 NO9386011117947 From ee21ef8d4e28059c0820d86a3290b70e13d068d8 Mon Sep 17 00:00:00 2001 From: apardods Date: Wed, 4 Dec 2024 09:23:10 +0000 Subject: [PATCH 03/16] Error Messages --- internal/gtou/gtou.go | 2 +- internal/gtou/payment.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/gtou/gtou.go b/internal/gtou/gtou.go index 8b2535b..0200dbb 100644 --- a/internal/gtou/gtou.go +++ b/internal/gtou/gtou.go @@ -102,7 +102,7 @@ func (c *Converter) newDocument(inv *bill.Invoice) error { func getTypeCode(inv *bill.Invoice) (string, error) { if inv.Tax == nil || inv.Tax.Ext == nil || inv.Tax.Ext[untdid.ExtKeyDocumentType].String() == "" { - return "", fmt.Errorf("invoice must contain tax extensions") + return "", fmt.Errorf("validation: invoice must contain document type extension, added automatically with the EN16931 addon") } return inv.Tax.Ext[untdid.ExtKeyDocumentType].String(), nil } diff --git a/internal/gtou/payment.go b/internal/gtou/payment.go index 46eebe4..98d4ea2 100644 --- a/internal/gtou/payment.go +++ b/internal/gtou/payment.go @@ -15,7 +15,7 @@ func (c *Converter) newPayment(pymt *bill.Payment) error { if pymt.Instructions != nil { ref := pymt.Instructions.Ref.String() if pymt.Instructions.Ext == nil || pymt.Instructions.Ext[untdid.ExtKeyPaymentMeans].String() == "" { - return fmt.Errorf("payment must contain payment means extension") + return fmt.Errorf("validation: payment must contain payment means extension, added automatically with the EN16931 addon") } c.doc.PaymentMeans = []document.PaymentMeans{ { From a9839b4884fc0ed9df4d11ff7aaea18009ce3bc3 Mon Sep 17 00:00:00 2001 From: apardods Date: Wed, 4 Dec 2024 10:18:23 +0000 Subject: [PATCH 04/16] Added tests and improved errors --- internal/gtou/gtou.go | 10 ++++- internal/gtou/gtou_test.go | 60 ++++++++++++++++++++++++++ internal/gtou/payment.go | 11 ++++- internal/gtou/payment_test.go | 14 +++++- test/data/gtou/invoice-minimal.json | 15 +++++++ test/data/gtou/out/invoice-minimal.xml | 10 +++++ 6 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 internal/gtou/gtou_test.go diff --git a/internal/gtou/gtou.go b/internal/gtou/gtou.go index 0200dbb..a72a91a 100644 --- a/internal/gtou/gtou.go +++ b/internal/gtou/gtou.go @@ -2,6 +2,7 @@ package gtou import ( + "errors" "fmt" "github.com/invopop/gobl" @@ -10,6 +11,7 @@ import ( "github.com/invopop/gobl/cal" "github.com/invopop/gobl/catalogues/untdid" "github.com/invopop/gobl/cbc" + "github.com/invopop/validation" ) // Converter is a struct that contains the necessary elements to convert between GOBL and UBL @@ -102,7 +104,13 @@ func (c *Converter) newDocument(inv *bill.Invoice) error { func getTypeCode(inv *bill.Invoice) (string, error) { if inv.Tax == nil || inv.Tax.Ext == nil || inv.Tax.Ext[untdid.ExtKeyDocumentType].String() == "" { - return "", fmt.Errorf("validation: invoice must contain document type extension, added automatically with the EN16931 addon") + return "", validation.Errors{ + "tax": validation.Errors{ + "ext": validation.Errors{ + untdid.ExtKeyDocumentType.String(): errors.New("required"), + }, + }, + } } return inv.Tax.Ext[untdid.ExtKeyDocumentType].String(), nil } diff --git a/internal/gtou/gtou_test.go b/internal/gtou/gtou_test.go new file mode 100644 index 0000000..d15ac0d --- /dev/null +++ b/internal/gtou/gtou_test.go @@ -0,0 +1,60 @@ +package gtou + +import ( + "testing" + + "github.com/invopop/gobl/bill" + "github.com/invopop/gobl/tax" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestInvoiceHeaders(t *testing.T) { + t.Run("document type extension", func(t *testing.T) { + env, err := loadTestEnvelope("invoice-de-de.json") + require.NoError(t, err) + + inv, ok := env.Extract().(*bill.Invoice) + assert.True(t, ok) + + code, err := getTypeCode(inv) + assert.NoError(t, err) + assert.Equal(t, "380", code) + + inv.Tax = nil + _, err = getTypeCode(inv) + assert.ErrorContains(t, err, "tax: (ext: (untdid-document-type: required.).).") + + inv.Tax = &bill.Tax{ + Ext: tax.Extensions{}, + } + _, err = getTypeCode(inv) + assert.ErrorContains(t, err, "ext: (untdid-document-type: required.).") + }) + + t.Run("format date", func(t *testing.T) { + env, err := loadTestEnvelope("invoice-de-de.json") + require.NoError(t, err) + + inv, ok := env.Extract().(*bill.Invoice) + assert.True(t, ok) + + date := formatDate(inv.IssueDate) + assert.Equal(t, "2024-02-13", date) + }) + + t.Run("invoice number", func(t *testing.T) { + env, err := loadTestEnvelope("invoice-de-de.json") + require.NoError(t, err) + + inv, ok := env.Extract().(*bill.Invoice) + assert.True(t, ok) + + number := invoiceNumber(inv.Series, inv.Code) + assert.Equal(t, "SAMPLE-001", number) + + inv.Series = "" + number = invoiceNumber(inv.Series, inv.Code) + assert.Equal(t, "001", number) + }) +} diff --git a/internal/gtou/payment.go b/internal/gtou/payment.go index 98d4ea2..967e591 100644 --- a/internal/gtou/payment.go +++ b/internal/gtou/payment.go @@ -1,11 +1,12 @@ package gtou import ( - "fmt" + "errors" "github.com/invopop/gobl.ubl/document" "github.com/invopop/gobl/bill" "github.com/invopop/gobl/catalogues/untdid" + "github.com/invopop/validation" ) func (c *Converter) newPayment(pymt *bill.Payment) error { @@ -15,7 +16,13 @@ func (c *Converter) newPayment(pymt *bill.Payment) error { if pymt.Instructions != nil { ref := pymt.Instructions.Ref.String() if pymt.Instructions.Ext == nil || pymt.Instructions.Ext[untdid.ExtKeyPaymentMeans].String() == "" { - return fmt.Errorf("validation: payment must contain payment means extension, added automatically with the EN16931 addon") + return validation.Errors{ + "instructions": validation.Errors{ + "ext": validation.Errors{ + untdid.ExtKeyPaymentMeans.String(): errors.New("required"), + }, + }, + } } c.doc.PaymentMeans = []document.PaymentMeans{ { diff --git a/internal/gtou/payment_test.go b/internal/gtou/payment_test.go index a650fea..991f4b3 100644 --- a/internal/gtou/payment_test.go +++ b/internal/gtou/payment_test.go @@ -3,6 +3,7 @@ package gtou import ( "testing" + "github.com/invopop/gobl/bill" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -20,7 +21,18 @@ func TestNewPayment(t *testing.T) { assert.NotEmpty(t, doc.PaymentMeans[0].PayeeFinancialAccount) assert.Equal(t, "NO9386011117947", *doc.PaymentMeans[0].PayeeFinancialAccount.ID) assert.Equal(t, "DNBANOKK", *doc.PaymentMeans[0].PayeeFinancialAccount.FinancialInstitutionBranch.ID) - }) + t.Run("document type extension", func(t *testing.T) { + env, err := loadTestEnvelope("invoice-minimal.json") + require.NoError(t, err) + + inv, ok := env.Extract().(*bill.Invoice) + assert.True(t, ok) + + inv.Payment.Instructions.Ext = nil + + _, err = Convert(env) + assert.ErrorContains(t, err, "instructions: (ext: (untdid-payment-means: required.).).") + }) } diff --git a/test/data/gtou/invoice-minimal.json b/test/data/gtou/invoice-minimal.json index 8df06cc..8a64c4f 100644 --- a/test/data/gtou/invoice-minimal.json +++ b/test/data/gtou/invoice-minimal.json @@ -85,6 +85,21 @@ "untdid-document-type": "380" } }, + "payment": { + "instructions": { + "key": "credit-transfer", + "ref": "0003434323213231", + "credit_transfer": [ + { + "iban": "NO9386011117947", + "bic": "DNBANOKK" + } + ], + "ext": { + "untdid-payment-means": "30" + } + } + }, "totals": { "sum": "1800.00", "total": "1800.00", diff --git a/test/data/gtou/out/invoice-minimal.xml b/test/data/gtou/out/invoice-minimal.xml index a3cb719..6c18dab 100755 --- a/test/data/gtou/out/invoice-minimal.xml +++ b/test/data/gtou/out/invoice-minimal.xml @@ -53,6 +53,16 @@ + + 30 + 0003434323213231 + + NO9386011117947 + + DNBANOKK + + + 342.00 From bdcde572bfe1c095936b3d66298d241dd08e058d Mon Sep 17 00:00:00 2001 From: apardods Date: Wed, 4 Dec 2024 10:20:04 +0000 Subject: [PATCH 05/16] Removed addon in some examples --- test/data/gtou/correction-invoice.json | 3 --- test/data/gtou/credit-note.json | 3 --- test/data/gtou/invoice-without-buyers-tax-id.json | 3 --- 3 files changed, 9 deletions(-) diff --git a/test/data/gtou/correction-invoice.json b/test/data/gtou/correction-invoice.json index ec73771..d922720 100644 --- a/test/data/gtou/correction-invoice.json +++ b/test/data/gtou/correction-invoice.json @@ -10,9 +10,6 @@ "doc": { "$schema": "https://gobl.org/draft-0/bill/invoice", "$regime": "DE", - "$addons": [ - "eu-en16931-v2017" - ], "uuid": "019231f1-90f1-7101-ae31-2df13f03971a", "type": "corrective", "series": "COR", diff --git a/test/data/gtou/credit-note.json b/test/data/gtou/credit-note.json index 2aad710..dac62dc 100644 --- a/test/data/gtou/credit-note.json +++ b/test/data/gtou/credit-note.json @@ -10,9 +10,6 @@ "doc": { "$schema": "https://gobl.org/draft-0/bill/invoice", "$regime": "DE", - "$addons": [ - "eu-en16931-v2017" - ], "uuid": "019231f1-910c-73d9-9493-a58fdccf14e9", "type": "credit-note", "series": "CN", diff --git a/test/data/gtou/invoice-without-buyers-tax-id.json b/test/data/gtou/invoice-without-buyers-tax-id.json index 2adff78..0304e50 100644 --- a/test/data/gtou/invoice-without-buyers-tax-id.json +++ b/test/data/gtou/invoice-without-buyers-tax-id.json @@ -10,9 +10,6 @@ "doc": { "$schema": "https://gobl.org/draft-0/bill/invoice", "$regime": "DE", - "$addons": [ - "eu-en16931-v2017" - ], "uuid": "019231f1-9168-70de-b1c8-9ea4d7294ef2", "type": "standard", "series": "SAMPLE", From 313278a9fde50325f1ed69bb4cadbceac04a1dbf Mon Sep 17 00:00:00 2001 From: apardods Date: Wed, 4 Dec 2024 10:25:36 +0000 Subject: [PATCH 06/16] Removed unnecessary test helper function --- internal/gtou/test.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/internal/gtou/test.go b/internal/gtou/test.go index 2bf8de1..467467a 100644 --- a/internal/gtou/test.go +++ b/internal/gtou/test.go @@ -35,15 +35,6 @@ func loadTestEnvelope(name string) (*gobl.Envelope, error) { return env, nil } -// NewDocumentFrom creates a UBL from a GOBL file in the `test/data` folder -func NewDocumentFrom(name string) (*document.Invoice, error) { - env, err := loadTestEnvelope(name) - if err != nil { - return nil, err - } - return Convert(env) -} - func getTestDataPath() string { return filepath.Join(getRootFolder(), "test", "data", "gtou") } From 6ccfc0b007ab2d4a9094df0ccade6c7a4a5b1ae8 Mon Sep 17 00:00:00 2001 From: apardods Date: Wed, 4 Dec 2024 10:26:53 +0000 Subject: [PATCH 07/16] update go.mod --- go.mod | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/go.mod b/go.mod index c393d19..9e0951d 100644 --- a/go.mod +++ b/go.mod @@ -7,13 +7,13 @@ toolchain go1.22.1 require ( github.com/invopop/gobl v0.205.1 github.com/joho/godotenv v1.5.1 - // github.com/lestrrat-go/libxml2 v0.0.0-20240521004304-a75c203ac627 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 gitlab.com/flimzy/testy v0.14.0 ) require ( + github.com/invopop/validation v0.8.0 github.com/lestrrat-go/libxml2 v0.0.0-20240905100032-c934e3fcb9d3 github.com/nbio/xml v0.0.0-20241028124227-eac89c735a80 ) @@ -28,7 +28,6 @@ require ( 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.8.0 // indirect github.com/invopop/yaml v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/magefile/mage v1.15.0 // indirect From 4b9ffb14f8f9782417336d7cf6076b57b7d20896 Mon Sep 17 00:00:00 2001 From: apardods Date: Thu, 5 Dec 2024 14:24:15 +0000 Subject: [PATCH 08/16] Update Extensions --- .github/workflows/codeql.yml | 92 ---------------------------------- .github/workflows/release.yaml | 51 +++++++++++++++++++ .github/workflows/test.yaml | 27 ++++++++++ go.mod | 6 +-- go.sum | 6 +++ internal/gtou/charges.go | 14 +++--- internal/gtou/gtou.go | 2 +- internal/gtou/payment.go | 4 +- 8 files changed, 97 insertions(+), 105 deletions(-) delete mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/release.yaml create mode 100644 .github/workflows/test.yaml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index ea9e7b9..0000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,92 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL Advanced" - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - schedule: - - cron: '17 3 * * 2' - -jobs: - analyze: - name: Analyze (${{ matrix.language }}) - # Runner size impacts CodeQL analysis time. To learn more, please see: - # - https://gh.io/recommended-hardware-resources-for-running-codeql - # - https://gh.io/supported-runners-and-hardware-resources - # - https://gh.io/using-larger-runners (GitHub.com only) - # Consider using larger runners or machines with greater resources for possible analysis time improvements. - runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} - permissions: - # required for all workflows - security-events: write - - # required to fetch internal or private CodeQL packs - packages: read - - # only required for workflows in private repositories - actions: read - contents: read - - strategy: - fail-fast: false - matrix: - include: - - language: go - build-mode: autobuild - # CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' - # Use `c-cpp` to analyze code written in C, C++ or both - # Use 'java-kotlin' to analyze code written in Java, Kotlin or both - # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both - # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, - # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. - # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how - # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - build-mode: ${{ matrix.build-mode }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - # If the analyze step fails for one of the languages you are analyzing with - # "We were unable to automatically build your code", modify the matrix above - # to set the build mode to "manual" for that language. Then modify this step - # to build your code. - # ℹī¸ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - if: matrix.build-mode == 'manual' - shell: bash - run: | - echo 'If you are using a "manual" build mode for one or more of the' \ - 'languages you are analyzing, replace this with the commands to build' \ - 'your code, for example:' - echo ' make bootstrap' - echo ' make release' - exit 1 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - with: - category: "/language:${{matrix.language}}" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..3ccfc8a --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,51 @@ +# +# Automatically tag a merge with master and release it +# + +name: Release + +on: + push: + branches: + - main + tags: + - "*" + +jobs: + tag-release: + name: Tag and Release + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: "0" # make sure we get all commits! + + - name: Get repo details + run: | + echo "COMMIT_TYPE=$(echo $GITHUB_REF | cut -d / -f 2)" >> $GITHUB_ENV + echo "REPO_NAME=$(echo $GITHUB_REPOSITORY | cut -d / -f 2-)" >> $GITHUB_ENV + echo "REPO_VERSION=$(echo $GITHUB_REF | cut -d / -f 3-)" >> $GITHUB_ENV + + - name: Bump version and push tag + id: bump + if: env.COMMIT_TYPE != 'tags' + uses: anothrNick/github-tag-action@1.52.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + RELEASE_BRANCHES: main + WITH_V: true + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version-file: "go.mod" + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v6 + with: + distribution: goreleaser + version: latest + args: release --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..10a4e38 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,27 @@ +name: Test Go +on: [push] +jobs: + lint-test-build: + name: Test, Build + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version-file: "go.mod" + id: go + + - name: Install Dependencies + env: + GOPROXY: https://proxy.golang.org,direct + run: go mod download + + - name: Test + run: go test -tags unit -race ./... + + - name: Build + run: go build -v ./... diff --git a/go.mod b/go.mod index 9e0951d..7183774 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22 toolchain go1.22.1 require ( - github.com/invopop/gobl v0.205.1 + github.com/invopop/gobl v0.206.2-0.20241205110633-34e317a013d9 github.com/joho/godotenv v1.5.1 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 @@ -20,7 +20,7 @@ require ( require ( cloud.google.com/go v0.116.0 // indirect - github.com/Masterminds/semver/v3 v3.3.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 @@ -37,6 +37,6 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect - golang.org/x/crypto v0.29.0 // indirect + golang.org/x/crypto v0.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 2e42c7a..7e6fad1 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE= cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U= github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +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/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= @@ -22,6 +24,8 @@ 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/gobl v0.205.1 h1:khW63/Hu2lzU+IpRN2RF71cfUttCizL0HHAmeakWHyE= github.com/invopop/gobl v0.205.1/go.mod h1:DmPohPel8b3ta4nDKnXRNzWQlB89cN74e0/WwPUEZUU= +github.com/invopop/gobl v0.206.2-0.20241205110633-34e317a013d9 h1:VIIyZspyf68JHHHQ6uk5Z2AufYPzkqCz1gF4WGRh32g= +github.com/invopop/gobl v0.206.2-0.20241205110633-34e317a013d9/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/validation v0.8.0 h1:e5hXHGnONHImgJdonIpNbctg1hlWy1ncaHoVIQ0JWuw= @@ -80,6 +84,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= diff --git a/internal/gtou/charges.go b/internal/gtou/charges.go index 96f1248..1ed763b 100644 --- a/internal/gtou/charges.go +++ b/internal/gtou/charges.go @@ -32,8 +32,8 @@ func makeCharge(ch *bill.Charge, ccy string) document.AllowanceCharge { if ch.Reason != "" { c.AllowanceChargeReason = &ch.Reason } - if ch.Ext != nil && ch.Ext[untdid.ExtKeyCharge].String() != "" { - e := ch.Ext[untdid.ExtKeyCharge].String() + e := ch.Ext.Get(untdid.ExtKeyCharge).String() + if e != "" { c.AllowanceChargeReasonCode = &e } if ch.Percent != nil { @@ -58,8 +58,8 @@ func makeDiscount(d *bill.Discount, ccy string) document.AllowanceCharge { if d.Reason != "" { c.AllowanceChargeReason = &d.Reason } - if d.Ext != nil && d.Ext[untdid.ExtKeyAllowance].String() != "" { - e := d.Ext[untdid.ExtKeyAllowance].String() + e := d.Ext.Get(untdid.ExtKeyAllowance).String() + if e != "" { c.AllowanceChargeReasonCode = &e } if d.Percent != nil { @@ -82,9 +82,9 @@ func makeTaxCategory(taxes tax.Set) []*document.TaxCategory { p := t.Percent.StringWithoutSymbol() category.Percent = &p } - if t.Ext != nil && t.Ext[untdid.ExtKeyTaxCategory].String() != "" { - r := t.Ext[untdid.ExtKeyTaxCategory].String() - category.ID = &r + e := t.Ext.Get(untdid.ExtKeyTaxCategory).String() + if e != "" { + category.ID = &e } set = append(set, &category) } diff --git a/internal/gtou/gtou.go b/internal/gtou/gtou.go index a72a91a..96c7a73 100644 --- a/internal/gtou/gtou.go +++ b/internal/gtou/gtou.go @@ -112,7 +112,7 @@ func getTypeCode(inv *bill.Invoice) (string, error) { }, } } - return inv.Tax.Ext[untdid.ExtKeyDocumentType].String(), nil + return inv.Tax.Ext.Get(untdid.ExtKeyDocumentType).String(), nil } func invoiceNumber(series cbc.Code, code cbc.Code) string { diff --git a/internal/gtou/payment.go b/internal/gtou/payment.go index 967e591..874720f 100644 --- a/internal/gtou/payment.go +++ b/internal/gtou/payment.go @@ -15,7 +15,7 @@ func (c *Converter) newPayment(pymt *bill.Payment) error { } if pymt.Instructions != nil { ref := pymt.Instructions.Ref.String() - if pymt.Instructions.Ext == nil || pymt.Instructions.Ext[untdid.ExtKeyPaymentMeans].String() == "" { + if pymt.Instructions.Ext == nil || pymt.Instructions.Ext.Get(untdid.ExtKeyPaymentMeans).String() == "" { return validation.Errors{ "instructions": validation.Errors{ "ext": validation.Errors{ @@ -26,7 +26,7 @@ func (c *Converter) newPayment(pymt *bill.Payment) error { } c.doc.PaymentMeans = []document.PaymentMeans{ { - PaymentMeansCode: document.IDType{Value: pymt.Instructions.Ext[untdid.ExtKeyPaymentMeans].String()}, + PaymentMeansCode: document.IDType{Value: pymt.Instructions.Ext.Get(untdid.ExtKeyPaymentMeans).String()}, PaymentID: &ref, }, } From 27d3eab29917363154eac4fefa690055f814a12e Mon Sep 17 00:00:00 2001 From: apardods Date: Fri, 13 Dec 2024 15:41:28 +0000 Subject: [PATCH 09/16] Move tax extension values to cbc.Code --- go.mod | 4 ++-- go.sum | 22 ++++++++-------------- internal/utog/charges.go | 8 ++++---- internal/utog/instructions.go | 2 +- internal/utog/lines.go | 2 +- internal/utog/party.go | 2 +- 6 files changed, 17 insertions(+), 23 deletions(-) diff --git a/go.mod b/go.mod index 7183774..c390e1c 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22 toolchain go1.22.1 require ( - github.com/invopop/gobl v0.206.2-0.20241205110633-34e317a013d9 + github.com/invopop/gobl v0.207.0 github.com/joho/godotenv v1.5.1 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 @@ -37,6 +37,6 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect - golang.org/x/crypto v0.30.0 // indirect + golang.org/x/crypto v0.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 7e6fad1..4b58c45 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE= cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U= -github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= -github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= 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/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= @@ -22,10 +20,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/invopop/gobl v0.205.1 h1:khW63/Hu2lzU+IpRN2RF71cfUttCizL0HHAmeakWHyE= -github.com/invopop/gobl v0.205.1/go.mod h1:DmPohPel8b3ta4nDKnXRNzWQlB89cN74e0/WwPUEZUU= -github.com/invopop/gobl v0.206.2-0.20241205110633-34e317a013d9 h1:VIIyZspyf68JHHHQ6uk5Z2AufYPzkqCz1gF4WGRh32g= -github.com/invopop/gobl v0.206.2-0.20241205110633-34e317a013d9/go.mod h1:DmPohPel8b3ta4nDKnXRNzWQlB89cN74e0/WwPUEZUU= +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/validation v0.8.0 h1:e5hXHGnONHImgJdonIpNbctg1hlWy1ncaHoVIQ0JWuw= @@ -82,20 +78,18 @@ gitlab.com/flimzy/testy v0.14.0 h1:2nZV4Wa1OSJb3rOKHh0GJqvvhtE03zT+sKnPCI0owfQ= gitlab.com/flimzy/testy v0.14.0/go.mod h1:m3aGuwdXc+N3QgnH+2Ar2zf1yg0UxNdIaXKvC5SlfMk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +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/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= diff --git a/internal/utog/charges.go b/internal/utog/charges.go index b8fef7f..d4d16ae 100644 --- a/internal/utog/charges.go +++ b/internal/utog/charges.go @@ -60,7 +60,7 @@ func (c *Converter) parseCharge(ac *document.AllowanceCharge) (*bill.Charge, err } if ac.AllowanceChargeReasonCode != nil { ch.Ext = tax.Extensions{ - untdid.ExtKeyCharge: tax.ExtValue(*ac.AllowanceChargeReasonCode), + untdid.ExtKeyCharge: cbc.Code(*ac.AllowanceChargeReasonCode), } } if ac.BaseAmount != nil { @@ -114,7 +114,7 @@ func (c *Converter) parseDiscount(ac *document.AllowanceCharge) (*bill.Discount, } if ac.AllowanceChargeReasonCode != nil { d.Ext = tax.Extensions{ - untdid.ExtKeyAllowance: tax.ExtValue(*ac.AllowanceChargeReasonCode), + untdid.ExtKeyAllowance: cbc.Code(*ac.AllowanceChargeReasonCode), } } if ac.BaseAmount != nil { @@ -164,7 +164,7 @@ func getLineCharge(ac *document.AllowanceCharge) (*bill.LineCharge, error) { } if ac.AllowanceChargeReasonCode != nil { ch.Ext = tax.Extensions{ - untdid.ExtKeyCharge: tax.ExtValue(*ac.AllowanceChargeReasonCode), + untdid.ExtKeyCharge: cbc.Code(*ac.AllowanceChargeReasonCode), } } if ac.AllowanceChargeReason != nil { @@ -193,7 +193,7 @@ func getLineDiscount(ac *document.AllowanceCharge) (*bill.LineDiscount, error) { } if ac.AllowanceChargeReasonCode != nil { d.Ext = tax.Extensions{ - untdid.ExtKeyAllowance: tax.ExtValue(*ac.AllowanceChargeReasonCode), + untdid.ExtKeyAllowance: cbc.Code(*ac.AllowanceChargeReasonCode), } } if ac.AllowanceChargeReason != nil { diff --git a/internal/utog/instructions.go b/internal/utog/instructions.go index 698ac1a..389d14b 100644 --- a/internal/utog/instructions.go +++ b/internal/utog/instructions.go @@ -12,7 +12,7 @@ func (c *Converter) getInstructions(paymentMeans *document.PaymentMeans) *pay.In instructions := &pay.Instructions{ Key: paymentMeansCode(paymentMeans.PaymentMeansCode.Value), Ext: tax.Extensions{ - untdid.ExtKeyPaymentMeans: tax.ExtValue(paymentMeans.PaymentMeansCode.Value), + untdid.ExtKeyPaymentMeans: cbc.Code(paymentMeans.PaymentMeansCode.Value), }, } diff --git a/internal/utog/lines.go b/internal/utog/lines.go index 74093a1..af6809b 100644 --- a/internal/utog/lines.go +++ b/internal/utog/lines.go @@ -142,7 +142,7 @@ func (c *Converter) getIdentities(docLine *document.InvoiceLine) []*org.Identity s := *docLine.Item.StandardItemIdentification.ID.SchemeID id := &org.Identity{ Ext: tax.Extensions{ - iso.ExtKeySchemeID: tax.ExtValue(s), + iso.ExtKeySchemeID: cbc.Code(s), }, Code: cbc.Code(docLine.Item.StandardItemIdentification.ID.Value), } diff --git a/internal/utog/party.go b/internal/utog/party.go index e5ca74e..4233dec 100644 --- a/internal/utog/party.go +++ b/internal/utog/party.go @@ -98,7 +98,7 @@ func (c *Converter) getParty(party *document.Party) *org.Party { s := *party.PartyIdentification.ID.SchemeID identity := &org.Identity{ Ext: tax.Extensions{ - iso.ExtKeySchemeID: tax.ExtValue(s), + iso.ExtKeySchemeID: cbc.Code(s), }, Code: cbc.Code(party.PartyIdentification.ID.Value), } From f1428a0cf1c4a079d3c5ef574ad27c68a6f7558f Mon Sep 17 00:00:00 2001 From: apardods Date: Thu, 19 Dec 2024 10:33:24 +0000 Subject: [PATCH 10/16] Fix field order --- document/payment.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/document/payment.go b/document/payment.go index 2eb0c19..5981cf2 100644 --- a/document/payment.go +++ b/document/payment.go @@ -3,12 +3,12 @@ package document // PaymentMeans represents the means of payment type PaymentMeans struct { PaymentMeansCode IDType `xml:"cbc:PaymentMeansCode"` - PaymentID *string `xml:"cbc:PaymentID"` - PayeeFinancialAccount *FinancialAccount `xml:"cac:PayeeFinancialAccount"` - PayerFinancialAccount *FinancialAccount `xml:"cac:PayerFinancialAccount"` - CardAccount *CardAccount `xml:"cac:CardAccount"` InstructionID *string `xml:"cbc:InstructionID"` InstructionNote []string `xml:"cbc:InstructionNote"` + PaymentID *string `xml:"cbc:PaymentID"` + CardAccount *CardAccount `xml:"cac:CardAccount"` + PayerFinancialAccount *FinancialAccount `xml:"cac:PayerFinancialAccount"` + PayeeFinancialAccount *FinancialAccount `xml:"cac:PayeeFinancialAccount"` PaymentMandate *PaymentMandate `xml:"cac:PaymentMandate"` } From 5ca2ced57800c4d288e6d94d6c0e0d908bcbfb07 Mon Sep 17 00:00:00 2001 From: apardods Date: Tue, 7 Jan 2025 09:12:01 +0000 Subject: [PATCH 11/16] Add Country Prefix --- internal/gtou/party.go | 2 +- internal/gtou/party_test.go | 4 ++-- test/data/gtou/out/correction-invoice.xml | 4 ++-- test/data/gtou/out/credit-note.xml | 4 ++-- test/data/gtou/out/invoice-complete.xml | 4 ++-- test/data/gtou/out/invoice-de-de.xml | 4 ++-- test/data/gtou/out/invoice-minimal.xml | 4 ++-- test/data/gtou/out/invoice-without-buyers-tax-id.xml | 2 +- test/data/gtou/out/self-billed-invoice.xml | 4 ++-- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/internal/gtou/party.go b/internal/gtou/party.go index 6d25ef2..eea7ab0 100644 --- a/internal/gtou/party.go +++ b/internal/gtou/party.go @@ -26,7 +26,7 @@ func (c *Converter) newParty(party *org.Party) document.Party { // Although taxID is mandatory, when there is a Tax Representative and the seller comes from // Ordering.Seller, the pointer could be nil if party.TaxID != nil && party.TaxID.Code != "" { - taxID := party.TaxID.Code.String() + taxID := party.TaxID.String() p.PartyTaxScheme = []document.PartyTaxScheme{ { CompanyID: &taxID, diff --git a/internal/gtou/party_test.go b/internal/gtou/party_test.go index 43f3b2f..7a8dd90 100644 --- a/internal/gtou/party_test.go +++ b/internal/gtou/party_test.go @@ -12,7 +12,7 @@ func TestNewParty(t *testing.T) { doc, err := newDocumentFrom("invoice-de-de.json") require.NoError(t, err) - assert.Equal(t, "111111125", *doc.AccountingSupplierParty.Party.PartyTaxScheme[0].CompanyID) + assert.Equal(t, "DE111111125", *doc.AccountingSupplierParty.Party.PartyTaxScheme[0].CompanyID) assert.Equal(t, "Provide One GmbH", *doc.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationName) assert.Equal(t, "+49100200300", *doc.AccountingSupplierParty.Party.Contact.Telephone) assert.Equal(t, "billing@example.com", *doc.AccountingSupplierParty.Party.Contact.ElectronicMail) @@ -22,7 +22,7 @@ func TestNewParty(t *testing.T) { assert.Equal(t, "69190", *doc.AccountingSupplierParty.Party.PostalAddress.PostalZone) assert.Equal(t, "DE", doc.AccountingSupplierParty.Party.PostalAddress.Country.IdentificationCode) - assert.Equal(t, "282741168", *doc.AccountingCustomerParty.Party.PartyTaxScheme[0].CompanyID) + assert.Equal(t, "DE282741168", *doc.AccountingCustomerParty.Party.PartyTaxScheme[0].CompanyID) assert.Equal(t, "Sample Consumer", *doc.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationName) assert.Equal(t, "email@sample.com", *doc.AccountingCustomerParty.Party.Contact.ElectronicMail) diff --git a/test/data/gtou/out/correction-invoice.xml b/test/data/gtou/out/correction-invoice.xml index 947eb32..1156ede 100755 --- a/test/data/gtou/out/correction-invoice.xml +++ b/test/data/gtou/out/correction-invoice.xml @@ -19,7 +19,7 @@ - 111111125 + DE111111125 VAT @@ -45,7 +45,7 @@ - 282741168 + DE282741168 VAT diff --git a/test/data/gtou/out/credit-note.xml b/test/data/gtou/out/credit-note.xml index e3c2663..e196d84 100755 --- a/test/data/gtou/out/credit-note.xml +++ b/test/data/gtou/out/credit-note.xml @@ -19,7 +19,7 @@ - 111111125 + DE111111125 VAT @@ -45,7 +45,7 @@ - 282741168 + DE282741168 VAT diff --git a/test/data/gtou/out/invoice-complete.xml b/test/data/gtou/out/invoice-complete.xml index b737a9b..9ad1b3a 100755 --- a/test/data/gtou/out/invoice-complete.xml +++ b/test/data/gtou/out/invoice-complete.xml @@ -33,7 +33,7 @@ - 111111125 + DE111111125 VAT @@ -59,7 +59,7 @@ - 282741168 + DE282741168 VAT diff --git a/test/data/gtou/out/invoice-de-de.xml b/test/data/gtou/out/invoice-de-de.xml index 7ad3f7e..2d73772 100755 --- a/test/data/gtou/out/invoice-de-de.xml +++ b/test/data/gtou/out/invoice-de-de.xml @@ -32,7 +32,7 @@ - 111111125 + DE111111125 VAT @@ -61,7 +61,7 @@ - 282741168 + DE282741168 VAT diff --git a/test/data/gtou/out/invoice-minimal.xml b/test/data/gtou/out/invoice-minimal.xml index 6c18dab..d35da2d 100755 --- a/test/data/gtou/out/invoice-minimal.xml +++ b/test/data/gtou/out/invoice-minimal.xml @@ -16,7 +16,7 @@ - 111111125 + DE111111125 VAT @@ -40,7 +40,7 @@ - 282741168 + DE282741168 VAT diff --git a/test/data/gtou/out/invoice-without-buyers-tax-id.xml b/test/data/gtou/out/invoice-without-buyers-tax-id.xml index 26eae54..3ac8c07 100755 --- a/test/data/gtou/out/invoice-without-buyers-tax-id.xml +++ b/test/data/gtou/out/invoice-without-buyers-tax-id.xml @@ -19,7 +19,7 @@ - 111111125 + DE111111125 VAT diff --git a/test/data/gtou/out/self-billed-invoice.xml b/test/data/gtou/out/self-billed-invoice.xml index 57a9bdd..6977733 100755 --- a/test/data/gtou/out/self-billed-invoice.xml +++ b/test/data/gtou/out/self-billed-invoice.xml @@ -20,7 +20,7 @@ - 111111125 + DE111111125 VAT @@ -46,7 +46,7 @@ - 282741168 + DE282741168 VAT From b0932caf692f4467fec5294604e3897d1a3e9f6c Mon Sep 17 00:00:00 2001 From: apardods Date: Tue, 7 Jan 2025 10:14:25 +0000 Subject: [PATCH 12/16] Add Codecov action --- .github/workflows/test.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 10a4e38..222f428 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -21,7 +21,9 @@ jobs: run: go mod download - name: Test - run: go test -tags unit -race ./... + run: go test -race -coverprofile=coverage.out -covermode=atomic ./... - - name: Build - run: go build -v ./... + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v4.0.1 + with: + token: ${{ secrets.CODECOV_TOKEN }} From d3740441c873b9e6d20bdc65a7cb5bb7dfafb53c Mon Sep 17 00:00:00 2001 From: apardods Date: Thu, 9 Jan 2025 17:56:37 +0000 Subject: [PATCH 13/16] Add cbc:EndpointID support --- internal/gtou/party.go | 7 +++++++ internal/gtou/party_test.go | 8 ++++++++ internal/utog/party.go | 8 ++++++++ internal/utog/party_test.go | 2 +- test/data/gtou/invoice-complete.json | 5 +++++ test/data/gtou/out/invoice-complete.xml | 1 + test/data/utog/out/ubl-example2.json | 5 +++++ test/data/utog/out/ubl-example5.json | 10 ++++++++++ test/data/utog/ubl-example2.xml | 1 + 9 files changed, 46 insertions(+), 1 deletion(-) diff --git a/internal/gtou/party.go b/internal/gtou/party.go index eea7ab0..95af8fb 100644 --- a/internal/gtou/party.go +++ b/internal/gtou/party.go @@ -54,6 +54,13 @@ func (c *Converter) newParty(party *org.Party) document.Party { p.Contact = contact } + if len(party.Inboxes) > 0 { + p.EndpointID = &document.EndpointID{ + Value: party.Inboxes[0].Email, + SchemeID: "EM", + } + } + if party.Alias != "" { p.PartyName = &document.PartyName{ Name: party.Alias, diff --git a/internal/gtou/party_test.go b/internal/gtou/party_test.go index 7a8dd90..1e14252 100644 --- a/internal/gtou/party_test.go +++ b/internal/gtou/party_test.go @@ -35,4 +35,12 @@ func TestNewParty(t *testing.T) { assert.Equal(t, "1234567890128", doc.AccountingCustomerParty.Party.PartyIdentification.ID.Value) }) + t.Run("invoice-complete.json", func(t *testing.T) { + doc, err := newDocumentFrom("invoice-complete.json") + require.NoError(t, err) + + assert.Equal(t, "inbox@example.com", doc.AccountingSupplierParty.Party.EndpointID.Value) + assert.Equal(t, "EM", doc.AccountingSupplierParty.Party.EndpointID.SchemeID) + }) + } diff --git a/internal/utog/party.go b/internal/utog/party.go index 4233dec..3648b62 100644 --- a/internal/utog/party.go +++ b/internal/utog/party.go @@ -16,6 +16,14 @@ func (c *Converter) getParty(party *document.Party) *org.Party { p.Name = *party.PartyLegalEntity.RegistrationName } + if party.EndpointID != nil { + p.Inboxes = []*org.Inbox{ + { + Email: party.EndpointID.Value, + }, + } + } + if party.PartyName != nil { if p.Name == "" { p.Name = party.PartyName.Name diff --git a/internal/utog/party_test.go b/internal/utog/party_test.go index 2ee7aae..8373efd 100644 --- a/internal/utog/party_test.go +++ b/internal/utog/party_test.go @@ -54,7 +54,7 @@ func TestGetParty(t *testing.T) { assert.Equal(t, "Antonio Salesmacher", seller.People[0].Name.Given) assert.Equal(t, "antonio@salescompany.no", seller.Emails[0].Address) assert.Equal(t, "46211230", seller.Telephones[0].Number) - + assert.Equal(t, "seller@email.de", seller.Inboxes[0].Email) customer := inv.Customer require.NotNil(t, customer) assert.Equal(t, "The Buyercompany", customer.Name) diff --git a/test/data/gtou/invoice-complete.json b/test/data/gtou/invoice-complete.json index c45303f..80a0efe 100644 --- a/test/data/gtou/invoice-complete.json +++ b/test/data/gtou/invoice-complete.json @@ -33,6 +33,11 @@ } } ], + "inboxes": [ + { + "email": "inbox@example.com" + } + ], "addresses": [ { "num": "16", diff --git a/test/data/gtou/out/invoice-complete.xml b/test/data/gtou/out/invoice-complete.xml index 9ad1b3a..40f1fba 100755 --- a/test/data/gtou/out/invoice-complete.xml +++ b/test/data/gtou/out/invoice-complete.xml @@ -24,6 +24,7 @@ + inbox@example.com Dietmar-Hopp-Allee 16 Walldorf diff --git a/test/data/utog/out/ubl-example2.json b/test/data/utog/out/ubl-example2.json index f097bf6..1c0ef2e 100755 --- a/test/data/utog/out/ubl-example2.json +++ b/test/data/utog/out/ubl-example2.json @@ -365,6 +365,11 @@ } } ], + "inboxes": [ + { + "email": "seller@email.de" + } + ], "addresses": [ { "street": "Main street 34", diff --git a/test/data/utog/out/ubl-example5.json b/test/data/utog/out/ubl-example5.json index 4cad830..7952044 100755 --- a/test/data/utog/out/ubl-example5.json +++ b/test/data/utog/out/ubl-example5.json @@ -63,6 +63,11 @@ } } ], + "inboxes": [ + { + "email": "info@buyercompany.dk" + } + ], "addresses": [ { "street": "Anystreet, Building 1", @@ -272,6 +277,11 @@ } } ], + "inboxes": [ + { + "email": "info@selco.nl" + } + ], "addresses": [ { "street": "Hoofdstraat 4", diff --git a/test/data/utog/ubl-example2.xml b/test/data/utog/ubl-example2.xml index bb77ff7..94959c2 100644 --- a/test/data/utog/ubl-example2.xml +++ b/test/data/utog/ubl-example2.xml @@ -45,6 +45,7 @@ + seller@email.de 1238764941386 From e937ffd8aa017a6635a486d46aba7b31f9d11a09 Mon Sep 17 00:00:00 2001 From: apardods Date: Thu, 9 Jan 2025 17:58:13 +0000 Subject: [PATCH 14/16] Update to GOBL 0.208 --- go.mod | 10 +++++----- go.sum | 29 ++++++++++++++--------------- internal/utog/lines.go | 6 +++--- internal/utog/utog.go | 4 ++-- 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/go.mod b/go.mod index c390e1c..e61d694 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22 toolchain go1.22.1 require ( - github.com/invopop/gobl v0.207.0 + github.com/invopop/gobl v0.208.0 github.com/joho/godotenv v1.5.1 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 @@ -19,7 +19,7 @@ require ( ) require ( - cloud.google.com/go v0.116.0 // 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 @@ -27,16 +27,16 @@ require ( 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/jsonschema v0.13.0 // indirect github.com/invopop/yaml v0.3.1 // indirect github.com/kr/text v0.2.0 // 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/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect - golang.org/x/crypto v0.31.0 // indirect + golang.org/x/crypto v0.32.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 4b58c45..6fe2b31 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE= -cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U= +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/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= @@ -20,17 +20,16 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -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/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= @@ -43,8 +42,8 @@ github.com/lestrrat-go/libxml2 v0.0.0-20240905100032-c934e3fcb9d3 h1:ZIYZ0+TEddr github.com/lestrrat-go/libxml2 v0.0.0-20240905100032-c934e3fcb9d3/go.mod h1:/0MMipmS+5SMXCSkulsvJwYmddKI4IL5tVy6AZMo9n0= 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.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -78,15 +77,15 @@ gitlab.com/flimzy/testy v0.14.0 h1:2nZV4Wa1OSJb3rOKHh0GJqvvhtE03zT+sKnPCI0owfQ= gitlab.com/flimzy/testy v0.14.0/go.mod h1:m3aGuwdXc+N3QgnH+2Ar2zf1yg0UxNdIaXKvC5SlfMk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +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/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= diff --git a/internal/utog/lines.go b/internal/utog/lines.go index af6809b..da791bb 100644 --- a/internal/utog/lines.go +++ b/internal/utog/lines.go @@ -37,7 +37,7 @@ func (c *Converter) getLines(doc *document.Invoice) error { } ids := make([]*org.Identity, 0) - notes := make([]*cbc.Note, 0) + notes := make([]*org.Note, 0) if docLine.InvoicedQuantity != nil { line.Quantity, err = num.AmountFromString(docLine.InvoicedQuantity.Value) @@ -49,7 +49,7 @@ func (c *Converter) getLines(doc *document.Invoice) error { if len(docLine.Note) > 0 { for _, note := range docLine.Note { if note != "" { - notes = append(notes, &cbc.Note{ + notes = append(notes, &org.Note{ Text: note, }) } @@ -62,7 +62,7 @@ func (c *Converter) getLines(doc *document.Invoice) error { // As there is no specific GOBL field for BT-133, we use a note to store it if docLine.AccountingCost != nil { - notes = append(notes, &cbc.Note{ + notes = append(notes, &org.Note{ Key: "buyer-accounting-ref", Text: *docLine.AccountingCost, }) diff --git a/internal/utog/utog.go b/internal/utog/utog.go index 64fe0c8..66b5a5b 100644 --- a/internal/utog/utog.go +++ b/internal/utog/utog.go @@ -76,9 +76,9 @@ func (c *Converter) NewInvoice(doc *document.Invoice) error { } if len(doc.Note) > 0 { - c.inv.Notes = make([]*cbc.Note, 0, len(doc.Note)) + c.inv.Notes = make([]*org.Note, 0, len(doc.Note)) for _, note := range doc.Note { - n := &cbc.Note{ + n := &org.Note{ Text: note, } c.inv.Notes = append(c.inv.Notes, n) From 6da979dcd7823f9ead9aab3306fb87ccfd1f38be Mon Sep 17 00:00:00 2001 From: apardods Date: Fri, 10 Jan 2025 11:19:47 +0000 Subject: [PATCH 15/16] Fix Releaser --- .github/workflows/release.yaml | 21 +++++++------------ .goreleaser.yml | 37 ++++++++++++++++++++++++++++++++++ internal/gtou/party.go | 3 +++ 3 files changed, 47 insertions(+), 14 deletions(-) create mode 100644 .goreleaser.yml diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 3ccfc8a..d3f954d 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,5 +1,5 @@ # -# Automatically tag a merge with master and release it +# Automatically tag a merge with main. # name: Release @@ -8,12 +8,12 @@ on: push: branches: - main - tags: - - "*" + paths-ignore: + - "README.md" jobs: - tag-release: - name: Tag and Release + release: + name: Tag runs-on: ubuntu-latest steps: - name: Checkout @@ -21,15 +21,8 @@ jobs: with: fetch-depth: "0" # make sure we get all commits! - - name: Get repo details - run: | - echo "COMMIT_TYPE=$(echo $GITHUB_REF | cut -d / -f 2)" >> $GITHUB_ENV - echo "REPO_NAME=$(echo $GITHUB_REPOSITORY | cut -d / -f 2-)" >> $GITHUB_ENV - echo "REPO_VERSION=$(echo $GITHUB_REF | cut -d / -f 3-)" >> $GITHUB_ENV - - name: Bump version and push tag id: bump - if: env.COMMIT_TYPE != 'tags' uses: anothrNick/github-tag-action@1.52.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -40,7 +33,7 @@ jobs: uses: actions/setup-go@v5 with: go-version-file: "go.mod" - + - name: Run GoReleaser uses: goreleaser/goreleaser-action@v6 with: @@ -48,4 +41,4 @@ jobs: version: latest args: release --clean env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..2899b6f --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,37 @@ +before: + hooks: + - go mod download +builds: + - id: gobl.ubl + env: + - CGO_ENABLED=0 + goos: + - linux + - windows + - darwin + main: ./cmd/gobl.ubl + binary: gobl.ubl + +archives: + - id: gobl.ubl + builds: + - gobl.ubl + format: tar.gz + name_template: "gobl.ubl_{{ .Version }}_{{ .Os }}_{{ .Arch }}" + wrap_in_directory: true + +checksum: + name_template: "checksums.txt" +snapshot: + name_template: "{{ .Tag }}" +changelog: + sort: asc + filters: + exclude: + - "^docs:" + - "^test:" +release: + github: + owner: invopop + name: gobl.ubl + prerelease: auto \ No newline at end of file diff --git a/internal/gtou/party.go b/internal/gtou/party.go index 95af8fb..15b9eb1 100644 --- a/internal/gtou/party.go +++ b/internal/gtou/party.go @@ -10,6 +10,9 @@ import ( "github.com/invopop/gobl/org" ) +// SchemeIDEmail is the EAS codelist value for email +const SchemeIDEmail = "EM" + func (c *Converter) newParty(party *org.Party) document.Party { if party == nil { return document.Party{} From 0c9de5259e1b17d36c75a331bd666196f2b44149 Mon Sep 17 00:00:00 2001 From: apardods Date: Fri, 10 Jan 2025 11:23:46 +0000 Subject: [PATCH 16/16] Codecov badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e7e2b6d..2e5c0a2 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ GOBL conversion into UBL XML format and vice versa. +[![codecov](https://codecov.io/gh/invopop/gobl.ubl/graph/badge.svg?token=KWKFOSEEK7)](https://codecov.io/gh/invopop/gobl.ubl) + Copyright [Invopop Ltd.](https://invopop.com) 2023. Released publicly under the [Apache License Version 2.0](LICENSE). For commercial licenses, please contact the [dev team at invopop](mailto:dev@invopop.com). To accept contributions to this library, we require transferring copyrights to Invopop Ltd. ## Usage