mirror of
https://github.com/aclindsa/ofxgo.git
synced 2024-10-30 13:30:05 -04:00
Aaron Lindsay
6491311dbc
They don't belong in with the banking message set like they were, even though they're in the same section in the spec...
179 lines
8.6 KiB
Go
179 lines
8.6 KiB
Go
package ofxgo
|
|
|
|
import (
|
|
"errors"
|
|
"github.com/golang/go/src/encoding/xml"
|
|
)
|
|
|
|
type StatementRequest struct {
|
|
XMLName xml.Name `xml:"STMTTRNRQ"`
|
|
TrnUID UID `xml:"TRNUID"`
|
|
BankAcctFrom BankAcct `xml:"STMTRQ>BANKACCTFROM"`
|
|
DtStart Date `xml:"STMTRQ>INCTRAN>DTSTART,omitempty"`
|
|
DtEnd Date `xml:"STMTRQ>INCTRAN>DTEND,omitempty"`
|
|
Include Boolean `xml:"STMTRQ>INCTRAN>INCLUDE"` // Include transactions (instead of just balance)
|
|
IncludePending Boolean `xml:"STMTRQ>INCLUDEPENDING,omitempty"` // Include pending transactions
|
|
IncTranImg Boolean `xml:"STMTRQ>INCTRANIMG,omitempty"` // Include transaction images
|
|
}
|
|
|
|
func (r *StatementRequest) Name() string {
|
|
return "STMTTRNRQ"
|
|
}
|
|
|
|
func (r *StatementRequest) Valid() (bool, error) {
|
|
if ok, err := r.TrnUID.Valid(); !ok {
|
|
return false, err
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
type Payee struct {
|
|
XMLName xml.Name `xml:"PAYEE"`
|
|
Name String `xml:"NAME"`
|
|
Addr1 String `xml:"ADDR1"`
|
|
Addr2 String `xml:"ADDR2,omitempty"`
|
|
Addr3 String `xml:"ADDR3,omitempty"`
|
|
City String `xml:"CITY"`
|
|
State String `xml:"STATE"`
|
|
PostalCode String `xml:"POSTALCODE"`
|
|
Country String `xml:"COUNTRY,omitempty"`
|
|
Phone String `xml:"PHONE"`
|
|
}
|
|
|
|
type ImageData struct {
|
|
XMLName xml.Name `xml:"IMAGEDATA"`
|
|
ImageType String `xml:"IMAGETYPE"` // One of STATEMENT, TRANSACTION, TAX
|
|
ImageRef String `xml:"IMAGEREF"` // URL or identifier, depending on IMAGEREFTYPE
|
|
ImageRefType String `xml:"IMAGEREFTYPE"` // One of OPAQUE, URL, FORMURL (see spec for more details on how to access images of each of these types)
|
|
// Only one of the next two should be valid at any given time
|
|
ImageDelay Int `xml:"IMAGEDELAY,omitempty"` // Number of calendar days from DTSERVER (for statement images) or DTPOSTED (for transaction image) the image will become available
|
|
DtImageAvail Date `xml:"DTIMAGEAVAIL,omitempty"` // Date image will become available
|
|
ImageTTL Int `xml:"IMAGETTL,omitempty"` // Number of days after image becomes available that it will remain available
|
|
CheckSup String `xml:"CHECKSUP,omitempty"` // What is contained in check images. One of FRONTONLY, BACKONLY, FRONTANDBACK
|
|
}
|
|
|
|
type Transaction struct {
|
|
XMLName xml.Name `xml:"STMTTRN"`
|
|
TrnType String `xml:"TRNTYPE"` // One of CREDIT, DEBIT, INT (interest earned or paid. Note: Depends on signage of amount), DIV, FEE, SRVCHG (service charge), DEP (deposit), ATM (Note: Depends on signage of amount), POS (Note: Depends on signage of amount), XFER, CHECK, PAYMENT, CASH, DIRECTDEP, DIRECTDEBIT, REPEATPMT, OTHER
|
|
DtPosted Date `xml:"DTPOSTED"`
|
|
DtUser Date `xml:"DTUSER,omitempty"`
|
|
DtAvail Date `xml:"DTAVAIL,omitempty"`
|
|
TrnAmt Amount `xml:"TRNAMT"`
|
|
FiTId String `xml:"FITID"`
|
|
CorrectFiTId String `xml:"CORRECTFITID,omitempty"` // Transaction Id that this transaction corrects, if present
|
|
CorrectAction String `xml:"CORRECTACTION,omitempty"` // One of DELETE, REPLACE
|
|
SrvrTId String `xml:"SRVRTID,omitempty"`
|
|
CheckNum String `xml:"CHECKNUM,omitempty"`
|
|
RefNum String `xml:"REFNUM,omitempty"`
|
|
SIC Int `xml:"SIC,omitempty"` // Standard Industrial Code
|
|
PayeeId String `xml:"PAYEEID,omitempty"`
|
|
// Note: Servers should provide NAME or PAYEE, but not both
|
|
Name String `xml:"NAME,omitempty"`
|
|
Payee Payee `xml:"PAYEE,omitempty"`
|
|
ExtdName String `xml:"EXTDNAME,omitempty"` // Extended name of payee or transaction description
|
|
BankAcctTo BankAcct `xml:"BANKACCTTO,omitempty"` // If the transfer was to a bank account we have the account information for
|
|
CCAcctTo CCAcct `xml:"CCACCTTO,omitempty"` // If the transfer was to a credit card account we have the account information for
|
|
Memo String `xml:"MEMO,omitempty"` // Extra information (not in NAME)
|
|
ImageData []ImageData `xml:"IMAGEDATA,omitempty"`
|
|
Currency String `xml:"CURRENCY,omitempty"` // If different from CURDEF in STMTTRS
|
|
OrigCurrency String `xml:"ORIGCURRENCY,omitempty"` // If different from CURDEF in STMTTRS
|
|
Inv401kSource String `xml:"INV401KSOURCE,omitempty"` // One of PRETAX, AFTERTAX, MATCH, PROFITSHARING, ROLLOVER, OTHERVEST, OTHERNONVEST (Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST.)
|
|
}
|
|
|
|
type TransactionList struct {
|
|
XMLName xml.Name `xml:"BANKTRANLIST"`
|
|
DtStart Date `xml:"DTSTART"`
|
|
DtEnd Date `xml:"DTEND"`
|
|
Transactions []Transaction `xml:"STMTTRN,omitempty"`
|
|
}
|
|
|
|
type PendingTransaction struct {
|
|
XMLName xml.Name `xml:"STMTTRN"`
|
|
TrnType String `xml:"TRNTYPE"` // One of CREDIT, DEBIT, INT (interest earned or paid. Note: Depends on signage of amount), DIV, FEE, SRVCHG (service charge), DEP (deposit), ATM (Note: Depends on signage of amount), POS (Note: Depends on signage of amount), XFER, CHECK, PAYMENT, CASH, DIRECTDEP, DIRECTDEBIT, REPEATPMT, HOLD, OTHER
|
|
DtTran Date `xml:"DTTRAN"`
|
|
DtExpire Date `xml:"DTEXPIRE,omitempty"` // only valid for TrnType==HOLD, the date the hold will expire
|
|
TrnAmt Amount `xml:"TRNAMT"`
|
|
RefNum String `xml:"REFNUM,omitempty"`
|
|
Name String `xml:"NAME,omitempty"`
|
|
ExtdName String `xml:"EXTDNAME,omitempty"` // Extended name of payee or transaction description
|
|
Memo String `xml:"MEMO,omitempty"` // Extra information (not in NAME)
|
|
ImageData []ImageData `xml:"IMAGEDATA,omitempty"`
|
|
Currency String `xml:"CURRENCY,omitempty"` // If different from CURDEF in STMTTRS
|
|
OrigCurrency String `xml:"ORIGCURRENCY,omitempty"` // If different from CURDEF in STMTTRS
|
|
}
|
|
|
|
// List of pending transactions
|
|
type PendingTransactionList struct {
|
|
XMLName xml.Name `xml:"BANKTRANLISTP"`
|
|
DtAsOf Date `xml:"DTASOF"`
|
|
Transactions []PendingTransaction `xml:"STMTTRNP,omitempty"`
|
|
}
|
|
|
|
type Balance struct {
|
|
XMLName xml.Name `xml:"BAL"`
|
|
Name String `xml:"NAME"`
|
|
Desc String `xml:"DESC"`
|
|
|
|
// Balance type:
|
|
// DOLLAR = dollar (value formatted DDDD.cc)
|
|
// PERCENT = percentage (value formatted XXXX.YYYY)
|
|
// NUMBER = number (value formatted as is)
|
|
BalType String `xml:"BALTYPE"`
|
|
|
|
Value Amount `xml:"VALUE"`
|
|
DtAsOf Date `xml:"DTASOF,omitempty"`
|
|
Currency Currency `xml:"CURRENCY,omitempty"` // if BALTYPE is DOLLAR
|
|
}
|
|
|
|
type StatementResponse struct {
|
|
XMLName xml.Name `xml:"STMTTRNRS"`
|
|
TrnUID UID `xml:"TRNUID"`
|
|
CurDef String `xml:"STMTRS>CURDEF"`
|
|
BankAcctFrom BankAcct `xml:"STMTRS>BANKACCTFROM"`
|
|
BankTranList TransactionList `xml:"STMTRS>BANKTRANLIST,omitempty"`
|
|
BankTranListP PendingTransactionList `xml:"STMTRS>BANKTRANLISTP,omitempty"`
|
|
BalAmt Amount `xml:"STMTRS>LEDGERBAL>BALAMT"`
|
|
DtAsOf Date `xml:"STMTRS>LEDGERBAL>DTASOF"`
|
|
AvailBalAmt Amount `xml:"STMTRS>AVAILBAL>BALAMT,omitempty"`
|
|
AvailDtAsOf Date `xml:"STMTRS>AVAILBAL>DTASOF,omitempty"`
|
|
CashAdvBalAmt Amount `xml:"STMTRS>CASHADVBALAMT,omitempty"` // Only for CREDITLINE accounts, available balance for cash advances
|
|
IntRate Amount `xml:"STMTRS>INTRATE,omitempty"` // Current interest rate
|
|
BalList []Balance `xml:"STMTRS>BALLIST>BAL,omitempty"`
|
|
MktgInfo String `xml:"STMTRS>MKTGINFO,omitempty"` // Marketing information
|
|
}
|
|
|
|
func (sr StatementResponse) Name() string {
|
|
return "STMTTRNRS"
|
|
}
|
|
|
|
func (sr StatementResponse) Valid() (bool, error) {
|
|
//TODO implement
|
|
return true, nil
|
|
}
|
|
|
|
func DecodeBankingMessageSet(d *xml.Decoder, start xml.StartElement) ([]Message, error) {
|
|
var msgs []Message
|
|
for {
|
|
tok, err := nextNonWhitespaceToken(d)
|
|
if err != nil {
|
|
return nil, err
|
|
} else if end, ok := tok.(xml.EndElement); ok && end.Name.Local == start.Name.Local {
|
|
// If we found the end of our starting element, we're done parsing
|
|
return msgs, nil
|
|
} else if startElement, ok := tok.(xml.StartElement); ok {
|
|
switch startElement.Name.Local {
|
|
case "STMTTRNRS":
|
|
var info StatementResponse
|
|
if err := d.DecodeElement(&info, &startElement); err != nil {
|
|
return nil, err
|
|
}
|
|
msgs = append(msgs, Message(info))
|
|
default:
|
|
return nil, errors.New("Unsupported banking response tag: " + startElement.Name.Local)
|
|
}
|
|
} else {
|
|
return nil, errors.New("Didn't find an opening element")
|
|
}
|
|
}
|
|
}
|