|
|
|
|
package pain
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"strings"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type PainXML struct {
|
|
|
|
|
GroupHeader GrpHdr `xml:"GrpHdr"`
|
|
|
|
|
PaymentInformation []PmtInf `xml:"PmtInf"`
|
|
|
|
|
TransactionInformation []TxInf `xml:"DrctDbtTxInf"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *PainXML) Valid() error {
|
|
|
|
|
var err []string
|
|
|
|
|
if e := p.GroupHeader.Valid(); e != nil {
|
|
|
|
|
err = append(err, fmt.Sprintf("%v", e))
|
|
|
|
|
}
|
|
|
|
|
if len(p.PaymentInformation) < 1 {
|
|
|
|
|
err = append(err, "no payment information")
|
|
|
|
|
}
|
|
|
|
|
if len(p.TransactionInformation) < 1 {
|
|
|
|
|
err = append(err, "no transaction information")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(err) > 0 {
|
|
|
|
|
return fmt.Errorf("pain XML not valid: %v", strings.Join(err, ", "))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type CdtrAcct struct {
|
|
|
|
|
Id IBAN `xml:"Id"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *CdtrAcct) Valid() error {
|
|
|
|
|
if e := c.Id.Valid(); e != nil {
|
|
|
|
|
return fmt.Errorf("creditor account id not valid: %v", e)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type IBAN struct {
|
|
|
|
|
IBAN string `xml:"IBAN"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (i *IBAN) Valid() error {
|
|
|
|
|
if !SEPARegexps["IBAN"].MatchString(i.IBAN) {
|
|
|
|
|
return fmt.Errorf("IBAN does not match format")
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Code struct {
|
|
|
|
|
Code string `xml:"Cd"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (meta *PmtTpInf) Valid() error {
|
|
|
|
|
var err []string
|
|
|
|
|
// TODO: check meta.ServiceLevel for nil
|
|
|
|
|
if !SEPARegexps["PmtMetaSvcLvl"].MatchString(meta.ServiceLevel.Code) {
|
|
|
|
|
err = append(err, "incorrect service level present (must be 'SEPA')")
|
|
|
|
|
}
|
|
|
|
|
// TODO: check meta.LocalInstrument for nil
|
|
|
|
|
if !SEPARegexps["PmtMetaLclInstrm"].MatchString(meta.LocalInstrument.Code) {
|
|
|
|
|
err = append(err, "incorrect local instrument present")
|
|
|
|
|
}
|
|
|
|
|
if !SEPARegexps["SeqTp"].MatchString(meta.SequenceType) {
|
|
|
|
|
err = append(err, "sequence type has incorrect format")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(err) > 0 {
|
|
|
|
|
return fmt.Errorf("payment meta not valid: %v", strings.Join(err, ", "))
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type TxInf struct {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type PartySEPA2 struct {
|
|
|
|
|
PrivateId PersonIdSEPA2 `xml:"PrvtId"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *PartySEPA2) Valid() error {
|
|
|
|
|
return p.PrivateId.Valid()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type PartyIdSEPA1 struct {
|
|
|
|
|
Name string `xml:"Nm"`
|
|
|
|
|
// We do not implement the "Id" element from "PartyIdentificationSEPA1"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type PartyIdSEPA3 struct {
|
|
|
|
|
Id PartySEPA2 `xml:"Id"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *PartyIdSEPA3) Valid() error {
|
|
|
|
|
return p.Id.Valid()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type PersonIdSEPA2 struct {
|
|
|
|
|
Other RestrictedPersonIdSEPA `xml:"Othr"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *PersonIdSEPA2) Valid() error {
|
|
|
|
|
return p.Other.Valid()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type RestrictedPersonIdSEPA struct {
|
|
|
|
|
Id string `xml:"Id"` // RestrictedPersonIdentifierSEPA
|
|
|
|
|
SchemeName RestrictedPersonIdSchemeNameSEPA `xml:"SchmeNm"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *RestrictedPersonIdSEPA) Valid() error {
|
|
|
|
|
var err []string
|
|
|
|
|
if !SEPARegexps["Id"].MatchString(r.Id) {
|
|
|
|
|
err = append(err, "id of RestrictedPersonIdSEPA does not match format")
|
|
|
|
|
}
|
|
|
|
|
if e := r.SchemeName.Valid(); e != nil {
|
|
|
|
|
err = append(err, fmt.Sprintf("SchemeName not valid: %v", e))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(err) > 0 {
|
|
|
|
|
return fmt.Errorf("restricted person id SEPA not valid: %v", strings.Join(err, ", "))
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type RestrictedPersonIdSchemeNameSEPA struct {
|
|
|
|
|
Party string `xml:"Prty"` // IdentificationSchemeNameSEPA
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *RestrictedPersonIdSchemeNameSEPA) Valid() error {
|
|
|
|
|
if r.Party != "SEPA" {
|
|
|
|
|
return fmt.Errorf("party should be 'SEPA', got %v", r.Party)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|