mirror of
https://github.com/aclindsa/ofxgo.git
synced 2024-11-22 03:30:04 -05:00
Add Type() to Message interface, check types when marshalling requests
This commit is contained in:
parent
85684883c6
commit
d822179446
@ -28,6 +28,10 @@ func (r *StatementRequest) Valid() (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *StatementRequest) Type() messageType {
|
||||||
|
return BankRq
|
||||||
|
}
|
||||||
|
|
||||||
type Payee struct {
|
type Payee struct {
|
||||||
XMLName xml.Name `xml:"PAYEE"`
|
XMLName xml.Name `xml:"PAYEE"`
|
||||||
Name String `xml:"NAME"`
|
Name String `xml:"NAME"`
|
||||||
@ -155,6 +159,10 @@ func (sr StatementResponse) Valid() (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sr StatementResponse) Type() messageType {
|
||||||
|
return BankRs
|
||||||
|
}
|
||||||
|
|
||||||
func decodeBankingMessageSet(d *xml.Decoder, start xml.StartElement) ([]Message, error) {
|
func decodeBankingMessageSet(d *xml.Decoder, start xml.StartElement) ([]Message, error) {
|
||||||
var msgs []Message
|
var msgs []Message
|
||||||
for {
|
for {
|
||||||
|
108
common.go
108
common.go
@ -5,11 +5,115 @@ import (
|
|||||||
"github.com/aclindsa/go/src/encoding/xml"
|
"github.com/aclindsa/go/src/encoding/xml"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Represents a top-level OFX message set (i.e. BANKMSGSRSV1)
|
// Represents an OFX message in a message set
|
||||||
type Message interface {
|
type Message interface {
|
||||||
Name() string // The name of the OFX element this set represents
|
Name() string // The name of the OFX transaction wrapper element this represents
|
||||||
Valid() (bool, error) // Called before a Message is marshaled and after
|
Valid() (bool, error) // Called before a Message is marshaled and after
|
||||||
// it's unmarshaled to ensure the request or response is valid
|
// it's unmarshaled to ensure the request or response is valid
|
||||||
|
Type() messageType // The message set this message belongs to
|
||||||
|
}
|
||||||
|
|
||||||
|
type messageType uint
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Requests
|
||||||
|
SignonRq messageType = iota
|
||||||
|
SignupRq
|
||||||
|
BankRq
|
||||||
|
CreditCardRq
|
||||||
|
LoanRq
|
||||||
|
InvStmtRq
|
||||||
|
InterXferRq
|
||||||
|
WireXferRq
|
||||||
|
BillpayRq
|
||||||
|
EmailRq
|
||||||
|
SecListRq
|
||||||
|
PresDirRq
|
||||||
|
PresDlvRq
|
||||||
|
ProfileRq
|
||||||
|
ImageRq
|
||||||
|
// Responses
|
||||||
|
SignonRs
|
||||||
|
SignupRs
|
||||||
|
BankRs
|
||||||
|
CreditCardRs
|
||||||
|
LoanRs
|
||||||
|
InvStmtRs
|
||||||
|
InterXferRs
|
||||||
|
WireXferRs
|
||||||
|
BillpayRs
|
||||||
|
EmailRs
|
||||||
|
SecListRs
|
||||||
|
PresDirRs
|
||||||
|
PresDlvRs
|
||||||
|
ProfileRs
|
||||||
|
ImageRs
|
||||||
|
)
|
||||||
|
|
||||||
|
func (t messageType) String() string {
|
||||||
|
switch t {
|
||||||
|
case SignonRq:
|
||||||
|
return "SIGNONMSGSRQV1"
|
||||||
|
case SignupRq:
|
||||||
|
return "SIGNUPMSGSRQV1"
|
||||||
|
case BankRq:
|
||||||
|
return "BANKMSGSRQV1"
|
||||||
|
case CreditCardRq:
|
||||||
|
return "CREDITCARDMSGSRQV1"
|
||||||
|
case LoanRq:
|
||||||
|
return "LOANMSGSRQV1"
|
||||||
|
case InvStmtRq:
|
||||||
|
return "INVSTMTMSGSRQV1"
|
||||||
|
case InterXferRq:
|
||||||
|
return "INTERXFERMSGSRQV1"
|
||||||
|
case WireXferRq:
|
||||||
|
return "WIREXFERMSGSRQV1"
|
||||||
|
case BillpayRq:
|
||||||
|
return "BILLPAYMSGSRQV1"
|
||||||
|
case EmailRq:
|
||||||
|
return "EMAILMSGSRQV1"
|
||||||
|
case SecListRq:
|
||||||
|
return "SECLISTMSGSRQV1"
|
||||||
|
case PresDirRq:
|
||||||
|
return "PRESDIRMSGSRQV1"
|
||||||
|
case PresDlvRq:
|
||||||
|
return "PRESDLVMSGSRQV1"
|
||||||
|
case ProfileRq:
|
||||||
|
return "PROFMSGSRQV1"
|
||||||
|
case ImageRq:
|
||||||
|
return "IMAGEMSGSRQV1"
|
||||||
|
case SignonRs:
|
||||||
|
return "SIGNONMSGSRSV1"
|
||||||
|
case SignupRs:
|
||||||
|
return "SIGNUPMSGSRSV1"
|
||||||
|
case BankRs:
|
||||||
|
return "BANKMSGSRSV1"
|
||||||
|
case CreditCardRs:
|
||||||
|
return "CREDITCARDMSGSRSV1"
|
||||||
|
case LoanRs:
|
||||||
|
return "LOANMSGSRSV1"
|
||||||
|
case InvStmtRs:
|
||||||
|
return "INVSTMTMSGSRSV1"
|
||||||
|
case InterXferRs:
|
||||||
|
return "INTERXFERMSGSRSV1"
|
||||||
|
case WireXferRs:
|
||||||
|
return "WIREXFERMSGSRSV1"
|
||||||
|
case BillpayRs:
|
||||||
|
return "BILLPAYMSGSRSV1"
|
||||||
|
case EmailRs:
|
||||||
|
return "EMAILMSGSRSV1"
|
||||||
|
case SecListRs:
|
||||||
|
return "SECLISTMSGSRSV1"
|
||||||
|
case PresDirRs:
|
||||||
|
return "PRESDIRMSGSRSV1"
|
||||||
|
case PresDlvRs:
|
||||||
|
return "PRESDLVMSGSRSV1"
|
||||||
|
case ProfileRs:
|
||||||
|
return "PROFMSGSRSV1"
|
||||||
|
case ImageRs:
|
||||||
|
return "IMAGEMSGSRSV1"
|
||||||
|
}
|
||||||
|
panic("Invalid messageType")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map of error codes to their meanings, SEVERITY, and conditions under which
|
// Map of error codes to their meanings, SEVERITY, and conditions under which
|
||||||
|
@ -28,6 +28,10 @@ func (r *CCStatementRequest) Valid() (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *CCStatementRequest) Type() messageType {
|
||||||
|
return CreditCardRq
|
||||||
|
}
|
||||||
|
|
||||||
type CCStatementResponse struct {
|
type CCStatementResponse struct {
|
||||||
XMLName xml.Name `xml:"CCSTMTTRNRS"`
|
XMLName xml.Name `xml:"CCSTMTTRNRS"`
|
||||||
TrnUID UID `xml:"TRNUID"`
|
TrnUID UID `xml:"TRNUID"`
|
||||||
@ -62,6 +66,10 @@ func (sr CCStatementResponse) Valid() (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sr CCStatementResponse) Type() messageType {
|
||||||
|
return CreditCardRs
|
||||||
|
}
|
||||||
|
|
||||||
func decodeCCMessageSet(d *xml.Decoder, start xml.StartElement) ([]Message, error) {
|
func decodeCCMessageSet(d *xml.Decoder, start xml.StartElement) ([]Message, error) {
|
||||||
var msgs []Message
|
var msgs []Message
|
||||||
for {
|
for {
|
||||||
|
@ -33,6 +33,10 @@ func (r *InvStatementRequest) Valid() (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *InvStatementRequest) Type() messageType {
|
||||||
|
return InvStmtRq
|
||||||
|
}
|
||||||
|
|
||||||
type InvTran struct {
|
type InvTran struct {
|
||||||
XMLName xml.Name `xml:"INVTRAN"`
|
XMLName xml.Name `xml:"INVTRAN"`
|
||||||
FiTId String `xml:"FITID"`
|
FiTId String `xml:"FITID"`
|
||||||
@ -816,6 +820,10 @@ func (sr InvStatementResponse) Valid() (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sr InvStatementResponse) Type() messageType {
|
||||||
|
return InvStmtRs
|
||||||
|
}
|
||||||
|
|
||||||
func decodeInvestmentsMessageSet(d *xml.Decoder, start xml.StartElement) ([]Message, error) {
|
func decodeInvestmentsMessageSet(d *xml.Decoder, start xml.StartElement) ([]Message, error) {
|
||||||
var msgs []Message
|
var msgs []Message
|
||||||
for {
|
for {
|
||||||
|
@ -25,6 +25,10 @@ func (r *ProfileRequest) Valid() (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *ProfileRequest) Type() messageType {
|
||||||
|
return ProfileRq
|
||||||
|
}
|
||||||
|
|
||||||
type SignonInfo struct {
|
type SignonInfo struct {
|
||||||
XMLName xml.Name `xml:"SIGNONINFO"`
|
XMLName xml.Name `xml:"SIGNONINFO"`
|
||||||
SignonRealm String `xml:"SIGNONREALM"`
|
SignonRealm String `xml:"SIGNONREALM"`
|
||||||
@ -130,6 +134,10 @@ func (pr ProfileResponse) Valid() (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pr ProfileResponse) Type() messageType {
|
||||||
|
return ProfileRs
|
||||||
|
}
|
||||||
|
|
||||||
func decodeProfileMessageSet(d *xml.Decoder, start xml.StartElement) ([]Message, error) {
|
func decodeProfileMessageSet(d *xml.Decoder, start xml.StartElement) ([]Message, error) {
|
||||||
var msgs []Message
|
var msgs []Message
|
||||||
for {
|
for {
|
||||||
|
21
request.go
21
request.go
@ -29,14 +29,17 @@ type Request struct {
|
|||||||
indent bool // Whether to indent the marshaled XML
|
indent bool // Whether to indent the marshaled XML
|
||||||
}
|
}
|
||||||
|
|
||||||
func marshalMessageSet(e *xml.Encoder, requests []Message, setname string) error {
|
func marshalMessageSet(e *xml.Encoder, requests []Message, set messageType) error {
|
||||||
if len(requests) > 0 {
|
if len(requests) > 0 {
|
||||||
messageSetElement := xml.StartElement{Name: xml.Name{Local: setname}}
|
messageSetElement := xml.StartElement{Name: xml.Name{Local: set.String()}}
|
||||||
if err := e.EncodeToken(messageSetElement); err != nil {
|
if err := e.EncodeToken(messageSetElement); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, request := range requests {
|
for _, request := range requests {
|
||||||
|
if request.Type() != set {
|
||||||
|
return errors.New("Expected " + set.String() + " message , found " + request.Type().String())
|
||||||
|
}
|
||||||
if ok, err := request.Valid(); !ok {
|
if ok, err := request.Valid(); !ok {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -104,7 +107,7 @@ NEWFILEUID:NONE
|
|||||||
if ok, err := oq.Signon.Valid(); !ok {
|
if ok, err := oq.Signon.Valid(); !ok {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
signonMsgSet := xml.StartElement{Name: xml.Name{Local: "SIGNONMSGSRQV1"}}
|
signonMsgSet := xml.StartElement{Name: xml.Name{Local: SignonRq.String()}}
|
||||||
if err := encoder.EncodeToken(signonMsgSet); err != nil {
|
if err := encoder.EncodeToken(signonMsgSet); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -115,22 +118,22 @@ NEWFILEUID:NONE
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := marshalMessageSet(encoder, oq.Signup, "SIGNUPMSGSRQV1"); err != nil {
|
if err := marshalMessageSet(encoder, oq.Signup, SignupRq); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := marshalMessageSet(encoder, oq.Banking, "BANKMSGSRQV1"); err != nil {
|
if err := marshalMessageSet(encoder, oq.Banking, BankRq); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := marshalMessageSet(encoder, oq.CreditCards, "CREDITCARDMSGSRQV1"); err != nil {
|
if err := marshalMessageSet(encoder, oq.CreditCards, CreditCardRq); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := marshalMessageSet(encoder, oq.Investments, "INVSTMTMSGSRQV1"); err != nil {
|
if err := marshalMessageSet(encoder, oq.Investments, InvStmtRq); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := marshalMessageSet(encoder, oq.Securities, "SECLISTMSGSRQV1"); err != nil {
|
if err := marshalMessageSet(encoder, oq.Securities, SecListRq); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := marshalMessageSet(encoder, oq.Profile, "PROFMSGSRQV1"); err != nil {
|
if err := marshalMessageSet(encoder, oq.Profile, ProfileRq); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,10 @@ func (r *SecListRequest) Valid() (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *SecListRequest) Type() messageType {
|
||||||
|
return SecListRq
|
||||||
|
}
|
||||||
|
|
||||||
type SecListResponse struct {
|
type SecListResponse struct {
|
||||||
XMLName xml.Name `xml:"SECLISTTRNRS"`
|
XMLName xml.Name `xml:"SECLISTTRNRS"`
|
||||||
TrnUID UID `xml:"TRNUID"`
|
TrnUID UID `xml:"TRNUID"`
|
||||||
@ -55,6 +59,10 @@ func (r SecListResponse) Valid() (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r SecListResponse) Type() messageType {
|
||||||
|
return SecListRs
|
||||||
|
}
|
||||||
|
|
||||||
type Security interface {
|
type Security interface {
|
||||||
SecurityType() string
|
SecurityType() string
|
||||||
}
|
}
|
||||||
@ -176,6 +184,10 @@ func (r SecurityList) Valid() (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r SecurityList) Type() messageType {
|
||||||
|
return SecListRs
|
||||||
|
}
|
||||||
|
|
||||||
func (r *SecurityList) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
func (r *SecurityList) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||||
for {
|
for {
|
||||||
tok, err := nextNonWhitespaceToken(d)
|
tok, err := nextNonWhitespaceToken(d)
|
||||||
|
@ -24,6 +24,10 @@ func (r *AcctInfoRequest) Valid() (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *AcctInfoRequest) Type() messageType {
|
||||||
|
return SignupRq
|
||||||
|
}
|
||||||
|
|
||||||
type HolderInfo struct {
|
type HolderInfo struct {
|
||||||
XMLName xml.Name
|
XMLName xml.Name
|
||||||
FirstName String `xml:"FIRSTNAME"`
|
FirstName String `xml:"FIRSTNAME"`
|
||||||
@ -125,6 +129,10 @@ func (air AcctInfoResponse) Valid() (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (air AcctInfoResponse) Type() messageType {
|
||||||
|
return SignupRs
|
||||||
|
}
|
||||||
|
|
||||||
func decodeSignupMessageSet(d *xml.Decoder, start xml.StartElement) ([]Message, error) {
|
func decodeSignupMessageSet(d *xml.Decoder, start xml.StartElement) ([]Message, error) {
|
||||||
var msgs []Message
|
var msgs []Message
|
||||||
for {
|
for {
|
||||||
|
Loading…
Reference in New Issue
Block a user