diff --git a/go.mod b/go.mod index 06eb29ce..edaf3859 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,6 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect github.com/kr/text v0.2.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.5.0 // indirect @@ -28,7 +27,6 @@ require ( github.com/prometheus/procfs v0.12.0 // indirect github.com/rickar/cal/v2 v2.1.13 // indirect golang.org/x/sys v0.16.0 // indirect - google.golang.org/appengine v1.6.8 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index b4954b37..e3dba404 100644 --- a/go.sum +++ b/go.sum @@ -14,11 +14,6 @@ github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= @@ -43,53 +38,14 @@ github.com/rickar/cal/v2 v2.1.13/go.mod h1:/fdlMcx7GjPlIBibMzOM9gMvDBsrK+mOtRXdT github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= -golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 h1:6R2FC06FonbXQ8pK11/PDFY6N6LWlf9KlzibaCapmqc= -golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= -golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw= -golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= -golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8= -golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/writer.go b/writer.go index 604556e2..878dfbe1 100644 --- a/writer.go +++ b/writer.go @@ -7,6 +7,9 @@ package wire import ( "bufio" "io" + "strings" + + "golang.org/x/exp/slices" ) // A Writer writes an fedWireMessage to an encoded file. @@ -81,466 +84,367 @@ func (w *Writer) Flush() error { } func (w *Writer) writeFEDWireMessage(file *File) error { - fwm := file.FEDWireMessage - if err := w.writeMandatory(fwm); err != nil { + var outputLines []string + + mandatoryLines, err := w.writeMandatory(fwm) + if err != nil { return err } + outputLines = append(outputLines, mandatoryLines...) - if err := w.writeOtherTransferInfo(fwm); err != nil { + otherTransferLines, err := w.writeOtherTransferInfo(fwm) + if err != nil { return err } + outputLines = append(outputLines, otherTransferLines...) - if err := w.writeBeneficiary(fwm); err != nil { + beneficiaryLines, err := w.writeBeneficiary(fwm) + if err != nil { return err } + outputLines = append(outputLines, beneficiaryLines...) - if err := w.writeOriginator(fwm); err != nil { + originatorLines, err := w.writeOriginator(fwm) + if err != nil { return err } + outputLines = append(outputLines, originatorLines...) - if err := w.writeFinancialInstitution(fwm); err != nil { + financialInstitutionLines, err := w.writeFinancialInstitution(fwm) + if err != nil { return err } + outputLines = append(outputLines, financialInstitutionLines...) - if err := w.writeCoverPayment(fwm); err != nil { + coverPaymentLines, err := w.writeCoverPayment(fwm) + if err != nil { return err } + outputLines = append(outputLines, coverPaymentLines...) if fwm.UnstructuredAddenda != nil { - if _, err := w.w.WriteString(fwm.UnstructuredAddenda.String() + w.NewlineCharacter); err != nil { - return err - } + outputLines = append(outputLines, fwm.UnstructuredAddenda.String()) } - if err := w.writeRemittance(fwm); err != nil { + remittanceLines, err := w.writeRemittance(fwm) + if err != nil { return err } + outputLines = append(outputLines, remittanceLines...) if fwm.ServiceMessage != nil { - if _, err := w.w.WriteString(fwm.ServiceMessage.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + outputLines = append(outputLines, fwm.ServiceMessage.Format(w.FormatOptions)) } - if err := w.writeFedAppended(fwm); err != nil { + fedAppendedLines, err := w.writeFedAppended(fwm) + if err != nil { return err } + outputLines = append(outputLines, fedAppendedLines...) + + slices.Sort(outputLines) + w.w.WriteString(strings.Join(outputLines, w.NewlineCharacter)) + w.w.WriteString(w.NewlineCharacter) return nil } -func (w *Writer) writeFedAppended(fwm FEDWireMessage) error { +func (w *Writer) writeFedAppended(fwm FEDWireMessage) ([]string, error) { + var lines []string if fwm.MessageDisposition != nil { - if _, err := w.w.WriteString(fwm.MessageDisposition.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.MessageDisposition.Format(w.FormatOptions)) } if fwm.ReceiptTimeStamp != nil { - if _, err := w.w.WriteString(fwm.ReceiptTimeStamp.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.ReceiptTimeStamp.Format(w.FormatOptions)) } if fwm.OutputMessageAccountabilityData != nil { - if _, err := w.w.WriteString(fwm.OutputMessageAccountabilityData.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.OutputMessageAccountabilityData.Format(w.FormatOptions)) } if fwm.ErrorWire != nil { - if _, err := w.w.WriteString(fwm.ErrorWire.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.ErrorWire.Format(w.FormatOptions)) } - return nil + return lines, nil } -func (w *Writer) writeMandatory(fwm FEDWireMessage) error { +func (w *Writer) writeMandatory(fwm FEDWireMessage) ([]string, error) { + var lines []string if fwm.SenderSupplied != nil { - if _, err := w.w.WriteString(fwm.SenderSupplied.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.SenderSupplied.Format(w.FormatOptions)) } else { if fwm.requireSenderSupplied() { - return fieldError("SenderSupplied", ErrFieldRequired) + return nil, fieldError("SenderSupplied", ErrFieldRequired) } } if fwm.TypeSubType != nil { - if _, err := w.w.WriteString(fwm.TypeSubType.String() + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.TypeSubType.String()) } else { - return fieldError("TypeSubType", ErrFieldRequired) + return nil, fieldError("TypeSubType", ErrFieldRequired) } if fwm.InputMessageAccountabilityData != nil { - if _, err := w.w.WriteString(fwm.InputMessageAccountabilityData.String() + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.InputMessageAccountabilityData.String()) } else { - return fieldError("InputMessageAccountabilityData", ErrFieldRequired) + return nil, fieldError("InputMessageAccountabilityData", ErrFieldRequired) } if fwm.Amount != nil { - if _, err := w.w.WriteString(fwm.Amount.String() + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.Amount.String()) } else { - return fieldError("Amount", ErrFieldRequired) + return nil, fieldError("Amount", ErrFieldRequired) } if fwm.SenderDepositoryInstitution != nil { - if _, err := w.w.WriteString(fwm.SenderDepositoryInstitution.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.SenderDepositoryInstitution.Format(w.FormatOptions)) } else { - return fieldError("SenderDepositoryInstitution", ErrFieldRequired) + return nil, fieldError("SenderDepositoryInstitution", ErrFieldRequired) } if fwm.ReceiverDepositoryInstitution != nil { - if _, err := w.w.WriteString(fwm.ReceiverDepositoryInstitution.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.ReceiverDepositoryInstitution.Format(w.FormatOptions)) } else { - return fieldError("ReceiverDepositoryInstitution", ErrFieldRequired) + return nil, fieldError("ReceiverDepositoryInstitution", ErrFieldRequired) } if fwm.BusinessFunctionCode != nil { - if _, err := w.w.WriteString(fwm.BusinessFunctionCode.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.BusinessFunctionCode.Format(w.FormatOptions)) } else { - return fieldError("ReceiverDepositoryInstitution", ErrFieldRequired) + return nil, fieldError("ReceiverDepositoryInstitution", ErrFieldRequired) } - return nil + return lines, nil } -func (w *Writer) writeOtherTransferInfo(fwm FEDWireMessage) error { +func (w *Writer) writeOtherTransferInfo(fwm FEDWireMessage) ([]string, error) { + var lines []string if fwm.SenderReference != nil { - if _, err := w.w.WriteString(fwm.SenderReference.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.SenderReference.Format(w.FormatOptions)) } if fwm.PreviousMessageIdentifier != nil { - if _, err := w.w.WriteString(fwm.PreviousMessageIdentifier.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.PreviousMessageIdentifier.Format(w.FormatOptions)) } if fwm.LocalInstrument != nil { - if _, err := w.w.WriteString(fwm.LocalInstrument.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.LocalInstrument.Format(w.FormatOptions)) } if fwm.PaymentNotification != nil { - if _, err := w.w.WriteString(fwm.PaymentNotification.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.PaymentNotification.Format(w.FormatOptions)) } if fwm.Charges != nil { - if _, err := w.w.WriteString(fwm.Charges.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.Charges.Format(w.FormatOptions)) } if fwm.InstructedAmount != nil { - if _, err := w.w.WriteString(fwm.InstructedAmount.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.InstructedAmount.Format(w.FormatOptions)) } if fwm.ExchangeRate != nil { - if _, err := w.w.WriteString(fwm.ExchangeRate.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.ExchangeRate.Format(w.FormatOptions)) } - return nil + return lines, nil } -func (w *Writer) writeBeneficiary(fwm FEDWireMessage) error { +func (w *Writer) writeBeneficiary(fwm FEDWireMessage) ([]string, error) { + var lines []string if fwm.BeneficiaryIntermediaryFI != nil { - if _, err := w.w.WriteString(fwm.BeneficiaryIntermediaryFI.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.BeneficiaryIntermediaryFI.Format(w.FormatOptions)) } if fwm.BeneficiaryFI != nil { - if fwm.BeneficiaryFI != nil { - if _, err := w.w.WriteString(fwm.BeneficiaryFI.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } - } + lines = append(lines, fwm.BeneficiaryFI.Format(w.FormatOptions)) } if fwm.Beneficiary != nil { - if fwm.Beneficiary != nil { - if _, err := w.w.WriteString(fwm.Beneficiary.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } - } + lines = append(lines, fwm.Beneficiary.Format(w.FormatOptions)) } if fwm.BeneficiaryReference != nil { - if fwm.BeneficiaryReference != nil { - if _, err := w.w.WriteString(fwm.BeneficiaryReference.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } - } + lines = append(lines, fwm.BeneficiaryReference.Format(w.FormatOptions)) } if fwm.AccountDebitedDrawdown != nil { - if fwm.AccountDebitedDrawdown != nil { - if _, err := w.w.WriteString(fwm.AccountDebitedDrawdown.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } - } + lines = append(lines, fwm.AccountDebitedDrawdown.Format(w.FormatOptions)) } - return nil + return lines, nil } -func (w *Writer) writeOriginator(fwm FEDWireMessage) error { +func (w *Writer) writeOriginator(fwm FEDWireMessage) ([]string, error) { + var lines []string if fwm.Originator != nil { - if _, err := w.w.WriteString(fwm.Originator.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.Originator.Format(w.FormatOptions)) } if fwm.OriginatorOptionF != nil { - if _, err := w.w.WriteString(fwm.OriginatorOptionF.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.OriginatorOptionF.Format(w.FormatOptions)) } if fwm.OriginatorFI != nil { - if _, err := w.w.WriteString(fwm.OriginatorFI.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.OriginatorFI.Format(w.FormatOptions)) } if fwm.InstructingFI != nil { - if _, err := w.w.WriteString(fwm.InstructingFI.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.InstructingFI.Format(w.FormatOptions)) } if fwm.AccountCreditedDrawdown != nil { - if _, err := w.w.WriteString(fwm.AccountCreditedDrawdown.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.AccountCreditedDrawdown.Format(w.FormatOptions)) } if fwm.OriginatorToBeneficiary != nil { - if _, err := w.w.WriteString(fwm.OriginatorToBeneficiary.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.OriginatorToBeneficiary.Format(w.FormatOptions)) } - return nil + return lines, nil } -func (w *Writer) writeFinancialInstitution(fwm FEDWireMessage) error { +func (w *Writer) writeFinancialInstitution(fwm FEDWireMessage) ([]string, error) { + var lines []string if fwm.FIReceiverFI != nil { - if _, err := w.w.WriteString(fwm.FIReceiverFI.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.FIReceiverFI.Format(w.FormatOptions)) } if fwm.FIDrawdownDebitAccountAdvice != nil { - if _, err := w.w.WriteString(fwm.FIDrawdownDebitAccountAdvice.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.FIDrawdownDebitAccountAdvice.Format(w.FormatOptions)) } if fwm.FIIntermediaryFI != nil { - if _, err := w.w.WriteString(fwm.FIIntermediaryFI.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.FIIntermediaryFI.Format(w.FormatOptions)) } if fwm.FIIntermediaryFIAdvice != nil { - if _, err := w.w.WriteString(fwm.FIIntermediaryFIAdvice.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.FIIntermediaryFIAdvice.Format(w.FormatOptions)) } if fwm.FIBeneficiaryFI != nil { - if _, err := w.w.WriteString(fwm.FIBeneficiaryFI.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.FIBeneficiaryFI.Format(w.FormatOptions)) } if fwm.FIBeneficiaryFIAdvice != nil { - if _, err := w.w.WriteString(fwm.FIBeneficiaryFIAdvice.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.FIBeneficiaryFIAdvice.Format(w.FormatOptions)) } if fwm.FIBeneficiary != nil { - if _, err := w.w.WriteString(fwm.FIBeneficiary.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.FIBeneficiary.Format(w.FormatOptions)) } if fwm.FIBeneficiaryAdvice != nil { - if _, err := w.w.WriteString(fwm.FIBeneficiaryAdvice.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.FIBeneficiaryAdvice.Format(w.FormatOptions)) } if fwm.FIPaymentMethodToBeneficiary != nil { - if _, err := w.w.WriteString(fwm.FIPaymentMethodToBeneficiary.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.FIPaymentMethodToBeneficiary.Format(w.FormatOptions)) } if fwm.FIAdditionalFIToFI != nil { - if _, err := w.w.WriteString(fwm.FIAdditionalFIToFI.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.FIAdditionalFIToFI.Format(w.FormatOptions)) } - return nil + return lines, nil } -func (w *Writer) writeCoverPayment(fwm FEDWireMessage) error { +func (w *Writer) writeCoverPayment(fwm FEDWireMessage) ([]string, error) { + var lines []string if fwm.CurrencyInstructedAmount != nil { - if _, err := w.w.WriteString(fwm.CurrencyInstructedAmount.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.CurrencyInstructedAmount.Format(w.FormatOptions)) } if fwm.OrderingCustomer != nil { - if _, err := w.w.WriteString(fwm.OrderingCustomer.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.OrderingCustomer.Format(w.FormatOptions)) } if fwm.OrderingInstitution != nil { - if _, err := w.w.WriteString(fwm.OrderingInstitution.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.OrderingInstitution.Format(w.FormatOptions)) } if fwm.IntermediaryInstitution != nil { - if _, err := w.w.WriteString(fwm.IntermediaryInstitution.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.IntermediaryInstitution.Format(w.FormatOptions)) } if fwm.InstitutionAccount != nil { - if _, err := w.w.WriteString(fwm.InstitutionAccount.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.InstitutionAccount.Format(w.FormatOptions)) } if fwm.BeneficiaryCustomer != nil { - if _, err := w.w.WriteString(fwm.BeneficiaryCustomer.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.BeneficiaryCustomer.Format(w.FormatOptions)) } if fwm.Remittance != nil { - if _, err := w.w.WriteString(fwm.Remittance.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.Remittance.Format(w.FormatOptions)) } if fwm.SenderToReceiver != nil { - if _, err := w.w.WriteString(fwm.SenderToReceiver.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.SenderToReceiver.Format(w.FormatOptions)) } - return nil + return lines, nil } -func (w *Writer) writeRemittance(fwm FEDWireMessage) error { +func (w *Writer) writeRemittance(fwm FEDWireMessage) ([]string, error) { + var lines []string // Related Remittance if fwm.RelatedRemittance != nil { - if _, err := w.w.WriteString(fwm.RelatedRemittance.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.RelatedRemittance.Format(w.FormatOptions)) } // Structured Remittance if fwm.RemittanceOriginator != nil { - if _, err := w.w.WriteString(fwm.RemittanceOriginator.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.RemittanceOriginator.Format(w.FormatOptions)) } if fwm.RemittanceBeneficiary != nil { - if _, err := w.w.WriteString(fwm.RemittanceBeneficiary.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.RemittanceBeneficiary.Format(w.FormatOptions)) } if fwm.PrimaryRemittanceDocument != nil { - if _, err := w.w.WriteString(fwm.PrimaryRemittanceDocument.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.PrimaryRemittanceDocument.Format(w.FormatOptions)) } if fwm.ActualAmountPaid != nil { - if _, err := w.w.WriteString(fwm.ActualAmountPaid.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.ActualAmountPaid.Format(w.FormatOptions)) } if fwm.GrossAmountRemittanceDocument != nil { - if _, err := w.w.WriteString(fwm.GrossAmountRemittanceDocument.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.GrossAmountRemittanceDocument.Format(w.FormatOptions)) } if fwm.AmountNegotiatedDiscount != nil { - if _, err := w.w.WriteString(fwm.AmountNegotiatedDiscount.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.AmountNegotiatedDiscount.Format(w.FormatOptions)) } if fwm.Adjustment != nil { - if _, err := w.w.WriteString(fwm.Adjustment.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.Adjustment.Format(w.FormatOptions)) } if fwm.DateRemittanceDocument != nil { - if _, err := w.w.WriteString(fwm.DateRemittanceDocument.String() + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.DateRemittanceDocument.String()) } if fwm.SecondaryRemittanceDocument != nil { - if _, err := w.w.WriteString(fwm.SecondaryRemittanceDocument.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.SecondaryRemittanceDocument.Format(w.FormatOptions)) } if fwm.RemittanceFreeText != nil { - if _, err := w.w.WriteString(fwm.RemittanceFreeText.Format(w.FormatOptions) + w.NewlineCharacter); err != nil { - return err - } + lines = append(lines, fwm.RemittanceFreeText.Format(w.FormatOptions)) } - return nil + return lines, nil } diff --git a/writer_test.go b/writer_test.go index 76a76ede..312b1be0 100644 --- a/writer_test.go +++ b/writer_test.go @@ -356,6 +356,18 @@ func TestFEDWireMessageWriteCustomerTransfer(t *testing.T) { file.AddFEDWireMessage(fwm) require.NoError(t, writeFile(file)) + + // Verify the exact tags written + tags := getTagsFromContents(t, file) + expected := []string{ + "{1500}", "{1510}", "{1520}", + "{2000}", + "{3100}", "{3320}", "{3400}", "{3500}", "{3600}", "{3700}", "{3710}", "{3720}", + "{4000}", "{4100}", "{4200}", "{4320}", + "{5000}", "{5100}", "{5200}", + "{6000}", "{6100}", "{6200}", "{6210}", "{6300}", "{6310}", "{6400}", "{6410}", "{6420}", "{6500}", + } + require.Equal(t, expected, tags) } // TestFEDWireMessageWriteCustomerTransferPlus writes a FEDWireMessage to a file with BusinessFunctionCode = CTP @@ -1005,6 +1017,35 @@ func TestFEDWireMessageWriteServiceMessage(t *testing.T) { require.NoError(t, writeFile(file)) } +func getTagsFromContents(t *testing.T, file *File) []string { + t.Helper() + + err := file.Create() + if err != nil { + t.Fatal(err) + } + + err = file.Validate() + if err != nil { + t.Fatal(err) + } + + var buf bytes.Buffer + err = NewWriter(&buf).Write(file) + if err != nil { + t.Fatal(err) + } + + lines := strings.Split(strings.TrimSpace(buf.String()), "\n") + for i := range lines { + idx := strings.Index(lines[i], "}") + if idx > 0 { + lines[i] = strings.TrimSpace(lines[i][:idx+1]) + } + } + return lines +} + // writeFile writes a FEDWireMessage File and ensures the File can be read func writeFile(file *File) error { if err := file.Create(); err != nil {