You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

187 lines
4.4 KiB

package pain
import (
"fmt"
"strings"
)
type DrctDbtTxInf struct {
Id PaymentId `xml:"PmtId"`
Amount CurrencyWithAmount `xml:"InstdAmt"`
Transaction DrctDbtTx `xml:"DrctDbtTx"`
Agent DbtrAgt `xml:"DbtrAgt"`
Debtor Dbtr `xml:"Dbtr"`
Account DbtrAcct `xml:"DbtrAcct"`
Info RmtInf `xml:"RmtInf"`
}
func NewDirectDebitTransaction(debtor Dbtr, account DbtrAcct, mandateInfo MndtRltdInf, amount float64, additionalInfo string) DrctDbtTxInf {
e2eid := fmt.Sprintf("%v%4d", time.Now().Format("20060102"), 4) // TODO: inform this function of current number of transactions
return DrctDbtTxInf{
Id: PaymentId{
InstrumentId: "asdfasdf",
EndToEndId: e2eid,
},
Amount: CurrencyWithAmount{
Currency: "EUR",
Value: fmt.Sprintf("%.2f", amount),
},
Transaction: DrctDbtTx{
MandateRelatedInfo: mandateInfo,
},
Agent: DbtrAgt{
InstitutionId: FinInstnId{
BIC: "KNABNL2H", // fixme
},
},
Debtor: debtor,
Account: account,
Info: additionalInfo,
}
}
func (d *DrctDbtTxInf) Valid() error {
var err []string
if e := d.Id.Valid(); e != nil {
err = append(err, fmt.Sprintf("%v", e))
}
if e := d.Amount.Valid(); e != nil {
err = append(err, fmt.Sprintf("%v", e))
}
if e := d.Transaction.Valid(); e != nil {
err = append(err, fmt.Sprintf("%v", e))
}
if e := d.Agent.Valid(); e != nil {
err = append(err, fmt.Sprintf("%v", e))
}
if e := d.Debtor.Valid(); e != nil {
err = append(err, fmt.Sprintf("%v", e))
}
if e := d.Account.Valid(); e != nil {
err = append(err, fmt.Sprintf("%v", e))
}
if len(err) > 0 {
return fmt.Errorf("direct debit transaction information not valid: %v", strings.Join(err, ", "))
}
return nil
}
type CurrencyWithAmount struct {
Currency string `xml:"Ccy,attr"`
Value string `xml:",innerxml"`
}
func (c *CurrencyWithAmount) Valid() error {
var err []string
if c.Currency != "EUR" {
err = append(err, "expected Ccy EUR")
}
if !SEPARegexps["InstdAmnt"].MatchString(c.Value) {
err = append(err, "value does not match format")
}
if len(err) > 0 {
return fmt.Errorf("currency with amount not valid: %v", strings.Join(err, ", "))
}
return nil
}
type PaymentId struct {
InstrumentId string `xml:"InstrId"`
EndToEndId string `xml:"EndToEndId"`
}
func (p *PaymentId) Valid() error {
var err []string
if !SEPARegexps["InstrId"].MatchString(p.InstrumentId) {
err = append(err, "instrument id does not match format")
}
if !SEPARegexps["EndToEndId"].MatchString(p.EndToEndId) {
err = append(err, "end-to-end id does not match format")
}
if len(err) > 0 {
return fmt.Errorf("payment id not valid: %v", strings.Join(err, ", "))
}
return nil
}
type MndtRltdInf struct {
Id string `xml:"MndtId"`
SignatureDate string `xml:"DtOfSgntr"`
IsAmended bool `xml:"AmdmntInd"`
//AmdmntInfDtls is optional
//ElctrncSgntr is optional
}
func (m *MndtRltdInf) Valid() error {
var err []string
if !SEPARegexps["MndtId"].MatchString(m.Id) {
err = append(err, "mandate id does not match format")
}
if !SEPARegexps["DtOfSgntr"].MatchString(m.SignatureDate) {
err = append(err, "date of signature does not match format")
}
if len(err) > 0 {
return fmt.Errorf("mandate related information is not valid: %v", strings.Join(err, ", "))
}
return nil
}
type DrctDbtTx struct {
MandateRelatedInfo MndtRltdInf `xml:"MndtRltdInf"`
//CdtrSchemeId is optional
}
func (d *DrctDbtTx) Valid() error {
return d.MandateRelatedInfo.Valid()
}
type DbtrAgt struct {
InstitutionId FinInstnId `xml:"FinInstnId"`
}
func (d *DbtrAgt) Valid() error {
return d.InstitutionId.Valid()
}
type Dbtr struct {
Name string `xml:"Nm"`
Address PstlAdr `xml:"PstlAdr"`
}
func (d *Dbtr) Valid() error {
var err []string
if !SEPARegexps["Nm"].MatchString(d.Name) {
err = append(err, "name does not match format")
}
if e := d.Address.Valid(); e != nil {
err = append(err, fmt.Sprintf("%v", e))
}
if len(err) > 0 {
return fmt.Errorf("dbtr not valid: %v", strings.Join(err, ", "))
}
return nil
}
type DbtrAcct struct {
Id IBAN `xml:"IBAN"`
}
func (d *DbtrAcct) Valid() error {
return d.Id.Valid()
}
type RmtInf struct {
Value string `xml:"Ustrd"`
}
func (r *RmtInf) Valid() error {
if !SEPARegexps["Ustrd"].MatchString(r.Value) {
return fmt.Errorf("remittance information does not match format")
}
return nil
}