diff --git a/bill/invoice_correct.go b/bill/invoice_correct.go index e37c0cba..c1464df5 100644 --- a/bill/invoice_correct.go +++ b/bill/invoice_correct.go @@ -180,15 +180,15 @@ func (inv *Invoice) CorrectionOptionsSchema() (interface{}, error) { } } - if len(cd.Keys) > 0 { + if len(cd.Changes) > 0 { cos.Required = append(cos.Required, "changes") if prop, ok := cos.Properties.Get("changes"); ok { ps := prop.(orderedmap.OrderedMap) items, _ := ps.Get("items") pi := items.(orderedmap.OrderedMap) - oneOf := make([]*jsonschema.Schema, len(cd.Keys)) - for i, v := range cd.Keys { + oneOf := make([]*jsonschema.Schema, len(cd.Changes)) + for i, v := range cd.Changes { oneOf[i] = &jsonschema.Schema{ Const: v.Key.String(), Title: v.Name.String(), @@ -346,12 +346,12 @@ func (inv *Invoice) validatePrecedingData(o *CorrectionOptions, cd *tax.Correcti } } - if len(cd.Keys) > 0 { + if len(cd.Changes) > 0 { if len(pre.Changes) == 0 { return errors.New("missing changes") } for _, k := range pre.Changes { - if !cd.HasKey(k) { + if !cd.HasChange(k) { return fmt.Errorf("invalid change key: '%v'", k) } } diff --git a/regimes/es/corrections.go b/regimes/es/corrections.go index f8d909af..c8fff7ad 100644 --- a/regimes/es/corrections.go +++ b/regimes/es/corrections.go @@ -45,7 +45,7 @@ const ( // correctionList contains an array of Key Definitions describing each of the acceptable // correction keys, descriptions, and their "code" as determined by the FacturaE specifications. -var correctionList = []*tax.KeyDefinition{ +var correctionChangesList = []*tax.KeyDefinition{ { Key: CorrectionKeyCode, Name: i18n.String{ @@ -259,10 +259,10 @@ var correctionMethodList = []*tax.KeyDefinition{ }, } -func correctionKeys() []interface{} { - keys := make([]interface{}, len(correctionList)) +func correctionChangeKeys() []interface{} { + keys := make([]interface{}, len(correctionChangesList)) i := 0 - for _, v := range correctionList { + for _, v := range correctionChangesList { keys[i] = v.Key i++ } @@ -279,6 +279,6 @@ func correctionMethodKeys() []interface{} { return keys } -var isValidCorrectionKey = validation.In(correctionKeys()...) +var isValidCorrectionChangeKey = validation.In(correctionChangeKeys()...) var isValidCorrectionMethodKey = validation.In(correctionMethodKeys()...) diff --git a/regimes/es/es.go b/regimes/es/es.go index 497c72ff..bc8b0288 100644 --- a/regimes/es/es.go +++ b/regimes/es/es.go @@ -91,8 +91,8 @@ func New() *tax.Regime { Types: []cbc.Key{ bill.InvoiceTypeCorrective, }, - Keys: correctionList, Methods: correctionMethodList, + Changes: correctionChangesList, }, }, } diff --git a/regimes/es/invoices.go b/regimes/es/invoices.go index 07b3522c..4faf957f 100644 --- a/regimes/es/invoices.go +++ b/regimes/es/invoices.go @@ -90,7 +90,7 @@ func (v *invoiceValidator) preceding(value interface{}) error { return validation.ValidateStruct(obj, validation.Field(&obj.Changes, validation.Required, - validation.Each(isValidCorrectionKey), + validation.Each(isValidCorrectionChangeKey), ), validation.Field(&obj.CorrectionMethod, validation.Required, diff --git a/regimes/it/invoice_validator.go b/regimes/it/invoice_validator.go index 138ff0d6..ba83f6d8 100644 --- a/regimes/it/invoice_validator.go +++ b/regimes/it/invoice_validator.go @@ -48,7 +48,6 @@ func (v *invoiceValidator) supplier(value interface{}) error { tax.IdentityTypeIn(TaxIdentityTypeBusiness, TaxIdentityTypeGovernment), ), validation.Field(&supplier.Addresses, - validation.Length(1, 1), validation.By(validateAddress), ), validation.Field(&supplier.Registration, @@ -68,7 +67,7 @@ func (v *invoiceValidator) customer(value interface{}) error { return validation.ValidateStruct(customer, validation.Field(&customer.TaxID, validation.When( - customer.TaxID.Country.In(l10n.IT), + isItalianParty(customer), validation.Required, tax.RequireIdentityCode, tax.IdentityTypeIn( @@ -79,24 +78,31 @@ func (v *invoiceValidator) customer(value interface{}) error { ), ), validation.Field(&customer.Addresses, - validation.Length(1, 1), - validation.By(validateAddress), + validation.When( + isItalianParty(customer), + validation.By(validateAddress), + ), ), ) } +func isItalianParty(party *org.Party) bool { + if party == nil || party.TaxID == nil { + return false + } + return party.TaxID.Country.In(l10n.IT) +} + func validateAddress(value interface{}) error { v, ok := value.([]*org.Address) if v == nil || !ok { return nil } + // Post code and street in addition to the locality are required in Italian invoices. address := v[0] return validation.ValidateStruct(address, - validation.Field(&address.Country), - validation.Field(&address.Locality, validation.Required), - validation.Field(&address.Code, validation.Required), validation.Field(&address.Street, validation.Required), - validation.Field(&address.Number, validation.Required), + validation.Field(&address.Code, validation.Required), ) } diff --git a/tax/regime.go b/tax/regime.go index 65a3c5ec..1f381e72 100644 --- a/tax/regime.go +++ b/tax/regime.go @@ -216,10 +216,10 @@ type CorrectionDefinition struct { Schema string `json:"schema" jsonschema:"title=Schema"` // The types of sub-documents supported by the regime Types []cbc.Key `json:"types,omitempty" jsonschema:"title=Types"` - // List of all the keys that can be used to identify a correction. - Keys []*KeyDefinition `json:"keys,omitempty" jsonschema:"title=Keys"` // Methods describe the methods used to correct an invoice. Methods []*KeyDefinition `json:"methods,omitempty" jsonschema:"title=Methods"` + // List of change keys that can be used to describe what has been corrected. + Changes []*KeyDefinition `json:"changes,omitempty" jsonschema:"title=Changes"` // ReasonRequired when true implies that a reason must be provided ReasonRequired bool `json:"reason_required,omitempty" jsonschema:"title=Reason Required"` // Stamps that must be copied from the preceding document. @@ -651,13 +651,13 @@ func (cd *CorrectionDefinition) HasType(t cbc.Key) bool { return t.In(cd.Types...) } -// HasKey returns true if the correction definition has the keys provided. -func (cd *CorrectionDefinition) HasKey(key cbc.Key) bool { +// HasChange returns true if the correction definition has the change key provided. +func (cd *CorrectionDefinition) HasChange(key cbc.Key) bool { if cd == nil { return false // no correction definitions } - for _, kd := range cd.Keys { + for _, kd := range cd.Changes { if kd.Key == key { return true } @@ -684,8 +684,8 @@ func (cd *CorrectionDefinition) Validate() error { validation.Field(&cd.Schema, validation.Required), validation.Field(&cd.Types), validation.Field(&cd.Stamps), - validation.Field(&cd.Keys), validation.Field(&cd.Methods), + validation.Field(&cd.Changes), ) return err }