package pain import ( "fmt" "strings" ) type PmtInf struct { Id string `xml:"PmtInfId"` Method string `xml:"PmtMtd"` PaymentMeta PmtTpInf `xml:"PmtTpInf"` CollectionDate string `xml:"ReqdColltnDt"` Creditor Cdtr `xml:"Cdtr"` CreditorAccount CdtrAcct `xml:"CdtrAcct"` CreditorAgent CdtrAgt `xml:"CdtrAgt"` SchemeId CdtrSchmeId `xml:"CdtrSchmeId"` Transactions []DrctDbtTxInf `xml:"DrctDbtTxInf"` } func (pmt *PmtInf) Valid() error { var err []string if !SEPARegexps["PmtInfId"].MatchString(pmt.Id) { err = append(err, "payment info id does not match expected format") } if !SEPARegexps["PmtMtd"].MatchString(pmt.Method) { 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 e := pmt.CreditorAgent.Valid(); e != nil { err = append(err, fmt.Sprintf("payment creditor agent not valid: %v", e)) } if e := pmt.SchemeId.Valid(); e != nil { err = append(err, fmt.Sprintf("payment scheme id not valid: %v", e)) } if len(pmt.Transactions) == 0 { err = append(err, fmt.Sprintf("need at least 1 transaction")) } if len(err) > 0 { return fmt.Errorf("payment info (Id: %q) not valid: %v", pmt.Id, strings.Join(err, ", ")) } return nil } type PmtTpInf struct { ServiceLevel Code `xml:"SvcLvl"` LocalInstrument Code `xml:"LclIntrm"` SequenceType string `xml:"SeqTp"` } type Cdtr struct { Name string `xml:"Nm"` PostalAddress PstlAdr `xml:"PstlAdr"` } 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 AdrLine string type PstlAdr struct { Country string `xml:"Ctry"` AddressLines []AdrLine `xml:"AdrLine"` } func (p *PstlAdr) 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 CdtrAgt struct { InstitutionId FinInstnId `xml:"FinInstId"` } func (c *CdtrAgt) Valid() error { return c.InstitutionId.Valid() } type FinInstnId struct { BIC string `xml:"BIC"` } func (f *FinInstnId) Valid() error { if !SEPARegexps["BIC"].MatchString(f.BIC) { return fmt.Errorf("BIC not in expected format") } return nil } type CdtrSchmeId struct { Id PartyIdSEPA3 `xml:"Id"` } func (c *CdtrSchmeId) Valid() error { return c.Id.Valid() }