|
|
|
@ -10,6 +10,7 @@ var ( |
|
|
|
SEPARegexps = map[string]*regexp.Regexp{ |
|
|
|
"MsgId": RestrictedIdentificationSEPA1, |
|
|
|
"CreDtTm": ISODateTime, |
|
|
|
"ReqdColltnDt": ISODateTime, |
|
|
|
"NbOfTxs": Max15NumericText, |
|
|
|
"CtrlSum": RestrictedDecimalNumber, |
|
|
|
"Nm": Max70Text, |
|
|
|
@ -18,6 +19,7 @@ var ( |
|
|
|
"PmtMetaSvcLvl": ServiceLevelSEPACode, |
|
|
|
"PmtMetaLclInstrm": LocalInstrumentSEPACode, |
|
|
|
"SeqTp": SequenceType1Code, |
|
|
|
"IBAN": IBAN2007Identifier, |
|
|
|
} |
|
|
|
) |
|
|
|
|
|
|
|
@ -68,16 +70,10 @@ func (g *GrpHdr) Valid() error { |
|
|
|
if !SEPARegexps["CtrlSum"].MatchString(g.Sum) { |
|
|
|
err = append(err, "sum did not match expected format") |
|
|
|
} |
|
|
|
// TODO
|
|
|
|
/* |
|
|
|
if g.InitiatingParty == nil { |
|
|
|
err = append(err, "no initiating party found") |
|
|
|
} else { |
|
|
|
if !SEPARegexps["Nm"].MatchString(g.InitiatingParty.Name) { |
|
|
|
err = append(err, "initiating party's name did not match expected format") |
|
|
|
} |
|
|
|
} |
|
|
|
*/ |
|
|
|
// Note: we assume g.InitiatingParty is initialized.
|
|
|
|
if !SEPARegexps["Nm"].MatchString(g.InitiatingParty.Name) { |
|
|
|
err = append(err, "initiating party's name did not match expected format") |
|
|
|
} |
|
|
|
|
|
|
|
if len(err) > 0 { |
|
|
|
return fmt.Errorf("group header not valid: %v", strings.Join(err, ", ")) |
|
|
|
@ -86,9 +82,12 @@ func (g *GrpHdr) Valid() error { |
|
|
|
} |
|
|
|
|
|
|
|
type PmtInf struct { |
|
|
|
Id string `xml:"PmtInfId"` |
|
|
|
Method string `xml:"PmtMtd"` |
|
|
|
PaymentMeta PmtTpInf `xml:"PmtTpInf"` |
|
|
|
Id string `xml:"PmtInfId"` |
|
|
|
Method string `xml:"PmtMtd"` |
|
|
|
PaymentMeta PmtTpInf `xml:"PmtTpInf"` |
|
|
|
CollectionDate string `xml:"ReqdColltnDt"` |
|
|
|
Creditor Cdtr `xml:"Cdtr"` |
|
|
|
CreditorAccount CdtrAcct `xml:"CdtrAcct"` |
|
|
|
} |
|
|
|
|
|
|
|
func (pmt *PmtInf) Valid() error { |
|
|
|
@ -97,11 +96,20 @@ func (pmt *PmtInf) Valid() error { |
|
|
|
err = append(err, "payment info id does not match expected format") |
|
|
|
} |
|
|
|
if !SEPARegexps["PmtMtd"].MatchString(pmt.Method) { |
|
|
|
err = append(err, "payment info id does not match expected format") |
|
|
|
err = append(err, "payment method does not match expected format") |
|
|
|
} |
|
|
|
if e := pmt.PaymentMeta.Valid(); e != nil { |
|
|
|
err = append(err, fmt.Sprintf("payment meta not valid: %v", e)) |
|
|
|
} |
|
|
|
if !SEPARegexps["ReqdColltnDt"].MatchString(pmt.CollectionDate) { |
|
|
|
err = append(err, "payment collection date does not match expected format") |
|
|
|
} |
|
|
|
if e := pmt.Creditor.Valid(); e != nil { |
|
|
|
err = append(err, fmt.Sprintf("payment creditor not valid: %v", e)) |
|
|
|
} |
|
|
|
if e := pmt.CreditorAccount.Valid(); e != nil { |
|
|
|
err = append(err, fmt.Sprintf("payment creditor account not valid: %v", e)) |
|
|
|
} |
|
|
|
|
|
|
|
if len(err) > 0 { |
|
|
|
return fmt.Errorf("payment info (Id: %q) not valid: %v", pmt.Id, strings.Join(err, ", ")) |
|
|
|
@ -115,6 +123,76 @@ type PmtTpInf struct { |
|
|
|
SequenceType string `xml:"SeqTp"` |
|
|
|
} |
|
|
|
|
|
|
|
type Cdtr struct { |
|
|
|
Name string `xml:"Nm"` |
|
|
|
PostalAddress PstlAddr `xml:"PstlAddr"` |
|
|
|
} |
|
|
|
|
|
|
|
func (c *Cdtr) Valid() error { |
|
|
|
var err []string |
|
|
|
if !SEPARegexps["Nm"].MatchString(c.Name) { |
|
|
|
err = append(err, "creditor name does not match format") |
|
|
|
} |
|
|
|
if e := c.PostalAddress.Valid(); e != nil { |
|
|
|
err = append(err, fmt.Sprintf("creditor postal address not valid: %v", e)) |
|
|
|
} |
|
|
|
|
|
|
|
if len(err) > 0 { |
|
|
|
return fmt.Errorf("creditor (Nm: %q) not valid: %v", c.Name, strings.Join(err, ", ")) |
|
|
|
} |
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
type PstlAddr struct { |
|
|
|
Country string `xml:"Ctry"` |
|
|
|
AddressLines []AdrLine `xml:"AdrLine"` |
|
|
|
} |
|
|
|
|
|
|
|
func (p *PstlAddr) Valid() error { |
|
|
|
var err []string |
|
|
|
if !SEPARegexps["Ctry"].MatchString(p.Country) { |
|
|
|
err = append(err, "country does not match format") |
|
|
|
} |
|
|
|
if len(p.AddressLines) > 2 { |
|
|
|
err = append(err, "expected at most 2 address lines") |
|
|
|
} |
|
|
|
for i, line := range p.AddressLines { |
|
|
|
if !SEPARegexps["AdrLine"].MatchString(string(line)) { |
|
|
|
err = append(err, fmt.Sprintf("address line %d (%q) does not match format", i, line)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if len(err) > 0 { |
|
|
|
return fmt.Errorf("address not valid: %v", strings.Join(err, ", ")) |
|
|
|
} |
|
|
|
|
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
type AdrLine string |
|
|
|
|
|
|
|
type CdtrAcct struct { |
|
|
|
Id IBAN `xml:"Id"` |
|
|
|
} |
|
|
|
|
|
|
|
type IBAN struct { |
|
|
|
IBAN string `xml:"IBAN"` |
|
|
|
} |
|
|
|
|
|
|
|
func (c *CdtrAcct) Valid() error { |
|
|
|
if e := c.Id.Valid(); e != nil { |
|
|
|
return fmt.Errorf("creditor account id not valid: %v", e) |
|
|
|
} |
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
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"` |
|
|
|
} |
|
|
|
@ -144,4 +222,5 @@ type TxInf struct { |
|
|
|
|
|
|
|
type InitgPty struct { |
|
|
|
Name string `xml:"Nm"` |
|
|
|
// We do not implement the "Id" element from "PartyIdentificationSEPA1"
|
|
|
|
} |
|
|
|
|