Skip to content

Commit

Permalink
Merge pull request #243 from invopop/correct-ext-fix
Browse files Browse the repository at this point in the history
Correct ext fix
  • Loading branch information
samlown authored Feb 8, 2024
2 parents 1560a33 + 28ccb97 commit 8a110ec
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 9 deletions.
27 changes: 21 additions & 6 deletions bill/invoice_correct.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ func (inv *Invoice) CorrectionOptionsSchema() (interface{}, error) {
// Try to add all the specific options for the extensions
if len(cd.Extensions) > 0 {
if ext, ok := cos.Properties.Get("ext"); ok {
ext.Ref = "" // remove the ref
ext.Type = "object"
ext.Properties = jsonschema.NewProperties()
for _, pk := range cd.Extensions {
re := r.ExtensionDef(pk)
Expand All @@ -180,37 +182,50 @@ func (inv *Invoice) CorrectionOptionsSchema() (interface{}, error) {
}
var oneOf []*jsonschema.Schema
if len(re.Codes) > 0 {
oneOf = make([]*jsonschema.Schema, len(re.Codes))
for i, c := range re.Codes {
oneOf = make([]*jsonschema.Schema, 1, len(re.Codes)+1)
oneOf[0] = &jsonschema.Schema{ // empty option validated later
Const: "",
Title: "None",
}
for _, c := range re.Codes {
ci := &jsonschema.Schema{
Const: c.Code.String(),
Title: c.Name.String(),
}
if len(c.Desc) > 0 {
ci.Description = c.Desc.String()
}
oneOf[i] = ci
oneOf = append(oneOf, ci)
}
} else if len(re.Keys) > 0 {
oneOf = make([]*jsonschema.Schema, len(re.Keys))
for i, c := range re.Codes {
oneOf = make([]*jsonschema.Schema, 1, len(re.Keys)+1)
oneOf[0] = &jsonschema.Schema{
Const: "",
Title: "None",
}
for _, c := range re.Codes {
ci := &jsonschema.Schema{
Const: c.Code.String(),
Title: c.Name.String(),
}
if len(c.Desc) > 0 {
ci.Description = c.Desc.String()
}
oneOf[i] = ci
oneOf = append(oneOf, ci)
}
}
if oneOf != nil {
prop.OneOf = oneOf
}
ext.Properties.Set(pk.String(), prop)
ext.Required = append(ext.Required, pk.String())
}
}
}
cos.Required = append(cos.Required, "ext")
} else {
// Remove extensions, they're not needed if not defined
cos.Properties.Delete("ext")
}

if cd.ReasonRequired {
Expand Down
4 changes: 2 additions & 2 deletions bill/invoice_correct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,10 @@ func TestCorrectionOptionsSchema(t *testing.T) {
require.True(t, ok)
pmp, ok := pm.Properties.Get(string(es.ExtKeyFacturaECorrection))
require.True(t, ok)
assert.Len(t, pmp.OneOf, 22)
assert.Len(t, pmp.OneOf, 23)

// Sorry, this is copied and pasted from the test output!
exp := `{"$ref":"https://gobl.org/draft-0/tax/ext-map","properties":{"es-facturae-correction":{"oneOf":[{"const":"01","title":"Invoice code"},{"const":"02","title":"Invoice series"},{"const":"03","title":"Issue date"},{"const":"04","title":"Name and surnames/Corporate name - Issuer (Sender)"},{"const":"05","title":"Name and surnames/Corporate name - Receiver"},{"const":"06","title":"Issuer's Tax Identification Number"},{"const":"07","title":"Receiver's Tax Identification Number"},{"const":"08","title":"Supplier's address"},{"const":"09","title":"Customer's address"},{"const":"10","title":"Item line"},{"const":"11","title":"Applicable Tax Rate"},{"const":"12","title":"Applicable Tax Amount"},{"const":"13","title":"Applicable Date/Period"},{"const":"14","title":"Invoice Class"},{"const":"15","title":"Legal literals"},{"const":"16","title":"Taxable Base"},{"const":"80","title":"Calculation of tax outputs"},{"const":"81","title":"Calculation of tax inputs"},{"const":"82","title":"Taxable Base modified due to return of packages and packaging materials"},{"const":"83","title":"Taxable Base modified due to discounts and rebates"},{"const":"84","title":"Taxable Base modified due to firm court ruling or administrative decision"},{"const":"85","title":"Taxable Base modified due to unpaid outputs where there is a judgement opening insolvency proceedings"}],"type":"string","title":"FacturaE Change","description":"FacturaE requires a specific and single code that explains why the previous invoice is being corrected."},"es-tbai-correction":{"oneOf":[{"const":"R1","title":"Rectified invoice: error based on law and Article 80 One, Two and Six of the Provincial Tax Law of VAT"},{"const":"R2","title":"Rectified invoice: error based on law and Article 80 Three of the Provincial Tax Law of VAT"},{"const":"R3","title":"Rectified invoice: error based on law and Article 80 Four of the Provincial Tax Law of VAT"},{"const":"R4","title":"Rectified invoice: Other"},{"const":"R5","title":"Rectified invoice: simplified invoices"}],"type":"string","title":"TicketBAI Rectification Type Code","description":"Corrected or rectified invoices that need to be sent in the TicketBAI format\nrequire a specific type code to be defined alongside the preceding invoice\ndata."}},"title":"Extensions","description":"Extensions for region specific requirements."}`
exp := `{"properties":{"es-facturae-correction":{"oneOf":[{"const":"","title":"None"},{"const":"01","title":"Invoice code"},{"const":"02","title":"Invoice series"},{"const":"03","title":"Issue date"},{"const":"04","title":"Name and surnames/Corporate name - Issuer (Sender)"},{"const":"05","title":"Name and surnames/Corporate name - Receiver"},{"const":"06","title":"Issuer's Tax Identification Number"},{"const":"07","title":"Receiver's Tax Identification Number"},{"const":"08","title":"Supplier's address"},{"const":"09","title":"Customer's address"},{"const":"10","title":"Item line"},{"const":"11","title":"Applicable Tax Rate"},{"const":"12","title":"Applicable Tax Amount"},{"const":"13","title":"Applicable Date/Period"},{"const":"14","title":"Invoice Class"},{"const":"15","title":"Legal literals"},{"const":"16","title":"Taxable Base"},{"const":"80","title":"Calculation of tax outputs"},{"const":"81","title":"Calculation of tax inputs"},{"const":"82","title":"Taxable Base modified due to return of packages and packaging materials"},{"const":"83","title":"Taxable Base modified due to discounts and rebates"},{"const":"84","title":"Taxable Base modified due to firm court ruling or administrative decision"},{"const":"85","title":"Taxable Base modified due to unpaid outputs where there is a judgement opening insolvency proceedings"}],"type":"string","title":"FacturaE Change","description":"FacturaE requires a specific and single code that explains why the previous invoice is being corrected."},"es-tbai-correction":{"oneOf":[{"const":"","title":"None"},{"const":"R1","title":"Rectified invoice: error based on law and Article 80 One, Two and Six of the Provincial Tax Law of VAT"},{"const":"R2","title":"Rectified invoice: error based on law and Article 80 Three of the Provincial Tax Law of VAT"},{"const":"R3","title":"Rectified invoice: error based on law and Article 80 Four of the Provincial Tax Law of VAT"},{"const":"R4","title":"Rectified invoice: Other"},{"const":"R5","title":"Rectified invoice: simplified invoices"}],"type":"string","title":"TicketBAI Rectification Type Code","description":"Corrected or rectified invoices that need to be sent in the TicketBAI format\nrequire a specific type code to be defined alongside the preceding invoice\ndata."}},"type":"object","required":["es-facturae-correction","es-tbai-correction"],"title":"Extensions","description":"Extensions for region specific requirements."}`
data, err := json.Marshal(pm)
require.NoError(t, err)
if !assert.JSONEq(t, exp, string(data)) {
Expand Down
2 changes: 1 addition & 1 deletion version.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
type Version string

// VERSION is the current version of the GOBL library.
const VERSION Version = "v0.67.2"
const VERSION Version = "v0.67.3"

// Semver parses and returns semver
func (v Version) Semver() *semver.Version {
Expand Down

0 comments on commit 8a110ec

Please sign in to comment.